geodetic 0.5.1 → 0.5.2
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 +23 -0
- data/README.md +9 -0
- data/docs/reference/geojson.md +68 -0
- data/examples/09_geojson_export.rb +1 -2
- data/examples/geodetic_demo.geojson +305 -0
- data/lib/geodetic/geojson.rb +89 -0
- data/lib/geodetic/version.rb +1 -1
- data/mkdocs.yml +10 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 44b5221a45f63382e712aa88d033d1cb0b8165f8804833a1fd8523a9d7d8ce32
|
|
4
|
+
data.tar.gz: 787dc88782b277262e15dde4fa1f61801894d1d34eff304dc63965147a3b10e8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ffb91f043c3c0c9a2bb6b44fad7952936121a09b18879350398cf260fd2be1f594f33c405df7cea0027f59c0e06679f1d4f718192d7626032a4b5fab195626f9
|
|
7
|
+
data.tar.gz: dd922521aa23db80a5d9fdf56dbb98dcdfab811f72a126978d9b8dffe248f72f3dd83c3cae1e41d3ee2a1cf11455d70120d6c81fff7523f3aac798397250fbca
|
data/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
10
|
|
|
11
|
+
## [0.5.2] - 2026-03-10
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`Geodetic::GeoJSON.load(path)`** — read a GeoJSON file and return an Array of Geodetic objects
|
|
16
|
+
- **`Geodetic::GeoJSON.parse(hash)`** — same as `load` but accepts an already-parsed Ruby Hash
|
|
17
|
+
- Roundtrip-safe import: Features with `"name"` or non-empty properties restore as `Geodetic::Feature` (label from `"name"`, remaining properties as `metadata` with symbol keys); Features with empty properties restore as raw geometry
|
|
18
|
+
- GeoJSON → Geodetic type mapping:
|
|
19
|
+
- Point → `Coordinate::LLA` (altitude preserved when present)
|
|
20
|
+
- LineString (2 points) → `Segment`
|
|
21
|
+
- LineString (3+ points) → `Path`
|
|
22
|
+
- Polygon → `Areas::Polygon` (outer ring; holes dropped)
|
|
23
|
+
- MultiPoint, MultiLineString, MultiPolygon → flattened into multiple objects
|
|
24
|
+
- GeometryCollection → flattened into individual geometries
|
|
25
|
+
- 17 new tests covering load, parse, roundtrip, multi-geometries, and edge cases
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Updated README with `GeoJSON.load` usage example
|
|
30
|
+
- Updated `docs/reference/geojson.md` with Import section, type mapping table, and roundtrip example
|
|
31
|
+
- Updated `mkdocs.yml` nav to include all 7 missing coordinate systems (GH36, GH, HAM, OLC, GEOREF, GARS, H3) and 3 missing reference pages (Vector, Arithmetic, GeoJSON Export)
|
|
32
|
+
- GeoJSON demo (`examples/09_geojson_export.rb`) now saves output to `examples/` directory instead of system temp
|
|
33
|
+
|
|
11
34
|
## [0.5.1] - 2026-03-10
|
|
12
35
|
|
|
13
36
|
### Added
|
data/README.md
CHANGED
|
@@ -760,6 +760,15 @@ feature.to_geojson # => {"type" => "Feature", ...}
|
|
|
760
760
|
|
|
761
761
|
Features carry their `label` as `"name"` and `metadata` as `properties` in the GeoJSON output. Non-Feature objects added to the collection are auto-wrapped as Features with empty properties.
|
|
762
762
|
|
|
763
|
+
**Loading GeoJSON files:**
|
|
764
|
+
|
|
765
|
+
```ruby
|
|
766
|
+
objects = Geodetic::GeoJSON.load("map.geojson")
|
|
767
|
+
# => [Feature("Seattle", LLA), Segment, Path, Polygon, LLA, ...]
|
|
768
|
+
```
|
|
769
|
+
|
|
770
|
+
`load` returns an Array of Geodetic objects. Features with a `"name"` or non-empty properties round-trip as `Feature` objects; bare geometries with empty properties return as raw coordinates, segments, paths, or polygons. `GeoJSON.parse(hash)` does the same from an already-parsed Hash.
|
|
771
|
+
|
|
763
772
|
### Web Mercator Tile Coordinates
|
|
764
773
|
|
|
765
774
|
```ruby
|
data/docs/reference/geojson.md
CHANGED
|
@@ -99,6 +99,60 @@ gj.to_s # => "GeoJSON::FeatureCollection(5 features)"
|
|
|
99
99
|
gj.inspect # => "#<Geodetic::GeoJSON size=5>"
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
### Import
|
|
103
|
+
|
|
104
|
+
| Method | Returns | Description |
|
|
105
|
+
|--------|---------|-------------|
|
|
106
|
+
| `GeoJSON.load(path)` | Array | Read a GeoJSON file and return an Array of Geodetic objects |
|
|
107
|
+
| `GeoJSON.parse(hash)` | Array | Parse a GeoJSON Hash and return an Array of Geodetic objects |
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
objects = Geodetic::GeoJSON.load("west_coast.geojson")
|
|
111
|
+
# => [Feature("Seattle", LLA), Feature("Portland", LLA), Segment, Polygon, ...]
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
`parse` accepts a Ruby Hash (useful when you already have parsed JSON):
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
data = JSON.parse(File.read("west_coast.geojson"))
|
|
118
|
+
objects = Geodetic::GeoJSON.parse(data)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**GeoJSON → Geodetic type mapping:**
|
|
122
|
+
|
|
123
|
+
| GeoJSON type | Geodetic type |
|
|
124
|
+
|--------------|---------------|
|
|
125
|
+
| Point | `Coordinate::LLA` |
|
|
126
|
+
| LineString (2 points) | `Segment` |
|
|
127
|
+
| LineString (3+ points) | `Path` |
|
|
128
|
+
| Polygon | `Areas::Polygon` (outer ring only; holes are dropped) |
|
|
129
|
+
| MultiPoint | Multiple `Coordinate::LLA` |
|
|
130
|
+
| MultiLineString | Multiple `Segment` or `Path` |
|
|
131
|
+
| MultiPolygon | Multiple `Areas::Polygon` |
|
|
132
|
+
| GeometryCollection | Flattened into individual geometries |
|
|
133
|
+
|
|
134
|
+
**Feature handling:**
|
|
135
|
+
|
|
136
|
+
- A GeoJSON Feature with a `"name"` property or any non-empty properties becomes a `Geodetic::Feature`. The `"name"` property maps to `label`, and remaining properties become `metadata` with symbol keys.
|
|
137
|
+
- A GeoJSON Feature with empty properties (`{}`) returns the raw geometry with no Feature wrapper.
|
|
138
|
+
|
|
139
|
+
This means a save/load roundtrip preserves Feature labels, metadata, and geometry types:
|
|
140
|
+
|
|
141
|
+
```ruby
|
|
142
|
+
# Save
|
|
143
|
+
gj = Geodetic::GeoJSON.new
|
|
144
|
+
gj << Geodetic::Feature.new(label: "Seattle", geometry: seattle, metadata: { state: "WA" })
|
|
145
|
+
gj << portland # raw coordinate, no Feature
|
|
146
|
+
gj.save("cities.geojson")
|
|
147
|
+
|
|
148
|
+
# Load
|
|
149
|
+
objects = Geodetic::GeoJSON.load("cities.geojson")
|
|
150
|
+
objects[0] # => Feature (label: "Seattle", metadata: {state: "WA"})
|
|
151
|
+
objects[0].label # => "Seattle"
|
|
152
|
+
objects[0].metadata # => {state: "WA"}
|
|
153
|
+
objects[1] # => LLA (raw coordinate, no Feature wrapper)
|
|
154
|
+
```
|
|
155
|
+
|
|
102
156
|
---
|
|
103
157
|
|
|
104
158
|
## Geometry Mapping
|
|
@@ -317,4 +371,18 @@ The output file can be opened directly in [geojson.io](https://geojson.io), QGIS
|
|
|
317
371
|
- **Altitude** is optional. Included as the third element when non-zero.
|
|
318
372
|
- **Polygon rings** follow the right-hand rule: exterior rings are counterclockwise. BoundingBox uses NW → NE → SE → SW → NW.
|
|
319
373
|
- **String keys** are used throughout (`"type"`, `"coordinates"`, `"properties"`, etc.) per JSON convention.
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Visualizing GeoJSON
|
|
378
|
+
|
|
379
|
+
The easiest way to verify your exported GeoJSON is [geojson.io](https://geojson.io). It renders points, lines, and polygons on an interactive map with property inspection.
|
|
380
|
+
|
|
381
|
+
To use it:
|
|
382
|
+
|
|
383
|
+
1. Export your collection: `gj.save("my_map.geojson", pretty: true)`
|
|
384
|
+
2. Open [geojson.io](https://geojson.io) in a browser
|
|
385
|
+
3. Drag and drop the `.geojson` file onto the map, or paste the JSON into the editor panel
|
|
386
|
+
|
|
387
|
+
Feature properties (name, metadata) appear in popups when you click on a rendered geometry. This makes it a quick way to confirm that coordinates, shapes, and metadata are correct before integrating with QGIS, Mapbox, Leaflet, or other GIS tools.
|
|
320
388
|
- Output is a Ruby Hash. Call `.to_json` or `JSON.generate(hash)` to produce a JSON string.
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
# and save it to a file that can be opened in any GeoJSON viewer.
|
|
6
6
|
|
|
7
7
|
require_relative "../lib/geodetic"
|
|
8
|
-
require "tmpdir"
|
|
9
8
|
|
|
10
9
|
include Geodetic
|
|
11
10
|
|
|
@@ -239,7 +238,7 @@ puts " to_json(pretty: true): #{pretty.length} bytes, #{pretty.lines.count} lin
|
|
|
239
238
|
puts
|
|
240
239
|
|
|
241
240
|
# save to file
|
|
242
|
-
output_path = File.join(
|
|
241
|
+
output_path = File.join(__dir__, "geodetic_demo.geojson")
|
|
243
242
|
gj.save(output_path, pretty: true)
|
|
244
243
|
puts " Saved to: #{output_path}"
|
|
245
244
|
puts " File size: #{File.size(output_path)} bytes"
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "FeatureCollection",
|
|
3
|
+
"features": [
|
|
4
|
+
{
|
|
5
|
+
"type": "Feature",
|
|
6
|
+
"geometry": {
|
|
7
|
+
"type": "Point",
|
|
8
|
+
"coordinates": [
|
|
9
|
+
-122.3493,
|
|
10
|
+
47.6205
|
|
11
|
+
]
|
|
12
|
+
},
|
|
13
|
+
"properties": {
|
|
14
|
+
"name": "Seattle",
|
|
15
|
+
"type": "city"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "Feature",
|
|
20
|
+
"geometry": {
|
|
21
|
+
"type": "Point",
|
|
22
|
+
"coordinates": [
|
|
23
|
+
-122.6784,
|
|
24
|
+
45.5152
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"properties": {
|
|
28
|
+
"name": "Portland",
|
|
29
|
+
"type": "city"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "Feature",
|
|
34
|
+
"geometry": {
|
|
35
|
+
"type": "Point",
|
|
36
|
+
"coordinates": [
|
|
37
|
+
-122.4194,
|
|
38
|
+
37.7749
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"properties": {
|
|
42
|
+
"name": "San Francisco",
|
|
43
|
+
"type": "city"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"type": "Feature",
|
|
48
|
+
"geometry": {
|
|
49
|
+
"type": "Point",
|
|
50
|
+
"coordinates": [
|
|
51
|
+
-118.2437,
|
|
52
|
+
34.0522
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"properties": {
|
|
56
|
+
"name": "Los Angeles",
|
|
57
|
+
"type": "city"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "Feature",
|
|
62
|
+
"geometry": {
|
|
63
|
+
"type": "Point",
|
|
64
|
+
"coordinates": [
|
|
65
|
+
-74.006,
|
|
66
|
+
40.7128
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
"properties": {
|
|
70
|
+
"name": "New York",
|
|
71
|
+
"type": "city"
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"type": "Feature",
|
|
76
|
+
"geometry": {
|
|
77
|
+
"type": "LineString",
|
|
78
|
+
"coordinates": [
|
|
79
|
+
[
|
|
80
|
+
-122.3493,
|
|
81
|
+
47.6205
|
|
82
|
+
],
|
|
83
|
+
[
|
|
84
|
+
-122.6784,
|
|
85
|
+
45.5152
|
|
86
|
+
],
|
|
87
|
+
[
|
|
88
|
+
-122.4194,
|
|
89
|
+
37.7749
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
-118.2437,
|
|
93
|
+
34.0522
|
|
94
|
+
]
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
"properties": {
|
|
98
|
+
"name": "West Coast Route",
|
|
99
|
+
"mode": "driving"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"type": "Feature",
|
|
104
|
+
"geometry": {
|
|
105
|
+
"type": "Point",
|
|
106
|
+
"coordinates": [
|
|
107
|
+
2.3522,
|
|
108
|
+
48.8566
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
"properties": {}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"type": "Feature",
|
|
115
|
+
"geometry": {
|
|
116
|
+
"type": "Point",
|
|
117
|
+
"coordinates": [
|
|
118
|
+
-0.1278,
|
|
119
|
+
51.5074
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"properties": {}
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"type": "Feature",
|
|
126
|
+
"geometry": {
|
|
127
|
+
"type": "Polygon",
|
|
128
|
+
"coordinates": [
|
|
129
|
+
[
|
|
130
|
+
[
|
|
131
|
+
-123.0,
|
|
132
|
+
48.0
|
|
133
|
+
],
|
|
134
|
+
[
|
|
135
|
+
-121.0,
|
|
136
|
+
48.0
|
|
137
|
+
],
|
|
138
|
+
[
|
|
139
|
+
-121.0,
|
|
140
|
+
46.0
|
|
141
|
+
],
|
|
142
|
+
[
|
|
143
|
+
-123.0,
|
|
144
|
+
46.0
|
|
145
|
+
],
|
|
146
|
+
[
|
|
147
|
+
-123.0,
|
|
148
|
+
48.0
|
|
149
|
+
]
|
|
150
|
+
]
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
"properties": {
|
|
154
|
+
"name": "Pacific NW",
|
|
155
|
+
"region": true
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"type": "Feature",
|
|
160
|
+
"geometry": {
|
|
161
|
+
"type": "Polygon",
|
|
162
|
+
"coordinates": [
|
|
163
|
+
[
|
|
164
|
+
[
|
|
165
|
+
-122.3493,
|
|
166
|
+
47.710441151017214
|
|
167
|
+
],
|
|
168
|
+
[
|
|
169
|
+
-122.32330338127136,
|
|
170
|
+
47.708710028492575
|
|
171
|
+
],
|
|
172
|
+
[
|
|
173
|
+
-122.29831079292721,
|
|
174
|
+
47.70358352014371
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
-122.27528691572327,
|
|
178
|
+
47.69525958316883
|
|
179
|
+
],
|
|
180
|
+
[
|
|
181
|
+
-122.25511936150583,
|
|
182
|
+
47.684059519927274
|
|
183
|
+
],
|
|
184
|
+
[
|
|
185
|
+
-122.23858413342101,
|
|
186
|
+
47.67041541322468
|
|
187
|
+
],
|
|
188
|
+
[
|
|
189
|
+
-122.22631565848305,
|
|
190
|
+
47.654853266080394
|
|
191
|
+
],
|
|
192
|
+
[
|
|
193
|
+
-122.21878256554382,
|
|
194
|
+
47.63797253321124
|
|
195
|
+
],
|
|
196
|
+
[
|
|
197
|
+
-122.21627011382594,
|
|
198
|
+
47.62042286978415
|
|
199
|
+
],
|
|
200
|
+
[
|
|
201
|
+
-122.21886987894307,
|
|
202
|
+
47.602879023582524
|
|
203
|
+
],
|
|
204
|
+
[
|
|
205
|
+
-122.2264769927538,
|
|
206
|
+
47.586014856783315
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
-122.23879492708923,
|
|
210
|
+
47.57047750255195
|
|
211
|
+
],
|
|
212
|
+
[
|
|
213
|
+
-122.25534752329217,
|
|
214
|
+
47.5568626411414
|
|
215
|
+
],
|
|
216
|
+
[
|
|
217
|
+
-122.27549771006404,
|
|
218
|
+
47.54569182325386
|
|
219
|
+
],
|
|
220
|
+
[
|
|
221
|
+
-122.2984721281491,
|
|
222
|
+
47.53739267934147
|
|
223
|
+
],
|
|
224
|
+
[
|
|
225
|
+
-122.32339069534318,
|
|
226
|
+
47.532282737212164
|
|
227
|
+
],
|
|
228
|
+
[
|
|
229
|
+
-122.3493,
|
|
230
|
+
47.53055743197494
|
|
231
|
+
],
|
|
232
|
+
[
|
|
233
|
+
-122.37520930465682,
|
|
234
|
+
47.532282737212164
|
|
235
|
+
],
|
|
236
|
+
[
|
|
237
|
+
-122.4001278718509,
|
|
238
|
+
47.53739267934147
|
|
239
|
+
],
|
|
240
|
+
[
|
|
241
|
+
-122.42310228993595,
|
|
242
|
+
47.54569182325386
|
|
243
|
+
],
|
|
244
|
+
[
|
|
245
|
+
-122.44325247670783,
|
|
246
|
+
47.55686264114141
|
|
247
|
+
],
|
|
248
|
+
[
|
|
249
|
+
-122.45980507291077,
|
|
250
|
+
47.57047750255195
|
|
251
|
+
],
|
|
252
|
+
[
|
|
253
|
+
-122.4721230072462,
|
|
254
|
+
47.58601485678331
|
|
255
|
+
],
|
|
256
|
+
[
|
|
257
|
+
-122.47973012105693,
|
|
258
|
+
47.60287902358252
|
|
259
|
+
],
|
|
260
|
+
[
|
|
261
|
+
-122.48232988617406,
|
|
262
|
+
47.62042286978415
|
|
263
|
+
],
|
|
264
|
+
[
|
|
265
|
+
-122.47981743445618,
|
|
266
|
+
47.63797253321123
|
|
267
|
+
],
|
|
268
|
+
[
|
|
269
|
+
-122.47228434151695,
|
|
270
|
+
47.6548532660804
|
|
271
|
+
],
|
|
272
|
+
[
|
|
273
|
+
-122.46001586657898,
|
|
274
|
+
47.670415413224674
|
|
275
|
+
],
|
|
276
|
+
[
|
|
277
|
+
-122.44348063849417,
|
|
278
|
+
47.684059519927274
|
|
279
|
+
],
|
|
280
|
+
[
|
|
281
|
+
-122.42331308427673,
|
|
282
|
+
47.69525958316883
|
|
283
|
+
],
|
|
284
|
+
[
|
|
285
|
+
-122.40028920707279,
|
|
286
|
+
47.70358352014371
|
|
287
|
+
],
|
|
288
|
+
[
|
|
289
|
+
-122.37529661872864,
|
|
290
|
+
47.708710028492575
|
|
291
|
+
],
|
|
292
|
+
[
|
|
293
|
+
-122.3493,
|
|
294
|
+
47.710441151017214
|
|
295
|
+
]
|
|
296
|
+
]
|
|
297
|
+
]
|
|
298
|
+
},
|
|
299
|
+
"properties": {
|
|
300
|
+
"name": "Seattle Metro",
|
|
301
|
+
"radius_km": 10
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
]
|
|
305
|
+
}
|
data/lib/geodetic/geojson.rb
CHANGED
|
@@ -101,6 +101,8 @@ module Geodetic
|
|
|
101
101
|
# ---------------------------------------------------------------
|
|
102
102
|
|
|
103
103
|
class << self
|
|
104
|
+
# --- Export helpers ---
|
|
105
|
+
|
|
104
106
|
def position(lla)
|
|
105
107
|
if lla.alt != 0.0
|
|
106
108
|
[lla.lng, lla.lat, lla.alt]
|
|
@@ -120,6 +122,93 @@ module Geodetic
|
|
|
120
122
|
def polygon_hash(rings)
|
|
121
123
|
{ "type" => "Polygon", "coordinates" => rings.map { |ring| ring.map { |p| position(p) } } }
|
|
122
124
|
end
|
|
125
|
+
|
|
126
|
+
# --- Import ---
|
|
127
|
+
|
|
128
|
+
def load(path)
|
|
129
|
+
data = JSON.parse(File.read(path))
|
|
130
|
+
parse(data)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def parse(data)
|
|
134
|
+
case data["type"]
|
|
135
|
+
when "FeatureCollection"
|
|
136
|
+
data["features"].flat_map { |f| parse(f) }
|
|
137
|
+
when "Feature"
|
|
138
|
+
parse_feature(data)
|
|
139
|
+
when "GeometryCollection"
|
|
140
|
+
data["geometries"].flat_map { |g| parse_geometry(g) }
|
|
141
|
+
else
|
|
142
|
+
[parse_geometry(data)]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def parse_feature(data)
|
|
149
|
+
geometry = parse_geometry(data["geometry"])
|
|
150
|
+
properties = data["properties"] || {}
|
|
151
|
+
|
|
152
|
+
results = geometry.is_a?(Array) ? geometry : [geometry]
|
|
153
|
+
|
|
154
|
+
results.map do |geom|
|
|
155
|
+
name = properties["name"]
|
|
156
|
+
metadata = properties.reject { |k, _| k == "name" }
|
|
157
|
+
|
|
158
|
+
if name || !metadata.empty?
|
|
159
|
+
Feature.new(
|
|
160
|
+
label: name,
|
|
161
|
+
geometry: geom,
|
|
162
|
+
metadata: metadata.transform_keys(&:to_sym)
|
|
163
|
+
)
|
|
164
|
+
else
|
|
165
|
+
geom
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def parse_geometry(data)
|
|
171
|
+
case data["type"]
|
|
172
|
+
when "Point"
|
|
173
|
+
parse_point(data["coordinates"])
|
|
174
|
+
when "LineString"
|
|
175
|
+
parse_line_string(data["coordinates"])
|
|
176
|
+
when "Polygon"
|
|
177
|
+
parse_polygon(data["coordinates"])
|
|
178
|
+
when "MultiPoint"
|
|
179
|
+
data["coordinates"].map { |pos| parse_point(pos) }
|
|
180
|
+
when "MultiLineString"
|
|
181
|
+
data["coordinates"].map { |coords| parse_line_string(coords) }
|
|
182
|
+
when "MultiPolygon"
|
|
183
|
+
data["coordinates"].map { |rings| parse_polygon(rings) }
|
|
184
|
+
when "GeometryCollection"
|
|
185
|
+
data["geometries"].flat_map { |g| parse_geometry(g) }
|
|
186
|
+
else
|
|
187
|
+
raise ArgumentError, "unknown GeoJSON geometry type: #{data["type"]}"
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def parse_point(coords)
|
|
192
|
+
lng, lat = coords[0], coords[1]
|
|
193
|
+
alt = coords[2] || 0.0
|
|
194
|
+
Coordinate::LLA.new(lat: lat, lng: lng, alt: alt)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def parse_line_string(coords)
|
|
198
|
+
points = coords.map { |pos| parse_point(pos) }
|
|
199
|
+
if points.length == 2
|
|
200
|
+
Segment.new(points[0], points[1])
|
|
201
|
+
else
|
|
202
|
+
Path.new(coordinates: points)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def parse_polygon(rings)
|
|
207
|
+
outer = rings[0].map { |pos| parse_point(pos) }
|
|
208
|
+
# Remove closing point if it duplicates the first (Polygon#initialize adds it)
|
|
209
|
+
outer.pop if outer.length > 1 && outer.first == outer.last
|
|
210
|
+
Areas::Polygon.new(boundary: outer)
|
|
211
|
+
end
|
|
123
212
|
end
|
|
124
213
|
|
|
125
214
|
# ---------------------------------------------------------------
|
data/lib/geodetic/version.rb
CHANGED
data/mkdocs.yml
CHANGED
|
@@ -132,6 +132,13 @@ nav:
|
|
|
132
132
|
- UPS: coordinate-systems/ups.md
|
|
133
133
|
- State Plane: coordinate-systems/state-plane.md
|
|
134
134
|
- BNG: coordinate-systems/bng.md
|
|
135
|
+
- GH36: coordinate-systems/gh36.md
|
|
136
|
+
- GH: coordinate-systems/gh.md
|
|
137
|
+
- HAM: coordinate-systems/ham.md
|
|
138
|
+
- OLC: coordinate-systems/olc.md
|
|
139
|
+
- GEOREF: coordinate-systems/georef.md
|
|
140
|
+
- GARS: coordinate-systems/gars.md
|
|
141
|
+
- H3: coordinate-systems/h3.md
|
|
135
142
|
- Reference:
|
|
136
143
|
- Datums: reference/datums.md
|
|
137
144
|
- Geoid Height: reference/geoid-height.md
|
|
@@ -141,4 +148,7 @@ nav:
|
|
|
141
148
|
- Feature: reference/feature.md
|
|
142
149
|
- Serialization: reference/serialization.md
|
|
143
150
|
- Conversions: reference/conversions.md
|
|
151
|
+
- Vector: reference/vector.md
|
|
152
|
+
- Arithmetic: reference/arithmetic.md
|
|
153
|
+
- GeoJSON Export: reference/geojson.md
|
|
144
154
|
- Map Rendering: reference/map-rendering.md
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: geodetic
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -79,6 +79,7 @@ files:
|
|
|
79
79
|
- examples/08_geodetic_arithmetic.rb
|
|
80
80
|
- examples/09_geojson_export.rb
|
|
81
81
|
- examples/README.md
|
|
82
|
+
- examples/geodetic_demo.geojson
|
|
82
83
|
- fiddle_pointer_buffer_pool.md
|
|
83
84
|
- lib/geodetic.rb
|
|
84
85
|
- lib/geodetic/areas.rb
|