-
Notifications
You must be signed in to change notification settings - Fork 1
/
DX.Types.GeoLocation.pas
145 lines (123 loc) · 3.61 KB
/
DX.Types.GeoLocation.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
unit DX.Types.GeoLocation;
/// <summary>
/// DX.Types.GeoLocation provides a GeoLocation data type which can be mapped to
/// SQL Server's Geography type
/// </summary>
/// <remarks>
/// DX.Types.GeoLocation is part of DX.Librayry<br />See:
/// http://code.google.com/p/dx-library/
/// </remarks>
interface
uses
SysUtils, Classes;
type
TGeoLocation = class(TObject)
type
//Only used internally
TGeography = class(TObject)
private
FFormat: TFormatSettings;
FLatitude: double;
FLongitude: double;
procedure CalcLatLong;
procedure CalcWellKnownText;
procedure SetLatitude(const Value: double);
procedure SetLongitude(const Value: double);
function GetLatitude: double;
function GetLongitude: double;
public
CoordinateSystemId: Integer;
WellKnownText: string;
property Latitude: double read GetLatitude write SetLatitude;
property Longitude: double read GetLongitude write SetLongitude;
constructor Create;
end;
private
//This is only used internally to map SQL Servers Geography Type via JSON
Geography: TGeography;
function GetLatitude: double;
function GetLongitude: double;
procedure SetLatitude(const Value: double);
procedure SetLongitude(const Value: double);
public
property Latitude: double read GetLatitude write SetLatitude;
property Longitude: double read GetLongitude write SetLongitude;
constructor Create;
end;
implementation
{ TGeoLocation }
constructor TGeoLocation.Create;
begin
inherited;
Geography := TGeography.Create;
end;
function TGeoLocation.GetLatitude: double;
begin
result := Geography.Latitude;
end;
function TGeoLocation.GetLongitude: double;
begin
result := Geography.Longitude;
end;
procedure TGeoLocation.SetLatitude(const Value: double);
begin
Geography.Latitude := Value;
end;
procedure TGeoLocation.SetLongitude(const Value: double);
begin
Geography.Longitude := Value;
end;
{ TGeoLocation.TGeography }
constructor TGeoLocation.TGeography.Create;
begin
FFormat := TFormatSettings.Create;
FFormat.DecimalSeparator := '.';
FFormat.ThousandSeparator := ',';
Longitude := 0.0;
Latitude := 0.0;
CoordinateSystemId := 4326; // WGS8
end;
function TGeoLocation.TGeography.GetLatitude: double;
begin
CalcLatLong;
result := FLatitude;
end;
function TGeoLocation.TGeography.GetLongitude: double;
begin
CalcLatLong;
result := FLongitude;
end;
procedure TGeoLocation.TGeography.CalcWellKnownText;
begin
WellKnownText := 'POINT(' + FloatToStr(FLatitude, FFormat) + ' ' + FloatToStr(FLongitude, FFormat) + ')';
end;
procedure TGeoLocation.TGeography.SetLatitude(const Value: double);
begin
FLatitude := Value;
CalcWellKnownText;
end;
procedure TGeoLocation.TGeography.SetLongitude(const Value: double);
begin
FLongitude := Value;
CalcWellKnownText;
end;
procedure TGeoLocation.TGeography.CalcLatLong;
var
s: string;
LCoords: TArray<string>;
begin
// POINT(50.130125 8.75081)
s := WellKnownText.Trim;
Delete(s, 1, pos('(', s)); // 50.130125 8.75081)
Delete(s, s.Length, 1); // 50.130125 8.75081
LCoords := s.Split([' ']);
if Length(LCoords) <> 2 then
raise Exception.Create('TGeoLocation: Invalid WellKnownText! Supported format: POINT(50.130125 8.75081)');
try
FLatitude := StrToFloat(LCoords[0], FFormat);
FLongitude := StrToFloat(LCoords[1], FFormat);
except
raise Exception.Create('TGeoLocation: Invalid WellKnownText! Supported format: POINT(50.130125 8.75081)');
end;
end;
end.