geodetic 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +28 -4
- data/README.md +19 -5
- data/docs/coordinate-systems/bng.md +5 -5
- data/docs/coordinate-systems/ecef.md +23 -23
- data/docs/coordinate-systems/enu.md +3 -3
- data/docs/coordinate-systems/gars.md +246 -0
- data/docs/coordinate-systems/georef.md +221 -0
- data/docs/coordinate-systems/gh.md +7 -7
- data/docs/coordinate-systems/gh36.md +6 -6
- data/docs/coordinate-systems/h3.md +312 -0
- data/docs/coordinate-systems/ham.md +6 -6
- data/docs/coordinate-systems/index.md +40 -34
- data/docs/coordinate-systems/lla.md +26 -26
- data/docs/coordinate-systems/mgrs.md +3 -3
- data/docs/coordinate-systems/ned.md +3 -3
- data/docs/coordinate-systems/olc.md +6 -6
- data/docs/coordinate-systems/state-plane.md +2 -2
- data/docs/coordinate-systems/ups.md +4 -4
- data/docs/coordinate-systems/usng.md +2 -2
- data/docs/coordinate-systems/utm.md +23 -23
- data/docs/coordinate-systems/web-mercator.md +7 -7
- data/docs/getting-started/installation.md +17 -17
- data/docs/getting-started/quick-start.md +8 -8
- data/docs/index.md +22 -19
- data/docs/reference/areas.md +15 -15
- data/docs/reference/conversions.md +31 -31
- data/docs/reference/geoid-height.md +5 -5
- data/docs/reference/serialization.md +44 -44
- data/examples/01_basic_conversions.rb +10 -10
- data/examples/02_all_coordinate_systems.rb +24 -24
- data/lib/geodetic/areas/circle.rb +1 -1
- data/lib/geodetic/areas/polygon.rb +2 -2
- data/lib/geodetic/areas/rectangle.rb +6 -6
- data/lib/geodetic/{coordinates → coordinate}/bng.rb +3 -37
- data/lib/geodetic/{coordinates → coordinate}/ecef.rb +3 -33
- data/lib/geodetic/{coordinates → coordinate}/enu.rb +30 -1
- data/lib/geodetic/coordinate/gars.rb +233 -0
- data/lib/geodetic/coordinate/georef.rb +204 -0
- data/lib/geodetic/coordinate/gh.rb +161 -0
- data/lib/geodetic/{coordinates → coordinate}/gh36.rb +28 -187
- data/lib/geodetic/coordinate/h3.rb +413 -0
- data/lib/geodetic/coordinate/ham.rb +226 -0
- data/lib/geodetic/{coordinates → coordinate}/lla.rb +31 -1
- data/lib/geodetic/{coordinates → coordinate}/mgrs.rb +3 -33
- data/lib/geodetic/{coordinates → coordinate}/ned.rb +30 -1
- data/lib/geodetic/{coordinates → coordinate}/olc.rb +19 -225
- data/lib/geodetic/coordinate/spatial_hash.rb +342 -0
- data/lib/geodetic/{coordinates → coordinate}/state_plane.rb +30 -1
- data/lib/geodetic/{coordinates → coordinate}/ups.rb +3 -37
- data/lib/geodetic/{coordinates → coordinate}/usng.rb +3 -33
- data/lib/geodetic/{coordinates → coordinate}/utm.rb +3 -33
- data/lib/geodetic/{coordinates → coordinate}/web_mercator.rb +3 -33
- data/lib/geodetic/{coordinates.rb → coordinate.rb} +62 -45
- data/lib/geodetic/version.rb +1 -1
- data/lib/geodetic.rb +1 -1
- data/spatial_hash_idea.md +241 -0
- metadata +29 -20
- data/lib/geodetic/coordinates/gh.rb +0 -372
- data/lib/geodetic/coordinates/ham.rb +0 -435
|
@@ -28,7 +28,7 @@ All `to_s` methods accept an optional `precision` parameter controlling the numb
|
|
|
28
28
|
Passing `0` returns integer values (no decimal point). MGRS and USNG are string-based and do not accept a precision parameter.
|
|
29
29
|
|
|
30
30
|
```ruby
|
|
31
|
-
lla = Geodetic::
|
|
31
|
+
lla = Geodetic::Coordinate::LLA.new(lat: 47.6205, lng: -122.3493, alt: 184.0)
|
|
32
32
|
lla.to_s # => "47.620500, -122.349300, 184.00"
|
|
33
33
|
lla.to_s(3) # => "47.620, -122.349, 184.00"
|
|
34
34
|
lla.to_s(0) # => "48, -122, 184"
|
|
@@ -41,14 +41,14 @@ lla.to_s(0) # => "48, -122, 184"
|
|
|
41
41
|
### LLA
|
|
42
42
|
|
|
43
43
|
```ruby
|
|
44
|
-
point = Geodetic::
|
|
44
|
+
point = Geodetic::Coordinate::LLA.new(lat: 38.8977, lng: -77.0365, alt: 100.0)
|
|
45
45
|
|
|
46
46
|
point.to_s # => "38.897700, -77.036500, 100.00"
|
|
47
47
|
point.to_s(2) # => "38.90, -77.04, 100.00"
|
|
48
48
|
point.to_a # => [38.8977, -77.0365, 100.0]
|
|
49
49
|
|
|
50
|
-
Geodetic::
|
|
51
|
-
Geodetic::
|
|
50
|
+
Geodetic::Coordinate::LLA.from_string("38.8977, -77.0365, 100.0")
|
|
51
|
+
Geodetic::Coordinate::LLA.from_array([38.8977, -77.0365, 100.0])
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
**LLA-specific: DMS format**
|
|
@@ -59,7 +59,7 @@ LLA also supports degrees-minutes-seconds notation:
|
|
|
59
59
|
point.to_dms
|
|
60
60
|
# => "38 53' 51.72\" N, 77 2' 11.40\" W, 100.00 m"
|
|
61
61
|
|
|
62
|
-
Geodetic::
|
|
62
|
+
Geodetic::Coordinate::LLA.from_dms("38 53' 51.72\" N, 77 2' 11.40\" W, 100.0 m")
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
The DMS string format is: `DD MM' SS.ss" H, DDD MM' SS.ss" H, ALT m` where H is N/S for latitude and E/W for longitude. The altitude portion is optional in `from_dms` (defaults to 0.0).
|
|
@@ -67,26 +67,26 @@ The DMS string format is: `DD MM' SS.ss" H, DDD MM' SS.ss" H, ALT m` where H is
|
|
|
67
67
|
### ECEF
|
|
68
68
|
|
|
69
69
|
```ruby
|
|
70
|
-
point = Geodetic::
|
|
70
|
+
point = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
|
|
71
71
|
|
|
72
72
|
point.to_s # => "1130730.00, -4828583.00, 3991570.00"
|
|
73
73
|
point.to_s(0) # => "1130730, -4828583, 3991570"
|
|
74
74
|
point.to_a # => [1130730.0, -4828583.0, 3991570.0]
|
|
75
75
|
|
|
76
|
-
Geodetic::
|
|
77
|
-
Geodetic::
|
|
76
|
+
Geodetic::Coordinate::ECEF.from_string("1130730.0, -4828583.0, 3991570.0")
|
|
77
|
+
Geodetic::Coordinate::ECEF.from_array([1130730.0, -4828583.0, 3991570.0])
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
### UTM
|
|
81
81
|
|
|
82
82
|
```ruby
|
|
83
|
-
point = Geodetic::
|
|
83
|
+
point = Geodetic::Coordinate::UTM.new(easting: 323394.0, northing: 4307396.0, altitude: 100.0, zone: 18, hemisphere: 'N')
|
|
84
84
|
|
|
85
85
|
point.to_s # => "323394.00, 4307396.00, 100.00, 18, N"
|
|
86
86
|
point.to_a # => [323394.0, 4307396.0, 100.0, 18, "N"]
|
|
87
87
|
|
|
88
|
-
Geodetic::
|
|
89
|
-
Geodetic::
|
|
88
|
+
Geodetic::Coordinate::UTM.from_string("323394.0, 4307396.0, 100.0, 18, N")
|
|
89
|
+
Geodetic::Coordinate::UTM.from_array([323394.0, 4307396.0, 100.0, 18, "N"])
|
|
90
90
|
```
|
|
91
91
|
|
|
92
92
|
Note: The array and string formats include all five components: easting, northing, altitude, zone number, and hemisphere.
|
|
@@ -94,67 +94,67 @@ Note: The array and string formats include all five components: easting, northin
|
|
|
94
94
|
### ENU
|
|
95
95
|
|
|
96
96
|
```ruby
|
|
97
|
-
point = Geodetic::
|
|
97
|
+
point = Geodetic::Coordinate::ENU.new(e: 100.0, n: 200.0, u: 50.0)
|
|
98
98
|
|
|
99
99
|
point.to_s # => "100.00, 200.00, 50.00"
|
|
100
100
|
point.to_a # => [100.0, 200.0, 50.0]
|
|
101
101
|
|
|
102
|
-
Geodetic::
|
|
103
|
-
Geodetic::
|
|
102
|
+
Geodetic::Coordinate::ENU.from_string("100.0, 200.0, 50.0")
|
|
103
|
+
Geodetic::Coordinate::ENU.from_array([100.0, 200.0, 50.0])
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
### NED
|
|
107
107
|
|
|
108
108
|
```ruby
|
|
109
|
-
point = Geodetic::
|
|
109
|
+
point = Geodetic::Coordinate::NED.new(n: 200.0, e: 100.0, d: -50.0)
|
|
110
110
|
|
|
111
111
|
point.to_s # => "200.00, 100.00, -50.00"
|
|
112
112
|
point.to_a # => [200.0, 100.0, -50.0]
|
|
113
113
|
|
|
114
|
-
Geodetic::
|
|
115
|
-
Geodetic::
|
|
114
|
+
Geodetic::Coordinate::NED.from_string("200.0, 100.0, -50.0")
|
|
115
|
+
Geodetic::Coordinate::NED.from_array([200.0, 100.0, -50.0])
|
|
116
116
|
```
|
|
117
117
|
|
|
118
118
|
### WebMercator
|
|
119
119
|
|
|
120
120
|
```ruby
|
|
121
|
-
point = Geodetic::
|
|
121
|
+
point = Geodetic::Coordinate::WebMercator.new(x: -8575605.0, y: 4707175.0)
|
|
122
122
|
|
|
123
123
|
point.to_s # => "-8575605.00, 4707175.00"
|
|
124
124
|
point.to_a # => [-8575605.0, 4707175.0]
|
|
125
125
|
|
|
126
|
-
Geodetic::
|
|
127
|
-
Geodetic::
|
|
126
|
+
Geodetic::Coordinate::WebMercator.from_string("-8575605.0, 4707175.0")
|
|
127
|
+
Geodetic::Coordinate::WebMercator.from_array([-8575605.0, 4707175.0])
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
### UPS
|
|
131
131
|
|
|
132
132
|
```ruby
|
|
133
|
-
point = Geodetic::
|
|
133
|
+
point = Geodetic::Coordinate::UPS.new(easting: 2000000.0, northing: 2000000.0, hemisphere: 'N', zone: 'Y')
|
|
134
134
|
|
|
135
135
|
point.to_s # => "2000000.00, 2000000.00, N, Y"
|
|
136
136
|
point.to_a # => [2000000.0, 2000000.0, "N", "Y"]
|
|
137
137
|
|
|
138
|
-
Geodetic::
|
|
139
|
-
Geodetic::
|
|
138
|
+
Geodetic::Coordinate::UPS.from_string("2000000.0, 2000000.0, N, Y")
|
|
139
|
+
Geodetic::Coordinate::UPS.from_array([2000000.0, 2000000.0, "N", "Y"])
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
### BNG
|
|
143
143
|
|
|
144
144
|
```ruby
|
|
145
|
-
point = Geodetic::
|
|
145
|
+
point = Geodetic::Coordinate::BNG.new(easting: 530000.0, northing: 180000.0)
|
|
146
146
|
|
|
147
147
|
point.to_s # => "530000.00, 180000.00"
|
|
148
148
|
point.to_a # => [530000.0, 180000.0]
|
|
149
149
|
|
|
150
|
-
Geodetic::
|
|
151
|
-
Geodetic::
|
|
150
|
+
Geodetic::Coordinate::BNG.from_string("530000.0, 180000.0")
|
|
151
|
+
Geodetic::Coordinate::BNG.from_array([530000.0, 180000.0])
|
|
152
152
|
```
|
|
153
153
|
|
|
154
154
|
BNG also supports grid reference notation via the constructor:
|
|
155
155
|
|
|
156
156
|
```ruby
|
|
157
|
-
point = Geodetic::
|
|
157
|
+
point = Geodetic::Coordinate::BNG.new(grid_ref: "TQ 30 80")
|
|
158
158
|
point.to_grid_reference(6) # => "TQ 300000 800000"
|
|
159
159
|
point.to_grid_reference(0) # => "TQ" (grid square only)
|
|
160
160
|
```
|
|
@@ -162,13 +162,13 @@ point.to_grid_reference(0) # => "TQ" (grid square only)
|
|
|
162
162
|
### StatePlane
|
|
163
163
|
|
|
164
164
|
```ruby
|
|
165
|
-
point = Geodetic::
|
|
165
|
+
point = Geodetic::Coordinate::StatePlane.new(easting: 2000000.0, northing: 500000.0, zone_code: 'CA_I')
|
|
166
166
|
|
|
167
167
|
point.to_s # => "2000000.00, 500000.00, CA_I"
|
|
168
168
|
point.to_a # => [2000000.0, 500000.0, "CA_I"]
|
|
169
169
|
|
|
170
|
-
Geodetic::
|
|
171
|
-
Geodetic::
|
|
170
|
+
Geodetic::Coordinate::StatePlane.from_string("2000000.0, 500000.0, CA_I")
|
|
171
|
+
Geodetic::Coordinate::StatePlane.from_array([2000000.0, 500000.0, "CA_I"])
|
|
172
172
|
```
|
|
173
173
|
|
|
174
174
|
---
|
|
@@ -180,12 +180,12 @@ MGRS and USNG use alphanumeric grid references rather than numeric arrays. They
|
|
|
180
180
|
### MGRS
|
|
181
181
|
|
|
182
182
|
```ruby
|
|
183
|
-
mgrs = Geodetic::
|
|
183
|
+
mgrs = Geodetic::Coordinate::MGRS.new(mgrs_string: "18SUJ2034706880")
|
|
184
184
|
mgrs.to_s # => "18SUJ2034706880"
|
|
185
185
|
mgrs.to_a # => ["18S", "UJ", 20347.0, 6880.0, 5]
|
|
186
186
|
|
|
187
|
-
Geodetic::
|
|
188
|
-
Geodetic::
|
|
187
|
+
Geodetic::Coordinate::MGRS.from_string("18SUJ2034706880")
|
|
188
|
+
Geodetic::Coordinate::MGRS.from_array(["18S", "UJ", 20347, 6880, 5])
|
|
189
189
|
```
|
|
190
190
|
|
|
191
191
|
The MGRS string format is: `{zone_number}{zone_letter}{square_id}{easting}{northing}` with no spaces. Precision varies based on the number of coordinate digits (0 to 5 pairs). The array format is `[grid_zone, square_id, easting, northing, precision]`.
|
|
@@ -193,12 +193,12 @@ The MGRS string format is: `{zone_number}{zone_letter}{square_id}{easting}{north
|
|
|
193
193
|
### USNG
|
|
194
194
|
|
|
195
195
|
```ruby
|
|
196
|
-
usng = Geodetic::
|
|
196
|
+
usng = Geodetic::Coordinate::USNG.new(usng_string: "18S UJ 20347 06880")
|
|
197
197
|
usng.to_s # => "18S UJ 20347 06880"
|
|
198
198
|
usng.to_a # => ["18S", "UJ", 20347.0, 6880.0, 5]
|
|
199
199
|
|
|
200
|
-
Geodetic::
|
|
201
|
-
Geodetic::
|
|
200
|
+
Geodetic::Coordinate::USNG.from_string("18S UJ 20347 06880")
|
|
201
|
+
Geodetic::Coordinate::USNG.from_array(["18S", "UJ", 20347, 6880, 5])
|
|
202
202
|
```
|
|
203
203
|
|
|
204
204
|
USNG uses the same underlying format as MGRS but separates components with spaces for readability. Both spaced and non-spaced formats are accepted by `from_string`. The array format is `[grid_zone, square_id, easting, northing, precision]`. USNG also provides:
|
|
@@ -216,24 +216,24 @@ String and array serialization support full roundtrip fidelity:
|
|
|
216
216
|
|
|
217
217
|
```ruby
|
|
218
218
|
# LLA roundtrip via string
|
|
219
|
-
original = Geodetic::
|
|
220
|
-
restored = Geodetic::
|
|
219
|
+
original = Geodetic::Coordinate::LLA.new(lat: 40.7128, lng: -74.0060, alt: 10.0)
|
|
220
|
+
restored = Geodetic::Coordinate::LLA.from_string(original.to_s)
|
|
221
221
|
original == restored # => true
|
|
222
222
|
|
|
223
223
|
# ECEF roundtrip via array
|
|
224
|
-
original = Geodetic::
|
|
225
|
-
restored = Geodetic::
|
|
224
|
+
original = Geodetic::Coordinate::ECEF.new(x: 1334000.0, y: -4654000.0, z: 4138000.0)
|
|
225
|
+
restored = Geodetic::Coordinate::ECEF.from_array(original.to_a)
|
|
226
226
|
original == restored # => true
|
|
227
227
|
|
|
228
228
|
# UTM roundtrip via string
|
|
229
|
-
original = Geodetic::
|
|
230
|
-
restored = Geodetic::
|
|
229
|
+
original = Geodetic::Coordinate::UTM.new(easting: 583960.0, northing: 4507523.0, altitude: 10.0, zone: 18, hemisphere: 'N')
|
|
230
|
+
restored = Geodetic::Coordinate::UTM.from_string(original.to_s)
|
|
231
231
|
original == restored # => true
|
|
232
232
|
|
|
233
233
|
# LLA roundtrip via DMS
|
|
234
|
-
original = Geodetic::
|
|
234
|
+
original = Geodetic::Coordinate::LLA.new(lat: 38.8977, lng: -77.0365, alt: 100.0)
|
|
235
235
|
dms_string = original.to_dms
|
|
236
|
-
restored = Geodetic::
|
|
236
|
+
restored = Geodetic::Coordinate::LLA.from_dms(dms_string)
|
|
237
237
|
# Note: DMS roundtrip has minor floating-point precision differences
|
|
238
238
|
```
|
|
239
239
|
|
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
# Shows all coordinate systems converting to/from each other
|
|
5
5
|
|
|
6
6
|
require_relative '../lib/geodetic'
|
|
7
|
-
require_relative '../lib/geodetic/
|
|
8
|
-
require_relative '../lib/geodetic/
|
|
9
|
-
require_relative '../lib/geodetic/
|
|
10
|
-
require_relative '../lib/geodetic/
|
|
11
|
-
require_relative '../lib/geodetic/
|
|
7
|
+
require_relative '../lib/geodetic/coordinate/lla'
|
|
8
|
+
require_relative '../lib/geodetic/coordinate/ecef'
|
|
9
|
+
require_relative '../lib/geodetic/coordinate/enu'
|
|
10
|
+
require_relative '../lib/geodetic/coordinate/ned'
|
|
11
|
+
require_relative '../lib/geodetic/coordinate/utm'
|
|
12
12
|
|
|
13
13
|
include Geodetic
|
|
14
|
-
LLA =
|
|
15
|
-
ECEF =
|
|
16
|
-
ENU =
|
|
17
|
-
NED =
|
|
18
|
-
UTM =
|
|
14
|
+
LLA = Coordinate::LLA
|
|
15
|
+
ECEF = Coordinate::ECEF
|
|
16
|
+
ENU = Coordinate::ENU
|
|
17
|
+
NED = Coordinate::NED
|
|
18
|
+
UTM = Coordinate::UTM
|
|
19
19
|
|
|
20
20
|
puts "=== Orthogonal Coordinate System Conversions Demo ==="
|
|
21
21
|
puts
|
|
@@ -3,33 +3,33 @@
|
|
|
3
3
|
# Shows complete orthogonal conversions between all implemented coordinate systems
|
|
4
4
|
|
|
5
5
|
require_relative '../lib/geodetic'
|
|
6
|
-
require_relative '../lib/geodetic/
|
|
7
|
-
require_relative '../lib/geodetic/
|
|
8
|
-
require_relative '../lib/geodetic/
|
|
9
|
-
require_relative '../lib/geodetic/
|
|
10
|
-
require_relative '../lib/geodetic/
|
|
11
|
-
require_relative '../lib/geodetic/
|
|
12
|
-
require_relative '../lib/geodetic/
|
|
13
|
-
require_relative '../lib/geodetic/
|
|
14
|
-
require_relative '../lib/geodetic/
|
|
15
|
-
require_relative '../lib/geodetic/
|
|
16
|
-
require_relative '../lib/geodetic/
|
|
17
|
-
require_relative '../lib/geodetic/
|
|
6
|
+
require_relative '../lib/geodetic/coordinate/lla'
|
|
7
|
+
require_relative '../lib/geodetic/coordinate/ecef'
|
|
8
|
+
require_relative '../lib/geodetic/coordinate/utm'
|
|
9
|
+
require_relative '../lib/geodetic/coordinate/enu'
|
|
10
|
+
require_relative '../lib/geodetic/coordinate/ned'
|
|
11
|
+
require_relative '../lib/geodetic/coordinate/mgrs'
|
|
12
|
+
require_relative '../lib/geodetic/coordinate/web_mercator'
|
|
13
|
+
require_relative '../lib/geodetic/coordinate/ups'
|
|
14
|
+
require_relative '../lib/geodetic/coordinate/usng'
|
|
15
|
+
require_relative '../lib/geodetic/coordinate/state_plane'
|
|
16
|
+
require_relative '../lib/geodetic/coordinate/bng'
|
|
17
|
+
require_relative '../lib/geodetic/coordinate/gh36'
|
|
18
18
|
require_relative '../lib/geodetic/geoid_height'
|
|
19
19
|
|
|
20
20
|
include Geodetic
|
|
21
|
-
LLA =
|
|
22
|
-
ECEF =
|
|
23
|
-
UTM_Coord =
|
|
24
|
-
ENU =
|
|
25
|
-
NED =
|
|
26
|
-
MGRS =
|
|
27
|
-
USNG =
|
|
28
|
-
WebMerc =
|
|
29
|
-
UPS =
|
|
30
|
-
StatePlane =
|
|
31
|
-
BNG =
|
|
32
|
-
GH36 =
|
|
21
|
+
LLA = Coordinate::LLA
|
|
22
|
+
ECEF = Coordinate::ECEF
|
|
23
|
+
UTM_Coord = Coordinate::UTM
|
|
24
|
+
ENU = Coordinate::ENU
|
|
25
|
+
NED = Coordinate::NED
|
|
26
|
+
MGRS = Coordinate::MGRS
|
|
27
|
+
USNG = Coordinate::USNG
|
|
28
|
+
WebMerc = Coordinate::WebMercator
|
|
29
|
+
UPS = Coordinate::UPS
|
|
30
|
+
StatePlane = Coordinate::StatePlane
|
|
31
|
+
BNG = Coordinate::BNG
|
|
32
|
+
GH36 = Coordinate::GH36
|
|
33
33
|
|
|
34
34
|
def demo_coordinate_systems
|
|
35
35
|
puts "=" * 80
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../
|
|
3
|
+
require_relative '../coordinate/lla'
|
|
4
4
|
|
|
5
5
|
module Geodetic
|
|
6
6
|
module Areas
|
|
@@ -27,7 +27,7 @@ module Geodetic
|
|
|
27
27
|
centroid_lng /= (6.0 * area)
|
|
28
28
|
centroid_lat /= (6.0 * area)
|
|
29
29
|
|
|
30
|
-
@centroid =
|
|
30
|
+
@centroid = Coordinate::LLA.new(lat: centroid_lat, lng: centroid_lng, alt: 0.0)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def includes?(a_point)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative '../
|
|
3
|
+
require_relative '../coordinate/lla'
|
|
4
4
|
|
|
5
5
|
module Geodetic
|
|
6
6
|
module Areas
|
|
@@ -15,13 +15,13 @@ module Geodetic
|
|
|
15
15
|
# se: LLA.new(lat: 40.0, lng: -74.0)
|
|
16
16
|
# )
|
|
17
17
|
def initialize(nw:, se:)
|
|
18
|
-
@nw = nw.is_a?(
|
|
19
|
-
@se = se.is_a?(
|
|
18
|
+
@nw = nw.is_a?(Coordinate::LLA) ? nw : nw.to_lla
|
|
19
|
+
@se = se.is_a?(Coordinate::LLA) ? se : se.to_lla
|
|
20
20
|
|
|
21
21
|
raise ArgumentError, "NW corner must have higher latitude than SE corner" if @nw.lat < @se.lat
|
|
22
22
|
raise ArgumentError, "NW corner must have lower longitude than SE corner" if @nw.lng > @se.lng
|
|
23
23
|
|
|
24
|
-
@centroid =
|
|
24
|
+
@centroid = Coordinate::LLA.new(
|
|
25
25
|
lat: (@nw.lat + @se.lat) / 2.0,
|
|
26
26
|
lng: (@nw.lng + @se.lng) / 2.0,
|
|
27
27
|
alt: 0.0
|
|
@@ -29,11 +29,11 @@ module Geodetic
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def ne
|
|
32
|
-
|
|
32
|
+
Coordinate::LLA.new(lat: @nw.lat, lng: @se.lng, alt: 0.0)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def sw
|
|
36
|
-
|
|
36
|
+
Coordinate::LLA.new(lat: @se.lat, lng: @nw.lng, alt: 0.0)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def includes?(a_point)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# Uses Transverse Mercator projection with specific parameters
|
|
6
6
|
|
|
7
7
|
module Geodetic
|
|
8
|
-
module
|
|
8
|
+
module Coordinate
|
|
9
9
|
class BNG
|
|
10
10
|
require_relative '../datum'
|
|
11
11
|
|
|
@@ -228,42 +228,6 @@ module Geodetic
|
|
|
228
228
|
from_lla(lla_coord, datum)
|
|
229
229
|
end
|
|
230
230
|
|
|
231
|
-
def to_gh36(datum = WGS84, precision: 10)
|
|
232
|
-
GH36.new(to_lla(datum), precision: precision)
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def self.from_gh36(gh36_coord, datum = WGS84)
|
|
236
|
-
lla_coord = gh36_coord.to_lla(datum)
|
|
237
|
-
from_lla(lla_coord, datum)
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def to_gh(datum = WGS84, precision: 12)
|
|
241
|
-
GH.new(to_lla(datum), precision: precision)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def self.from_gh(gh_coord, datum = WGS84)
|
|
245
|
-
lla_coord = gh_coord.to_lla(datum)
|
|
246
|
-
from_lla(lla_coord, datum)
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
def to_ham(datum = WGS84, precision: 6)
|
|
250
|
-
HAM.new(to_lla(datum), precision: precision)
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def self.from_ham(ham_coord, datum = WGS84)
|
|
254
|
-
lla_coord = ham_coord.to_lla(datum)
|
|
255
|
-
from_lla(lla_coord, datum)
|
|
256
|
-
end
|
|
257
|
-
|
|
258
|
-
def to_olc(datum = WGS84, precision: 10)
|
|
259
|
-
OLC.new(to_lla(datum), precision: precision)
|
|
260
|
-
end
|
|
261
|
-
|
|
262
|
-
def self.from_olc(olc_coord, datum = WGS84)
|
|
263
|
-
lla_coord = olc_coord.to_lla(datum)
|
|
264
|
-
from_lla(lla_coord, datum)
|
|
265
|
-
end
|
|
266
|
-
|
|
267
231
|
def ==(other)
|
|
268
232
|
return false unless other.is_a?(BNG)
|
|
269
233
|
|
|
@@ -388,6 +352,8 @@ module Geodetic
|
|
|
388
352
|
|
|
389
353
|
new(easting: easting, northing: northing)
|
|
390
354
|
end
|
|
355
|
+
|
|
356
|
+
Coordinate.register_class(self)
|
|
391
357
|
end
|
|
392
358
|
end
|
|
393
359
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require_relative '../datum'
|
|
4
4
|
|
|
5
5
|
module Geodetic
|
|
6
|
-
module
|
|
6
|
+
module Coordinate
|
|
7
7
|
class ECEF
|
|
8
8
|
attr_reader :x, :y, :z
|
|
9
9
|
|
|
@@ -184,38 +184,6 @@ module Geodetic
|
|
|
184
184
|
bng_coord.to_ecef(datum)
|
|
185
185
|
end
|
|
186
186
|
|
|
187
|
-
def to_gh36(precision: 10)
|
|
188
|
-
GH36.new(to_lla, precision: precision)
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def self.from_gh36(gh36_coord, datum = WGS84)
|
|
192
|
-
gh36_coord.to_ecef(datum)
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def to_gh(precision: 12)
|
|
196
|
-
GH.new(to_lla, precision: precision)
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
def self.from_gh(gh_coord, datum = WGS84)
|
|
200
|
-
gh_coord.to_ecef(datum)
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def to_ham(precision: 6)
|
|
204
|
-
HAM.new(to_lla, precision: precision)
|
|
205
|
-
end
|
|
206
|
-
|
|
207
|
-
def self.from_ham(ham_coord, datum = WGS84)
|
|
208
|
-
ham_coord.to_ecef(datum)
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def to_olc(precision: 10)
|
|
212
|
-
OLC.new(to_lla, precision: precision)
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
def self.from_olc(olc_coord, datum = WGS84)
|
|
216
|
-
olc_coord.to_ecef(datum)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
187
|
def to_s(precision = 2)
|
|
220
188
|
precision = precision.to_i
|
|
221
189
|
if precision == 0
|
|
@@ -248,6 +216,8 @@ module Geodetic
|
|
|
248
216
|
delta_x <= 1e-6 && delta_y <= 1e-6 && delta_z <= 1e-6
|
|
249
217
|
end
|
|
250
218
|
|
|
219
|
+
|
|
220
|
+
Coordinate.register_class(self)
|
|
251
221
|
end
|
|
252
222
|
end
|
|
253
223
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
require_relative '../datum'
|
|
4
4
|
|
|
5
5
|
module Geodetic
|
|
6
|
-
module
|
|
6
|
+
module Coordinate
|
|
7
7
|
class ENU
|
|
8
8
|
attr_reader :e, :n, :u
|
|
9
9
|
alias_method :east, :e
|
|
@@ -194,6 +194,33 @@ module Geodetic
|
|
|
194
194
|
from_lla(lla, reference_lla)
|
|
195
195
|
end
|
|
196
196
|
|
|
197
|
+
def to_georef(reference_lla, precision: 8)
|
|
198
|
+
GEOREF.new(to_lla(reference_lla), precision: precision)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def self.from_georef(georef_coord, reference_lla)
|
|
202
|
+
lla = georef_coord.to_lla
|
|
203
|
+
from_lla(lla, reference_lla)
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def to_gars(reference_lla, precision: 7)
|
|
207
|
+
GARS.new(to_lla(reference_lla), precision: precision)
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def self.from_gars(gars_coord, reference_lla)
|
|
211
|
+
lla = gars_coord.to_lla
|
|
212
|
+
from_lla(lla, reference_lla)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def to_h3(reference_lla, precision: 7)
|
|
216
|
+
H3.new(to_lla(reference_lla), precision: precision)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def self.from_h3(h3_coord, reference_lla)
|
|
220
|
+
lla = h3_coord.to_lla
|
|
221
|
+
from_lla(lla, reference_lla)
|
|
222
|
+
end
|
|
223
|
+
|
|
197
224
|
def to_s(precision = 2)
|
|
198
225
|
precision = precision.to_i
|
|
199
226
|
if precision == 0
|
|
@@ -266,6 +293,8 @@ module Geodetic
|
|
|
266
293
|
def horizontal_distance_to_origin
|
|
267
294
|
Math.sqrt(@e**2 + @n**2)
|
|
268
295
|
end
|
|
296
|
+
|
|
297
|
+
Coordinate.register_class(self)
|
|
269
298
|
end
|
|
270
299
|
end
|
|
271
300
|
end
|