geodetic 0.0.1 → 0.2.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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +54 -0
  3. data/README.md +118 -22
  4. data/docs/assets/images/geodetic.jpg +0 -0
  5. data/docs/coordinate-systems/bng.md +5 -5
  6. data/docs/coordinate-systems/ecef.md +23 -23
  7. data/docs/coordinate-systems/enu.md +3 -3
  8. data/docs/coordinate-systems/gars.md +246 -0
  9. data/docs/coordinate-systems/georef.md +221 -0
  10. data/docs/coordinate-systems/gh.md +282 -0
  11. data/docs/coordinate-systems/gh36.md +6 -6
  12. data/docs/coordinate-systems/ham.md +207 -0
  13. data/docs/coordinate-systems/index.md +39 -29
  14. data/docs/coordinate-systems/lla.md +26 -26
  15. data/docs/coordinate-systems/mgrs.md +3 -3
  16. data/docs/coordinate-systems/ned.md +3 -3
  17. data/docs/coordinate-systems/olc.md +221 -0
  18. data/docs/coordinate-systems/state-plane.md +2 -2
  19. data/docs/coordinate-systems/ups.md +4 -4
  20. data/docs/coordinate-systems/usng.md +2 -2
  21. data/docs/coordinate-systems/utm.md +23 -23
  22. data/docs/coordinate-systems/web-mercator.md +7 -7
  23. data/docs/getting-started/installation.md +18 -14
  24. data/docs/getting-started/quick-start.md +11 -11
  25. data/docs/index.md +44 -15
  26. data/docs/reference/areas.md +15 -15
  27. data/docs/reference/conversions.md +38 -32
  28. data/docs/reference/datums.md +10 -17
  29. data/docs/reference/geoid-height.md +5 -5
  30. data/docs/reference/serialization.md +55 -47
  31. data/examples/01_basic_conversions.rb +10 -10
  32. data/examples/02_all_coordinate_systems.rb +24 -24
  33. data/lib/geodetic/areas/circle.rb +1 -1
  34. data/lib/geodetic/areas/polygon.rb +2 -2
  35. data/lib/geodetic/areas/rectangle.rb +6 -6
  36. data/lib/geodetic/{coordinates → coordinate}/bng.rb +3 -10
  37. data/lib/geodetic/{coordinates → coordinate}/ecef.rb +3 -9
  38. data/lib/geodetic/{coordinates → coordinate}/enu.rb +48 -1
  39. data/lib/geodetic/coordinate/gars.rb +233 -0
  40. data/lib/geodetic/coordinate/georef.rb +204 -0
  41. data/lib/geodetic/coordinate/gh.rb +161 -0
  42. data/lib/geodetic/{coordinates → coordinate}/gh36.rb +28 -163
  43. data/lib/geodetic/coordinate/ham.rb +226 -0
  44. data/lib/geodetic/{coordinates → coordinate}/lla.rb +58 -3
  45. data/lib/geodetic/{coordinates → coordinate}/mgrs.rb +3 -9
  46. data/lib/geodetic/{coordinates → coordinate}/ned.rb +48 -1
  47. data/lib/geodetic/coordinate/olc.rb +273 -0
  48. data/lib/geodetic/coordinate/spatial_hash.rb +342 -0
  49. data/lib/geodetic/{coordinates → coordinate}/state_plane.rb +48 -1
  50. data/lib/geodetic/{coordinates → coordinate}/ups.rb +3 -10
  51. data/lib/geodetic/{coordinates → coordinate}/usng.rb +3 -9
  52. data/lib/geodetic/{coordinates → coordinate}/utm.rb +3 -9
  53. data/lib/geodetic/{coordinates → coordinate}/web_mercator.rb +3 -9
  54. data/lib/geodetic/{coordinates.rb → coordinate.rb} +61 -39
  55. data/lib/geodetic/version.rb +1 -1
  56. data/lib/geodetic.rb +1 -1
  57. data/spatial_hash_idea.md +241 -0
  58. metadata +32 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aff287312f66448c5c97edde02c099b6bb6fbfa3e465afe604b744e6c50676dc
4
- data.tar.gz: 5800e7ac55fe3d6bd74a1383b21d9b7aae777d2999b42050e12a0b18633aca07
3
+ metadata.gz: 782ba82d99727dfa9a075fcdfb9dea89f631ebc78e0e105293745c64f77f9dae
4
+ data.tar.gz: 59e9c844470d77026a9929c8b9ffd01a5d065fd491d8efb67106b0903267c681
5
5
  SHA512:
6
- metadata.gz: a9f38b3a2587b77592d51549649042f25267929f09c515a5526fb53f5ca3a87a2ec8d665672ed0f90da2642f9ae00f1aa9b31db9bc076374b19ac6ec1f722fcf
7
- data.tar.gz: d3ed9287c2fe9d942e387df0d53754f0acdbc497235ac7a72c415be367bd766bb5b814efaefa6568809e68b3f90b3e4f3d059456f203b0bd03b341c94df16a65
6
+ metadata.gz: 38543deb9e8d62aa20b4a90c9602b0e97806d7d2f55dd9d308a138b9aea2b033e6f51656a9d247ce750d5abcd5298f170825a3f0e4f013a63198bc467e1f3d8c
7
+ data.tar.gz: fcb62fac876d350bd784d08bb17d45b7c14218a31ff6cfcce4be7e384e3f9a6a2c711ae3731b4a4241e5b34c062a8ddcdc2fb8ce6786ac114ff35d872ad8a7f3
data/CHANGELOG.md CHANGED
@@ -10,6 +10,60 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
10
10
 
11
11
  ## [Unreleased]
12
12
 
13
+
14
+ ## [0.2.0] - 2026-03-08
15
+
16
+ ### Added
17
+
18
+ - **2 new coordinate systems** bringing the total from 15 to 17:
19
+ - `Geodetic::Coordinate::GEOREF` — World Geographic Reference System (aviation/military geocode with variable precision from 15-degree tiles to 0.001-minute resolution)
20
+ - `Geodetic::Coordinate::GARS` — Global Area Reference System (NGA standard with 30-minute cells, 15-minute quadrants, and 5-minute keypads)
21
+ - Full cross-system conversions for GEOREF and GARS — all 17 coordinate systems convert to/from every other system (289 conversion paths)
22
+ - Spatial hash features for GEOREF and GARS: `neighbors`, `to_area`, `precision_in_meters`, `to_slug`, configurable precision
23
+ - Documentation pages: `docs/coordinate-systems/georef.md` and `docs/coordinate-systems/gars.md`
24
+
25
+ ### Changed
26
+
27
+ - **Namespace renamed**: `Geodetic::Coordinates` is now `Geodetic::Coordinate` (singular)
28
+ - **SpatialHash base class** (`lib/geodetic/coordinate/spatial_hash.rb`) — GH36, GH, HAM, OLC, GEOREF, and GARS now inherit from a shared base class that provides common behavior (neighbors, to_area, precision_in_meters, serialization, encoding/decoding contract)
29
+ - **Auto-generated hash conversions** — `SpatialHash.generate_hash_conversions_for` replaces 232 lines of hand-written boilerplate `to_gh`/`from_gh`/`to_ham`/`from_ham`/etc. methods across 7 coordinate classes
30
+ - **Self-registration** — each coordinate class calls `Coordinate.register_class(self)` at load time; `ALL_COORD_CLASSES` is populated from the registry instead of a manual list
31
+
32
+ ## [0.1.0] - 2026-03-08
33
+
34
+ ### Added
35
+
36
+ - **4 new coordinate systems** bringing the total from 11 to 15:
37
+ - `Geodetic::Coordinate::GH36` — Geohash-36 (radix-36 spatial hash, URL-friendly)
38
+ - `Geodetic::Coordinate::GH` — Geohash base-32 (standard geohash, supported by Elasticsearch, Redis, PostGIS)
39
+ - `Geodetic::Coordinate::HAM` — Maidenhead Locator System (amateur radio grid squares)
40
+ - `Geodetic::Coordinate::OLC` — Open Location Code / Plus Codes (Google's location encoding)
41
+ - **Full cross-system conversions** — all 15 coordinate systems convert to/from every other system (225 conversion paths)
42
+ - **Spatial hash features** for GH36, GH, HAM, and OLC:
43
+ - `neighbors` — returns all 8 adjacent grid cells
44
+ - `to_area` — returns the cell as a `Geodetic::Areas::Rectangle`
45
+ - `precision_in_meters` — cell size in meters as `{ lat:, lng: }`
46
+ - `to_slug` — URL-friendly string representation
47
+ - Configurable precision on construction
48
+ - **Geographic areas** — `Geodetic::Areas::Circle`, `Geodetic::Areas::Polygon`, and `Geodetic::Areas::Rectangle` for point-in-area testing
49
+ - **Bearing calculations** — universal `bearing_to` and `elevation_to` methods on all coordinate classes via `BearingMethods` mixin
50
+ - **`Geodetic::Bearing` class** — immutable value type with compass directions, reciprocal, radians, arithmetic, and `Comparable`
51
+ - **Validated setters** with type coercion and range validation on all mutable coordinate classes
52
+ - **`to_s(precision)`** on all coordinate classes, `Distance`, and `Bearing` with class-specific defaults
53
+ - **ENU and NED local methods** — `local_bearing_to` and `local_elevation_angle_to` for tangent-plane operations; NED adds `horizontal_distance_to`
54
+ - **GitHub Pages documentation** site with MkDocs
55
+
56
+ ### Changed
57
+
58
+ - Coordinate classes use `attr_reader` with validated setter methods instead of `attr_accessor`
59
+ - ENU/NED bearing methods renamed: `bearing_to` → `local_bearing_to`, `elevation_angle_to` → `local_elevation_angle_to` (universal `bearing_to`/`elevation_to` now come from the mixin)
60
+
61
+ ### Fixed
62
+
63
+ - ENU/NED argument mismatch in 8 coordinate classes — `to_enu`/`to_ned` passed extra `datum` arg that `LLA#to_enu`/`LLA#to_ned` does not accept
64
+ - StatePlane `lambert_conformal_conic_to_lla` double `DEG_PER_RAD` conversion producing incorrect results
65
+ - OLC floating-point encoding error — pre-computed `PAIR_RESOLUTIONS` with epsilon correction prevents truncation (e.g., Google HQ encoding "849VCWC8+R9")
66
+
13
67
  ## [0.0.1] - 2026-03-07
14
68
 
15
69
  Initial update from an old archived project.
data/README.md CHANGED
@@ -1,23 +1,33 @@
1
1
  # Geodetic
2
2
 
3
- A Ruby gem for converting between geodetic coordinate systems. Supports 12 coordinate systems with full bidirectional conversions, plus geoid height calculations and geographic area operations.
4
-
5
- ## Coordinate Systems
6
-
7
- | Class | Description |
8
- |-------|-------------|
9
- | `Coordinates::LLA` | Latitude, Longitude, Altitude (degrees/meters) |
10
- | `Coordinates::ECEF` | Earth-Centered, Earth-Fixed (meters) |
11
- | `Coordinates::UTM` | Universal Transverse Mercator |
12
- | `Coordinates::ENU` | East, North, Up (local tangent plane) |
13
- | `Coordinates::NED` | North, East, Down (local tangent plane) |
14
- | `Coordinates::MGRS` | Military Grid Reference System |
15
- | `Coordinates::USNG` | US National Grid |
16
- | `Coordinates::WebMercator` | Web Mercator / EPSG:3857 |
17
- | `Coordinates::UPS` | Universal Polar Stereographic |
18
- | `Coordinates::StatePlane` | US State Plane Coordinate System |
19
- | `Coordinates::BNG` | British National Grid |
20
- | `Coordinates::GH36` | Geohash-36 (spatial hash, URL-friendly) |
3
+ > [!INFO]
4
+ > See the [CHANGELOG](CHANGELOG.md) for the latest changes. The [examples directory has runnable demo apps](examples/) that show-off the various capabilities of the Geodetic library.
5
+
6
+ <br>
7
+ <table>
8
+ <tr>
9
+ <td width="50%" align="center" valign="top">
10
+ <img src="docs/assets/images/geodetic.jpg" alt="Geodetic"><br>
11
+ <em>"Convert coordinates. Map the world."</em>
12
+ </td>
13
+ <td width="50%" valign="top">
14
+ <strong>Key Features</strong><br>
15
+
16
+ - <strong>17 Coordinate Systems</strong> - LLA, ECEF, UTM, ENU, NED, MGRS, USNG, Web Mercator, UPS, State Plane, BNG, GH36, GH, HAM, OLC, GEOREF, GARS<br>
17
+ - <strong>Full Bidirectional Conversions</strong> - Every system converts to and from every other system<br>
18
+ - <strong>Distance Calculations</strong> - Vincenty great-circle and straight-line with unit tracking<br>
19
+ - <strong>Bearing Calculations</strong> - Forward azimuth, back azimuth, compass directions, elevation angles<br>
20
+ - <strong>Geoid Height Support</strong> - EGM96, EGM2008, GEOID18, GEOID12B models<br>
21
+ - <strong>Geographic Areas</strong> - Circle, Polygon, and Rectangle with point-in-area tests<br>
22
+ - <strong>Validated Setters</strong> - Type coercion and range validation on all coordinate attributes<br>
23
+ - <strong>Serialization</strong> - to_s(precision), to_a, from_string, from_array, DMS format<br>
24
+ - <strong>Multiple Datums</strong> - WGS84, Clarke 1866, GRS 1980, Airy 1830, and more<br>
25
+ - <strong>Immutable Value Types</strong> - Distance and Bearing with arithmetic and comparison
26
+ </td>
27
+ </tr>
28
+ </table>
29
+
30
+ <p>Geodetic enables precise conversion between geodetic coordinate systems in Ruby. All 17 coordinate systems support complete bidirectional conversions with high precision. Review the <a href="https://madbomber.github.io/geodetic/">full documentation website</a> and explore the <a href="examples/">runnable examples</a>.</p>
21
31
 
22
32
  ## Installation
23
33
 
@@ -53,12 +63,12 @@ ned = Coordinates::NED.new(n: 200.0, e: 100.0, d: -50.0)
53
63
 
54
64
  ### GCS Shorthand
55
65
 
56
- `GCS` is a top-level alias for `Geodetic::Coordinates`, providing a concise way to create and work with coordinates:
66
+ `GCS` is a top-level alias for `Geodetic::Coordinate`, providing a concise way to create and work with coordinates:
57
67
 
58
68
  ```ruby
59
69
  require "geodetic"
60
70
 
61
- # Use GCS as a shorthand for Geodetic::Coordinates
71
+ # Use GCS as a shorthand for Geodetic::Coordinate
62
72
  seattle = GCS::LLA.new(lat: 47.6205, lng: -122.3493, alt: 184.0)
63
73
  ecef = GCS::ECEF.new(x: -2304643.57, y: -3638650.07, z: 4688674.43)
64
74
  ```
@@ -129,7 +139,7 @@ bng = Coordinates::BNG.new(easting: 530000, northing: 180000)
129
139
  bng.easting = 430000 # grid_ref automatically recalculated
130
140
  ```
131
141
 
132
- ECEF, ENU, NED, and WebMercator setters coerce to float with no range constraints. MGRS, USNG, GH36, Distance, and Bearing are immutable.
142
+ ECEF, ENU, NED, and WebMercator setters coerce to float with no range constraints. MGRS, USNG, GH36, GH, HAM, OLC, Distance, and Bearing are immutable.
133
143
 
134
144
  ### DMS (Degrees, Minutes, Seconds)
135
145
 
@@ -396,6 +406,90 @@ gh36.precision # => 10
396
406
  gh36.precision_in_meters # => { lat: 0.31, lng: 0.62 }
397
407
  ```
398
408
 
409
+ ### Geohash (GH)
410
+
411
+ The standard Geohash (base-32) algorithm by Gustavo Niemeyer, widely supported by Elasticsearch, Redis, PostGIS, and geocoding services:
412
+
413
+ ```ruby
414
+ # From a geohash string
415
+ gh = Coordinates::GH.new("dr5ru7")
416
+
417
+ # From any coordinate
418
+ gh = Coordinates::GH.new(lla)
419
+ gh = lla.to_gh(precision: 8)
420
+
421
+ # Decode back to LLA
422
+ lla = gh.to_lla
423
+
424
+ # URL slug (the hash itself is URL-safe)
425
+ gh.to_slug # => "dr5ru7"
426
+
427
+ # Neighbor cells
428
+ gh.neighbors # => { N: GH, S: GH, E: GH, W: GH, NE: ..., NW: ..., SE: ..., SW: ... }
429
+
430
+ # Bounding rectangle of the geohash cell
431
+ area = gh.to_area # => Areas::Rectangle
432
+ area.includes?(gh.to_lla) # => true
433
+
434
+ # Precision info
435
+ gh.precision # => 6
436
+ gh.precision_in_meters # => { lat: 610.98, lng: 1221.97 }
437
+ ```
438
+
439
+ ### Maidenhead Locator (HAM)
440
+
441
+ The Maidenhead Locator System used worldwide in amateur radio for grid square identification:
442
+
443
+ ```ruby
444
+ # From a Maidenhead locator string
445
+ ham = Coordinates::HAM.new("FN31pr")
446
+
447
+ # From any coordinate
448
+ ham = Coordinates::HAM.new(lla)
449
+ ham = lla.to_ham(precision: 8)
450
+
451
+ # Decode back to LLA
452
+ lla = ham.to_lla
453
+
454
+ # Neighbor cells
455
+ ham.neighbors # => { N: HAM, S: HAM, E: HAM, W: HAM, NE: ..., NW: ..., SE: ..., SW: ... }
456
+
457
+ # Bounding rectangle of the grid square
458
+ area = ham.to_area # => Areas::Rectangle
459
+ area.includes?(ham.to_lla) # => true
460
+
461
+ # Precision info
462
+ ham.precision # => 6
463
+ ham.precision_in_meters # => { lat: 4631.0, lng: 9260.0 }
464
+ ```
465
+
466
+ ### Open Location Code / Plus Codes (OLC)
467
+
468
+ Google's open system for encoding locations into short, URL-friendly codes:
469
+
470
+ ```ruby
471
+ # From a plus code string
472
+ olc = Coordinates::OLC.new("849VCWC8+R9")
473
+
474
+ # From any coordinate
475
+ olc = Coordinates::OLC.new(lla)
476
+ olc = lla.to_olc(precision: 11)
477
+
478
+ # Decode back to LLA
479
+ lla = olc.to_lla
480
+
481
+ # Neighbor cells
482
+ olc.neighbors # => { N: OLC, S: OLC, E: OLC, W: OLC, NE: ..., NW: ..., SE: ..., SW: ... }
483
+
484
+ # Bounding rectangle of the plus code cell
485
+ area = olc.to_area # => Areas::Rectangle
486
+ area.includes?(olc.to_lla) # => true
487
+
488
+ # Precision info
489
+ olc.precision # => 10
490
+ olc.precision_in_meters # => { lat: 13.9, lng: 13.9 }
491
+ ```
492
+
399
493
  ### Geographic Areas
400
494
 
401
495
  ```ruby
@@ -448,7 +542,7 @@ The [`examples/`](examples/) directory contains runnable demo scripts showing pr
448
542
  | Script | Description |
449
543
  |--------|-------------|
450
544
  | [`01_basic_conversions.rb`](examples/01_basic_conversions.rb) | LLA, ECEF, UTM, ENU, NED conversions and roundtrips |
451
- | [`02_all_coordinate_systems.rb`](examples/02_all_coordinate_systems.rb) | All 12 coordinate systems, cross-system chains, and areas |
545
+ | [`02_all_coordinate_systems.rb`](examples/02_all_coordinate_systems.rb) | All 17 coordinate systems, cross-system chains, and areas |
452
546
  | [`03_distance_calculations.rb`](examples/03_distance_calculations.rb) | Distance class features, unit conversions, and arithmetic |
453
547
  | [`04_bearing_calculations.rb`](examples/04_bearing_calculations.rb) | Bearing class, compass directions, elevation angles, and chain bearings |
454
548
 
@@ -460,6 +554,8 @@ ruby -Ilib examples/01_basic_conversions.rb
460
554
 
461
555
  ## Development
462
556
 
557
+ For comprehensive guides and API documentation, visit **[https://madbomber.github.io/geodetic](https://madbomber.github.io/geodetic)**
558
+
463
559
  ```bash
464
560
  bin/setup # Install dependencies
465
561
  rake test # Run tests
Binary file
@@ -1,4 +1,4 @@
1
- # Geodetic::Coordinates::BNG
1
+ # Geodetic::Coordinate::BNG
2
2
 
3
3
  ## British National Grid
4
4
 
@@ -9,13 +9,13 @@ The British National Grid (BNG) is the official coordinate system for Great Brit
9
9
  Create a BNG coordinate from numeric easting/northing values:
10
10
 
11
11
  ```ruby
12
- point = Geodetic::Coordinates::BNG.new(easting: 530000.0, northing: 180000.0)
12
+ point = Geodetic::Coordinate::BNG.new(easting: 530000.0, northing: 180000.0)
13
13
  ```
14
14
 
15
15
  Alternatively, create from an alphanumeric grid reference string:
16
16
 
17
17
  ```ruby
18
- point = Geodetic::Coordinates::BNG.new(grid_ref: "TQ 300000 800000")
18
+ point = Geodetic::Coordinate::BNG.new(grid_ref: "TQ 300000 800000")
19
19
  ```
20
20
 
21
21
  ## Grid References
@@ -52,8 +52,8 @@ point.valid? # => true if within Great Britain bounds
52
52
  The universal `distance_to` method computes the Vincenty great-circle distance to any other coordinate type, returning a `Distance` object. The `straight_line_distance_to` method computes the Euclidean distance in ECEF space. The universal `bearing_to` method computes the great-circle forward azimuth, returning a `Bearing` object. All accept single or multiple targets.
53
53
 
54
54
  ```ruby
55
- bng_a = Geodetic::Coordinates::BNG.new(easting: 530000.0, northing: 180000.0)
56
- bng_b = Geodetic::Coordinates::BNG.new(easting: 540000.0, northing: 190000.0)
55
+ bng_a = Geodetic::Coordinate::BNG.new(easting: 530000.0, northing: 180000.0)
56
+ bng_b = Geodetic::Coordinate::BNG.new(easting: 540000.0, northing: 190000.0)
57
57
  bng_a.distance_to(bng_b) # => Distance (great-circle)
58
58
  bng_a.straight_line_distance_to(bng_b) # => Distance (Euclidean)
59
59
  bng_a.bearing_to(bng_b) # => Bearing (great-circle forward azimuth)
@@ -1,4 +1,4 @@
1
- # Geodetic::Coordinates::ECEF
1
+ # Geodetic::Coordinate::ECEF
2
2
 
3
3
  Earth-Centered, Earth-Fixed -- a Cartesian coordinate system with its origin at the center of mass of the Earth. The X axis points toward the intersection of the Prime Meridian and the Equator, the Y axis points toward 90 degrees East longitude on the Equator, and the Z axis points toward the North Pole. All values are in meters.
4
4
 
@@ -7,7 +7,7 @@ ECEF is useful for satellite positioning, radar tracking, and any application re
7
7
  ## Constructor
8
8
 
9
9
  ```ruby
10
- Geodetic::Coordinates::ECEF.new(x: 0.0, y: 0.0, z: 0.0)
10
+ Geodetic::Coordinate::ECEF.new(x: 0.0, y: 0.0, z: 0.0)
11
11
  ```
12
12
 
13
13
  | Parameter | Type | Default | Description |
@@ -35,9 +35,9 @@ All conversion methods accept an optional `datum` parameter (defaults to `Geodet
35
35
  Converts to geodetic Latitude, Longitude, Altitude coordinates using an iterative algorithm. The iteration converges when both latitude and altitude changes are below `1e-12`, with a maximum of 100 iterations.
36
36
 
37
37
  ```ruby
38
- ecef = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
38
+ ecef = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
39
39
  lla = ecef.to_lla
40
- # => Geodetic::Coordinates::LLA
40
+ # => Geodetic::Coordinate::LLA
41
41
  ```
42
42
 
43
43
  ### ECEF.from_lla(lla, datum = WGS84)
@@ -45,7 +45,7 @@ lla = ecef.to_lla
45
45
  Creates an ECEF from an LLA instance. Raises `ArgumentError` if the argument is not an `LLA`.
46
46
 
47
47
  ```ruby
48
- ecef = Geodetic::Coordinates::ECEF.from_lla(lla)
48
+ ecef = Geodetic::Coordinate::ECEF.from_lla(lla)
49
49
  ```
50
50
 
51
51
  ### to_utm(datum = WGS84)
@@ -54,7 +54,7 @@ Converts to Universal Transverse Mercator coordinates. Internally converts to LL
54
54
 
55
55
  ```ruby
56
56
  utm = ecef.to_utm
57
- # => Geodetic::Coordinates::UTM
57
+ # => Geodetic::Coordinate::UTM
58
58
  ```
59
59
 
60
60
  ### ECEF.from_utm(utm, datum = WGS84)
@@ -66,10 +66,10 @@ Creates an ECEF from a UTM instance. Raises `ArgumentError` if the argument is n
66
66
  Converts to East-North-Up local tangent plane coordinates relative to a reference ECEF position. If `reference_lla` is not provided, it is computed from `reference_ecef` via `to_lla`.
67
67
 
68
68
  ```ruby
69
- ref_ecef = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
70
- point_ecef = Geodetic::Coordinates::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
69
+ ref_ecef = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
70
+ point_ecef = Geodetic::Coordinate::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
71
71
  enu = point_ecef.to_enu(ref_ecef)
72
- # => Geodetic::Coordinates::ENU
72
+ # => Geodetic::Coordinate::ENU
73
73
  ```
74
74
 
75
75
  Raises `ArgumentError` if `reference_ecef` is not an `ECEF`.
@@ -84,7 +84,7 @@ Converts to North-East-Down local tangent plane coordinates. Internally converts
84
84
 
85
85
  ```ruby
86
86
  ned = point_ecef.to_ned(ref_ecef)
87
- # => Geodetic::Coordinates::NED
87
+ # => Geodetic::Coordinate::NED
88
88
  ```
89
89
 
90
90
  ### ECEF.from_ned(ned, reference_ecef, reference_lla = nil)
@@ -98,7 +98,7 @@ Creates an ECEF from a NED instance and a reference ECEF origin. Raises `Argumen
98
98
  Returns a comma-separated string of `x, y, z`.
99
99
 
100
100
  ```ruby
101
- ecef = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
101
+ ecef = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
102
102
  ecef.to_s
103
103
  # => "1130730.0, -4828583.0, 3991570.0"
104
104
  ```
@@ -117,7 +117,7 @@ ecef.to_a
117
117
  Parses a comma-separated string into an ECEF.
118
118
 
119
119
  ```ruby
120
- ecef = Geodetic::Coordinates::ECEF.from_string("1130730.0, -4828583.0, 3991570.0")
120
+ ecef = Geodetic::Coordinate::ECEF.from_string("1130730.0, -4828583.0, 3991570.0")
121
121
  ```
122
122
 
123
123
  ### ECEF.from_array(array)
@@ -125,7 +125,7 @@ ecef = Geodetic::Coordinates::ECEF.from_string("1130730.0, -4828583.0, 3991570.0
125
125
  Creates an ECEF from a three-element array `[x, y, z]`.
126
126
 
127
127
  ```ruby
128
- ecef = Geodetic::Coordinates::ECEF.from_array([1130730.0, -4828583.0, 3991570.0])
128
+ ecef = Geodetic::Coordinate::ECEF.from_array([1130730.0, -4828583.0, 3991570.0])
129
129
  ```
130
130
 
131
131
  ## Additional Methods
@@ -135,8 +135,8 @@ ecef = Geodetic::Coordinates::ECEF.from_array([1130730.0, -4828583.0, 3991570.0]
135
135
  Compares two ECEF instances for approximate equality. Returns `true` if the absolute difference for each of `x`, `y`, and `z` is `<= 1e-6` meters. Returns `false` if `other` is not an `ECEF`.
136
136
 
137
137
  ```ruby
138
- a = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
139
- b = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
138
+ a = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
139
+ b = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
140
140
  a == b
141
141
  # => true
142
142
  ```
@@ -146,8 +146,8 @@ a == b
146
146
  Computes the Vincenty great-circle distance to one or more other coordinates. Accepts any coordinate type (coordinates are converted to LLA internally). Returns a `Distance` for a single target or an Array of `Distance` objects for multiple targets (radial distances from the receiver).
147
147
 
148
148
  ```ruby
149
- a = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
150
- b = Geodetic::Coordinates::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
149
+ a = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
150
+ b = Geodetic::Coordinate::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
151
151
  a.distance_to(b)
152
152
  # => Distance (meters, great-circle distance)
153
153
  ```
@@ -169,7 +169,7 @@ a.straight_line_distance_to(b)
169
169
  require 'geodetic'
170
170
 
171
171
  # Create an ECEF coordinate
172
- ecef = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
172
+ ecef = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
173
173
 
174
174
  # Convert to LLA and back
175
175
  lla = ecef.to_lla
@@ -181,8 +181,8 @@ ecef == ecef_roundtrip
181
181
  ### Distance between two points
182
182
 
183
183
  ```ruby
184
- station_a = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
185
- station_b = Geodetic::Coordinates::ECEF.new(x: 1131000.0, y: -4828300.0, z: 3991800.0)
184
+ station_a = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
185
+ station_b = Geodetic::Coordinate::ECEF.new(x: 1131000.0, y: -4828300.0, z: 3991800.0)
186
186
 
187
187
  # Great-circle distance (Vincenty)
188
188
  distance = station_a.distance_to(station_b)
@@ -196,8 +196,8 @@ puts "Straight-line distance: #{straight.meters} meters"
196
196
  ### Local tangent plane from ECEF
197
197
 
198
198
  ```ruby
199
- origin = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
200
- target = Geodetic::Coordinates::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
199
+ origin = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
200
+ target = Geodetic::Coordinate::ECEF.new(x: 1130740.0, y: -4828573.0, z: 3991580.0)
201
201
 
202
202
  # Provide reference LLA to avoid recomputing it
203
203
  ref_lla = origin.to_lla
@@ -210,6 +210,6 @@ ned = target.to_ned(origin, ref_lla)
210
210
 
211
211
  ```ruby
212
212
  clarke66 = Geodetic::Datum.new(name: 'CLARKE_1866')
213
- ecef = Geodetic::Coordinates::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
213
+ ecef = Geodetic::Coordinate::ECEF.new(x: 1130730.0, y: -4828583.0, z: 3991570.0)
214
214
  lla = ecef.to_lla(clarke66)
215
215
  ```
@@ -1,4 +1,4 @@
1
- # Geodetic::Coordinates::ENU - East, North, Up
1
+ # Geodetic::Coordinate::ENU - East, North, Up
2
2
 
3
3
  ## Overview
4
4
 
@@ -52,7 +52,7 @@ The one exception is the conversion between ENU and NED, which does not require
52
52
  ENU is a relative coordinate system. The universal `distance_to`, `straight_line_distance_to`, `bearing_to`, and `elevation_to` methods raise `ArgumentError` because ENU cannot be converted to an absolute system without a reference point. Convert to an absolute system first:
53
53
 
54
54
  ```ruby
55
- ref = Geodetic::Coordinates::LLA.new(lat: 47.62, lng: -122.35, alt: 0.0)
55
+ ref = Geodetic::Coordinate::LLA.new(lat: 47.62, lng: -122.35, alt: 0.0)
56
56
  lla = enu.to_lla(ref)
57
57
  lla.distance_to(other_lla) # Vincenty great-circle distance
58
58
  lla.bearing_to(other_lla) # Great-circle forward azimuth (Bearing object)
@@ -65,7 +65,7 @@ Bearing is measured in **degrees from north**, clockwise, in the range **0-360**
65
65
  ## Example
66
66
 
67
67
  ```ruby
68
- point = Geodetic::Coordinates::ENU.new(e: 100.0, n: 200.0, u: 50.0)
68
+ point = Geodetic::Coordinate::ENU.new(e: 100.0, n: 200.0, u: 50.0)
69
69
 
70
70
  point.east # => 100.0
71
71
  point.north # => 200.0