@konfirm/geojson 1.0.1 → 2.0.0-beta.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.
package/README.md CHANGED
@@ -3,7 +3,108 @@
3
3
 
4
4
  # @konfirm/geojson
5
5
 
6
- GeoJSON validation, iteration, intersection and distance calculation.
6
+ GeoJSON is a standard format for encoding geographic data structures — points, lines, polygons as JSON. It was formalized in [RFC 7946](https://www.rfc-editor.org/rfc/rfc7946) in 2016, which introduced requirements (like winding order for polygon rings) that many tools still don't enforce.
7
+ > This TypeScript-first library gives you strict RFC 7946 validation and relaxed structural checks — so you can choose the right level of correctness for your data — along with geodesic distance across four formulas, intersection testing, and geometry iteration.
8
+
9
+ ## Installation and usage
10
+
11
+ ```sh
12
+ npm install @konfirm/geojson
13
+ ```
14
+
15
+ ```ts
16
+ import { isGeoJSON, isStrictGeoJSON, distance, karney } from '@konfirm/geojson';
17
+ ```
18
+
19
+ ## What @konfirm/geojson offers
20
+
21
+ **Types.** All RFC 7946 GeoJSON types (`Point`, `LineString`, `Polygon`, their `Multi*` variants, `GeometryCollection`, `Feature`, `FeatureCollection`) are exported as TypeScript types. `Feature<G>`, `FeatureCollection<G>`, and `GeometryCollection<G>` are generic so you can narrow the geometry type at compile time.
22
+
23
+ **Validation.** Every type has two guards: `is*` checks structure (is this a valid GeoJSON object at all?), and `isStrict*` also checks coordinate ranges and RFC 7946 (§3.1.6) winding order. You pick the tier; you can use both in the same codebase.
24
+
25
+ ```ts
26
+ import { isGeoJSON, isStrictGeoJSON } from '@konfirm/geojson';
27
+
28
+ isGeoJSON(value) // structural check — coordinates in bounds? irrelevant.
29
+ isStrictGeoJSON(value) // also checks ranges and CCW/CW winding per RFC 7946
30
+ ```
31
+
32
+ **Distance.** Geodesic distance between any two GeoJSON objects (not just points) across four formulas. `haversine` covers most use cases. `karney` always converges.
33
+
34
+ **Intersection.** Boolean intersection test across all geometry type combinations (`Point`, `LineString`, `Polygon` and their `Multi*` and `Feature`/`FeatureCollection` wrappers).
35
+
36
+ **Iteration.** `SimpleGeometryIterator` flattens any GeoJSON — including nested `GeometryCollection` and `FeatureCollection` — into a sequence of simple `Point`, `LineString`, and `Polygon` geometries.
37
+
38
+ ## Upgrading to v2?
39
+
40
+ **What's new:**
41
+ - `karney` — fourth distance formula; always converges, ~15 nm accuracy on WGS84, including near-antipodal inputs
42
+ - Generic `Feature<G>`, `FeatureCollection<G>`, `GeometryCollection<G>` — narrow the geometry type at compile time by passing a guard: `isFeature(value, isPoint)` → `value is Feature<Point>`
43
+ - Named formula exports — `cartesian`, `haversine`, `vincenty`, `karney` as standalone `(GeoJSON, GeoJSON) => number` functions for direct use and tree-shaking
44
+ - RFC 7946 winding enforcement in `isStrictPolygon` and `isStrictMultiPolygon` — was silently skipped in v1
45
+
46
+ Five breaking changes. Quick fixes below; the [full migration guide](./MIGRATION.md) has the details.
47
+
48
+ | Change | v1 | v2 | Quick fix |
49
+ |--------|----|----|-----------|
50
+ | `distance()` default | `'cartesian'` | `'haversine'` | Pass `'cartesian'` explicitly, or `import { cartesian as distance }` |
51
+ | `isStrictPolygon` winding | not enforced | RFC 7946 §3.1.6 (CCW exterior, CW interior) | Use `isPolygon` for loose validation |
52
+ | `vincenty` near-antipodal | silent wrong result | throws `EvalError` | Catch the error, or switch to `'karney'` |
53
+ | `Geometry` / `isGeometry` | excluded `GeometryCollection` | includes `GeometryCollection` | Use `isGeometryPrimitive` if you need the six coordinate-bearing types only |
54
+ | `Feature.geometry` type | `Geometry \| GeometryCollection` (null never typed) | `Geometry \| null` (matches runtime) | Add null checks where `geometry` was assumed non-null; `isFeature(v, isGeometry)` narrows to non-null |
55
+
56
+ On the winding: `isStrictPolygon` didn't check the one thing [RFC 7946](https://www.rfc-editor.org/rfc/rfc7946#section-3.1.6) says polygons MUST do — the winding. Counterclockwise for the outer ring, and clockwise for the inner rings (holes). To top it off, if it had checked, it would have been wrong anyway. Wrong formula, wrong data backing it up. That's on me — [read more on what happened, why I didn't notice, and what was done to prevent it](./docs/adr-winding-and-test-data.md).
57
+
58
+ **The most likely change you need to make** is the `distance()` default. If you had:
59
+
60
+ ```ts
61
+ import { distance } from '@konfirm/geojson';
62
+ distance(pointA, polygonB);
63
+ ```
64
+
65
+ you are getting a better answer now. Don't want that? Pick your fix:
66
+
67
+ ```ts
68
+ // explicit at the call site
69
+ distance(pointA, polygonB, 'cartesian');
70
+
71
+ // or: import the formula directly — zero call-site changes
72
+ import { cartesian as distance } from '@konfirm/geojson';
73
+ distance(pointA, polygonB);
74
+ ```
75
+
76
+ Either way, [ask yourself whether `cartesian` is actually what you want](./MIGRATION.md#1-distance-default-formula-changed-from-cartesian-to-haversine) — for real-world coordinates it can be off by more than 50%.
77
+
78
+ ## Why this over...?
79
+
80
+ The one thing most GeoJSON validators skip is winding order. [RFC 7946 §3.1.6](https://www.rfc-editor.org/rfc/rfc7946#section-3.1.6) says polygon exterior rings **must** be counterclockwise and interior rings (holes) clockwise — but virtually no public library enforces this. `isStrictPolygon` is one of the very few that does.
81
+
82
+ This has a concrete consequence: [Natural Earth](https://www.naturalearthdata.com/), the de-facto standard country dataset, [uses the opposite convention](https://github.com/nvkelso/natural-earth-vector/issues/885) and fails strict validation. That is a feature, not a bug — `isPolygon` accepts it, `isStrictPolygon` rejects it. The split lets you choose strictness without switching libraries.
83
+
84
+ | | this | @types/geojson | geojson-validation | @mapbox/geojsonhint | @mapbox/geojson-rewind | @turf/turf |
85
+ |---|:-:|:-:|:-:|:-:|:-:|:-:|
86
+ | TypeScript types | ✓ | ✓ | — | — | — | ✓ |
87
+ | Structural (loose) validation | ✓ | — | ✓ | ✓ | — | — |
88
+ | Strict validation (ranges + winding) | ✓ | — | — | — | — | — |
89
+ | Validation failure reasons | — | — | ✓ | ✓ | — | — |
90
+ | RFC 7946 winding enforcement | ✓ | — | — | — | — | — |
91
+ | Winding correction | — | — | — | — | ✓¹ | — |
92
+ | Intersection testing | ✓ | — | — | — | — | ✓ |
93
+ | Haversine distance | ✓ | — | — | — | — | ✓ |
94
+ | Vincenty distance | ✓ | — | — | — | — | — |
95
+ | Karney distance (always converges, ~15 nm) | ✓ | — | — | — | — | — |
96
+ | Spatial ops (buffer, union, simplify, …) | — | — | — | — | — | ✓ |
97
+ | CLI | — | — | ✓ | ✓ | ✓ | — |
98
+ | Zero runtime dependencies | ✓ | ✓ | ✓ | — | — | — |
99
+ | Active maintenance | ✓ | ✓ | — | ✓ | ✓ | ✓ |
100
+
101
+ ¹ `@mapbox/geojson-rewind` defaults to clockwise exterior — the pre-RFC 7946 convention. To match RFC 7946 you must pass `rewind(geojson, false)` explicitly.
102
+
103
+ **When you should use something else instead:**
104
+
105
+ - Need spatial operations — buffer, union, difference, simplify, Voronoi, clustering? Use [Turf](https://turfjs.org/). It is a far broader library and this package does not compete with it.
106
+ - Need to know *why* a value failed — which ring, which coordinate, which rule? [`geojson-validation`](https://www.npmjs.com/package/geojson-validation) and [`@mapbox/geojsonhint`](https://www.npmjs.com/package/@mapbox/geojsonhint) return error strings; this package returns `boolean`.
107
+ - Need a CLI to lint GeoJSON files? Neither does this package; `geojsonhint` is the right tool for that.
7
108
 
8
109
  ## API
9
110
 
@@ -20,20 +121,22 @@ All [GeoJSON types](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1) a
20
121
  | MultiLineString | A [GeoJSON MultiLineString](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.5) | The `coordinates` property is an array of`LineString` coordinates |
21
122
  | Polygon | A [GeoJSON Polygon](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6) | The `coordinates` property is an array of "LinearRings" (closed `LineString` coordinates, where the first and last `Position` are identical) |
22
123
  | MultiPolygon | A [GeoJSON MultiPolygon](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.7) | The `coordinates` property is an array of `Polygon` coordinate arrays |
23
- | GeometryCollection | A [GeoJSON GeometryCollection](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.8) | geometries is an array of Geometries (`Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`) |
24
- | Feature | A [GeoJSON Feature](https://datatracker.ietf.org/doc/html/rfc7946#section-3.2) | A spatially bounded 'Thing', consisting of a `geometry` property (`Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `GeometryCollection`) with additional `properties` |
25
- | FeatureCollection | A [GeoJSON Collection](https://datatracker.ietf.org/doc/html/rfc7946#section-3.3) | The `features` property is an array of `Feature` objects |
124
+ | GeometryCollection | A [GeoJSON GeometryCollection](https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.8) | `geometries` is an array of Geometries (`Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`). Generic: `GeometryCollection<G extends Geometry>` |
125
+ | Feature | A [GeoJSON Feature](https://datatracker.ietf.org/doc/html/rfc7946#section-3.2) | A spatially bounded thing with a `geometry` (`Geometry \| null`) and `properties`. Generic: `Feature<G extends Geometry \| null>` |
126
+ | FeatureCollection | A [GeoJSON Collection](https://datatracker.ietf.org/doc/html/rfc7946#section-3.3) | The `features` property is an array of `Feature` objects. Generic: `FeatureCollection<G extends Geometry \| null>` |
127
+ | Geometry | — (union type) | Union of all geometry types including `GeometryCollection`. Use `GeometryPrimitive` when you need only the six coordinate-bearing types. |
128
+ | GeometryPrimitive | — (union type) | The six coordinate-bearing geometry types: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`. Excludes `GeometryCollection`. |
26
129
 
27
130
 
28
131
  ### Type Guards
29
132
 
30
- Most of the exported functionality is based on validation of GeoJSON objects, validating required and optional (if provided) properties.
133
+ Most of the exported functionality is based on validation of GeoJSON objects, validating required and optional (if provided) properties.
31
134
  The `isStrict*` variants of the type guards also validate the following:
32
135
  - `Longitude` is a number in the range (inclusive) `-180..180`
33
136
  - `Latitude` is a number in the range (inclusive) `-90..90`
34
137
  - `Altitude` is a number in the range (inclusive) `-6371008.7714..20180000` (Earth center(-ish) up to the GPS satelite distance)
35
138
  - `Polygon` "LinearRing" are closed (first and last `Position` are identical)
36
- - ~~`Polygon` "LinearRing" have the correct winding (counterclockwise for exterior rings (outline), clockwise for interior rings (holes))~~ _(not yet enforced — planned for v2)_
139
+ - `Polygon` "LinearRing" have the correct winding per RFC 7946 (§3.1.6): counterclockwise for exterior rings, clockwise for interior rings (holes)
37
140
 
38
141
 
39
142
  | type | guard | strict guard | description |
@@ -46,7 +149,8 @@ The `isStrict*` variants of the type guards also validate the following:
46
149
  | Polygon | `isPolygon` | `isStrictPolygon` | validate whether the input is valid GeoJSON Polygon |
47
150
  | MultiPolygon | `isMultiPolygon` | `isStrictMultiPolygon` | validate whether the input is valid GeoJSON MultiPolygon |
48
151
  | GeometryCollection | `isGeometryCollection` | `isStrictGeometryCollection` | validate whether the input is valid GeoJSON GeometryCollection |
49
- | Geometry | `isGeometry` | `isStrictGeometry` | validate whether the input is valid GeoJSON Geometry (`Point`, `LineString`, `Polygon` or their `Multi*` variants) |
152
+ | Geometry | `isGeometry` | `isStrictGeometry` | validate whether the input is any valid GeoJSON Geometry, including `GeometryCollection` |
153
+ | GeometryPrimitive | `isGeometryPrimitive` | `isStrictGeometryPrimitive` | validate whether the input is one of the six coordinate-bearing geometry types (excludes `GeometryCollection`) |
50
154
  | Feature | `isFeature` | `isStrictFeature` | validate whether the input is valid GeoJSON Feature |
51
155
  | FeatureCollection | `isFeatureCollection` | `isStrictFeatureCollection` | validate whether the input is valid GeoJSON FeatureCollection |
52
156
  | GeoJSON | `isGeoJSON` | `isStrictGeoJSON` | validate the input to be valid GeoJSON |
@@ -63,6 +167,30 @@ console.log('the point is a GeoJSON Point', isPoint(point)); // true, as the str
63
167
  console.log('the point is a strict GeoJSON Point', isStrictPoint(point)); // false, as the coordinates are not within the specified ranges
64
168
  ```
65
169
 
170
+ #### Generics and narrowing
171
+
172
+ `Feature<G>`, `FeatureCollection<G>`, and `GeometryCollection<G>` are generic. The corresponding guards accept an optional second argument — a geometry guard — to narrow the inferred type:
173
+
174
+ ```ts
175
+ import { isFeature, isFeatureCollection, isGeometryCollection, isPoint, isStrictPoint } from '@konfirm/geojson';
176
+
177
+ // Without a guard: value is Feature<Geometry | null>
178
+ isFeature(value);
179
+
180
+ // With a guard: value is Feature<Point>
181
+ isFeature(value, isPoint);
182
+
183
+ // Works with strict guards and custom guards too
184
+ isFeature(value, isStrictPoint); // value is Feature<Point> (strict coordinates)
185
+ isFeatureCollection(value, isPoint); // value is FeatureCollection<Point>
186
+ isGeometryCollection(value, isPoint); // value is GeometryCollection<Point>
187
+
188
+ // The strict variants of the three guards accept the same optional narrowing argument
189
+ isStrictFeature(value, isStrictPoint); // value is Feature<Point>
190
+ isStrictFeatureCollection(value, isStrictPoint); // value is FeatureCollection<Point>
191
+ isStrictGeometryCollection(value, isStrictPoint); // value is GeometryCollection<Point>
192
+ ```
193
+
66
194
  ### intersect
67
195
 
68
196
  Verify whether the provided GeoJSON objects intersect.
@@ -93,47 +221,70 @@ console.log('feature intersects point', intersect(feature, point)); // true
93
221
 
94
222
  ### distance
95
223
 
96
- Obtain the (shortest) distance in meters between two GeoJSON objects. There are three formulas which can be used:
224
+ Obtain the (shortest) distance in meters between two GeoJSON objects. Choose a formula based on your use case:
97
225
 
98
- - `cartesian` (default), calculates the distance between coordinates using the Pythagorean equation, this is the fastest formula at the cost of (huge amount of) accuracy
99
- - `haversine`, calculates the distance between coordinates using the [haversine formula](https://en.wikipedia.org/wiki/Haversine_formula), improves the accuracy to a level which is probably suitable for most needs with a decent performance
100
- - `vincenty`, calculates the distance between coordinates using the [Vincenty's formula](https://en.wikipedia.org/wiki/Vincenty%27s_formulae), the most accurate but the least performant algorithm.
226
+ - `haversine` (**default**) geographic lon/lat coordinates, most use cases; good accuracy, good performance
227
+ - `vincenty` when you need higher accuracy than haversine and can guarantee inputs are not near-antipodal points on nearly opposite sides of the Earth (throws for those)
228
+ - `karney` when correctness is unconditional: near-antipodal inputs, or when you simply cannot afford a wrong answer; ~15 nm accuracy on WGS84
229
+ - `cartesian` — when coordinates are in a metric projected system (e.g. RD New / EPSG:28992, UTM) where Euclidean distance is correct; note that projected coordinates are not valid strict GeoJSON (RFC 7946 requires geographic lon/lat, WGS84) — **do not use for geographic coordinates**
101
230
 
102
- Usage: `distance(<Geometry(Collection)|Feature(Collection)>, <Geometry(Collection)|Feature(Collection)> [, <'cartesian'|'haversine'|'vincenty'>]): number`
231
+ Each formula is also exported as a standalone function for direct use and better tree-shaking.
232
+
233
+ The formula argument accepts either a string or a custom `(a: Position, b: Position) => number` function — useful when you need a projection-specific calculation or want to plug in your own formula. The `PointToPointCalculation` type covers both and is exported for use in typed wrapper functions.
234
+
235
+ Usage: `distance(<GeoJSON>, <GeoJSON> [, <PointToPointCalculation>]): number`
103
236
 
104
237
  ```ts
105
- import { distance, Feature } from '@konfirm/geojson';
238
+ import { distance, karney, Feature } from '@konfirm/geojson';
106
239
 
107
- const a: Feature = {
108
- type: 'Feature',
109
- properties: {
110
- name: 'Schiphol Airport, Amsterdam',
111
- },
112
- geometry: {
113
- type: 'Point',
114
- coordinates: [4.763889, 52.308333],
115
- },
116
- };
117
- const b: Feature = {
118
- type: 'Feature',
119
- properties: {
120
- name: 'John F. Kennedy International Airport, New York',
121
- },
122
- geometry: {
123
- type: 'Point',
124
- coordinates: [-73.778889, 40.639722],
125
- },
126
- };
240
+ const a: Feature = {
241
+ type: 'Feature',
242
+ properties: { name: 'Schiphol Airport, Amsterdam' },
243
+ geometry: { type: 'Point', coordinates: [4.763889, 52.308333] },
244
+ };
245
+ const b: Feature = {
246
+ type: 'Feature',
247
+ properties: { name: 'John F. Kennedy International Airport, New York' },
248
+ geometry: { type: 'Point', coordinates: [-73.778889, 40.639722] },
249
+ };
127
250
 
128
- console.log(distance(a, b)); // 8829424.604594177 ('cartesian' is the default)
129
- console.log(distance(a, b, 'cartesian')); // 8829424.604594177
130
- console.log(distance(a, b, 'haversine')); // 5847546.425707642
131
- console.log(distance(a, b, 'vincenty')); // 5863355.371234315
251
+ console.log(distance(a, b)); // 5847546.425707642 ('haversine' is the default)
252
+ console.log(distance(a, b, 'haversine')); // 5847546.425707642
253
+ console.log(distance(a, b, 'vincenty')); // 5863355.371234315
254
+ console.log(distance(a, b, 'karney')); // 5863355.371221913
255
+ console.log(distance(a, b, 'cartesian')); // 8829424.604594177
256
+
257
+ console.log(karney(a, b)); // 5863355.371221913 — same as distance(a, b, 'karney')
132
258
  ```
133
259
 
260
+ #### Accuracy versus performance
261
+
262
+ This library's karney implementation matches Karney's own GeographicLib C++ reference within 1 nm on average and 11 nm at worst, across 500,000 test cases — close enough to use as the accuracy benchmark below.
263
+ A result is counted as **wrong** when it deviates from the benchmark by more than 10.0 m. Throws count as wrong too.
264
+
265
+ Performance: karney shows absolute µs/call on this machine; other formulas show speed relative to karney (~Nx = N times faster) — ratios are more portable across machines than absolute times.
266
+
267
+ | band | n | karney | vincenty | haversine | cartesian |
268
+ | --- | ---: | --- | --- | --- | --- |
269
+ | <1 m | 45 | none · 13.2 µs | none · ~23x | none · ~53x | **4.4% · ~86x** |
270
+ | <10 m | 375 | none · 1.87 µs | none · ~4x | none · ~12x | 14.4% · ~20x |
271
+ | <100 m | 3,980 | none · 1.84 µs | none · ~4x | none · ~12x | 42.9% · ~20x |
272
+ | <1 km | 40,523 | none · 2.00 µs | none · ~4x | none · ~13x | 73.0% · ~21x |
273
+ | <10 km | 5,125 | none · 2.18 µs | none · ~4x | **0.3% · ~14x** | 81.3% · ~22x |
274
+ | <25 km | 78 | none · 2.41 µs | none · ~4x | 96.2% · ~12x | 96.2% · ~20x |
275
+ | <50 km | 108 | none · 2.68 µs | none · ~4x | 97.2% · ~14x | 98.1% · ~23x |
276
+ | <100 km | 239 | none · 2.20 µs | none · ~4x | 99.6% · ~13x | 99.6% · ~24x |
277
+ | <1 000 km | 5,371 | none · 2.32 µs | none · ~4x | 99.9% · ~14x | 99.9% · ~25x |
278
+ | <10 000 km | 119,455 | none · 2.90 µs | none · ~4x | 100.0% · ~14x | 100.0% · ~30x |
279
+ | <15 000 km | 77,875 | none · 3.06 µs | **none · ~4x** | 100.0% · ~16x | 100.0% · ~31x |
280
+ | >15 000 km | 146,826 | none · 2.68 µs | 19.8% · ~4x | 100.0% · ~14x | 100.0% · ~27x |
281
+ | near-antipodal | 100,000 | none · 3.25 µs | 34.9% · ~1x | 99.9% · ~18x | 100.0% · ~31x |
282
+
283
+ Run your own numbers: `npm run compare:formulas -- --threshold <metres>` (current: 10 m)
284
+
134
285
  ### SimpleGeometryIterator
135
286
 
136
- The SimpleGeometryIterator class is a convenience helper utility which yields all simple Geometric shapes (`Point`, `LineString`, `Polygon`) from any GeoJSON object. Using a SimpleGeometryIterator allows you to focus on just implementing logic for the simple Geometric shapes whilst supporting any combination of GeoJSON objects as input.
287
+ The SimpleGeometryIterator class is a helper utility that flattens any GeoJSON input — including nested `FeatureCollection` and `GeometryCollection` — into a flat sequence of simple geometries (`Point`, `LineString`, `Polygon`). Multi-geometry types are split into their individual components. The original structure is never modified and no intermediate arrays are built.
137
288
 
138
289
  | input type | yields type(s) | description |
139
290
  | -------------------- | ---------------------------------- | ---------------------------------------------------------------------------------------- |
@@ -237,9 +388,13 @@ const simplified = [...new SimpleGeometryIterator(multipoint, geometrycollection
237
388
  */
238
389
  ```
239
390
 
391
+ ## Contributing
392
+
393
+ Contributions are welcome — see [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get started. To report a vulnerability, see [SECURITY.md](./SECURITY.md).
394
+
240
395
  ## License
241
396
 
242
- MIT License Copyright (c) 2021-2023 Rogier Spieker (Konfirm)
397
+ MIT License Copyright (c) 2021-2026 Rogier Spieker (Konfirm)
243
398
 
244
399
  Permission is hereby granted, free of charge, to any person obtaining a copy
245
400
  of this software and associated documentation files (the "Software"), to deal
@@ -257,4 +412,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
257
412
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
258
413
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
259
414
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
260
- SOFTWARE.
415
+ SOFTWARE.
package/dist/main.d.mts CHANGED
@@ -7,9 +7,9 @@ type Latitude = number;
7
7
 
8
8
  type Longitude = number;
9
9
 
10
- type Position = [Longitude, Latitude, Altitude?];
11
- declare const isPosition: _konfirm_guard.Guard<Position>;
12
- declare const isStrictPosition: _konfirm_guard.Guard<Position>;
10
+ type Position = [Longitude, Latitude, Altitude?, ...Array<unknown>];
11
+ declare const isPosition: _konfirm_guard.Guard<[number, number, (number | undefined)?, ...unknown[]]>;
12
+ declare const isStrictPosition: _konfirm_guard.Guard<[number, number, (number | undefined)?, ...unknown[]]>;
13
13
 
14
14
  type BoundingBox = [Longitude, Latitude, Altitude, Longitude, Latitude, Altitude] | [Longitude, Latitude, Longitude, Latitude];
15
15
 
@@ -68,33 +68,35 @@ type MultiPolygon = MultiGeometryObject<Polygon>;
68
68
  declare const isMultiPolygon: _konfirm_guard.Guard<MultiPolygon>;
69
69
  declare const isStrictMultiPolygon: _konfirm_guard.Guard<MultiPolygon>;
70
70
 
71
- type Geometry = Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon;
72
- declare const isGeometry: _konfirm_guard.Guard<Geometry>;
73
- declare const isStrictGeometry: _konfirm_guard.Guard<Geometry>;
74
-
75
- type GeometryCollection = GeoJSONObject<{
71
+ type GeometryPrimitive = Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon;
72
+ declare const isGeometryPrimitive: Guard<GeometryPrimitive>;
73
+ declare const isStrictGeometryPrimitive: Guard<GeometryPrimitive>;
74
+ type GeometryCollection<G extends GeometryPrimitive = GeometryPrimitive> = GeoJSONObject<{
76
75
  type: 'GeometryCollection';
77
- geometries: Array<Geometry | GeometryCollection>;
76
+ geometries: Array<G | GeometryCollection<G>>;
78
77
  }>;
79
- declare function isGeometryCollection(value: unknown): value is GeometryCollection;
80
- declare function isStrictGeometryCollection(value: unknown): value is GeometryCollection;
78
+ type Geometry = GeometryPrimitive | GeometryCollection;
79
+ declare const isGeometry: Guard<Geometry>;
80
+ declare const isStrictGeometry: Guard<Geometry>;
81
+ declare function isGeometryCollection<G extends GeometryPrimitive = GeometryPrimitive>(value: unknown, isG?: Guard<G>): value is GeometryCollection<G>;
82
+ declare function isStrictGeometryCollection<G extends GeometryPrimitive = GeometryPrimitive>(value: unknown, isG?: Guard<G>): value is GeometryCollection<G>;
81
83
 
82
- type Feature = GeoJSONObject<{
84
+ type Feature<G extends Geometry | null = Geometry | null> = GeoJSONObject<{
83
85
  type: 'Feature';
84
- geometry: Geometry | GeometryCollection;
86
+ geometry: G;
85
87
  properties: {
86
88
  [key: string]: unknown;
87
89
  } | null;
88
90
  }>;
89
- declare const isFeature: _konfirm_guard.Guard<Feature>;
90
- declare const isStrictFeature: _konfirm_guard.Guard<Feature>;
91
+ declare function isFeature<G extends Geometry | null>(input: unknown, isG?: Guard<G>): input is Feature<G>;
92
+ declare function isStrictFeature<G extends Geometry | null>(input: unknown, isG?: Guard<G>): input is Feature<G>;
91
93
 
92
- type FeatureCollection = GeoJSONObject<{
94
+ type FeatureCollection<G extends Geometry | null = Geometry | null> = GeoJSONObject<{
93
95
  type: 'FeatureCollection';
94
- features: Array<Feature>;
96
+ features: Array<Feature<G>>;
95
97
  }>;
96
- declare const isFeatureCollection: _konfirm_guard.Guard<FeatureCollection>;
97
- declare const isStrictFeatureCollection: _konfirm_guard.Guard<FeatureCollection>;
98
+ declare function isFeatureCollection<G extends Geometry | null>(value: unknown, isG?: Guard<G>): value is FeatureCollection<G>;
99
+ declare function isStrictFeatureCollection<G extends Geometry | null>(value: unknown, isG?: Guard<G>): value is FeatureCollection<G>;
98
100
 
99
101
  type GeoJSON = Geometry | GeometryCollection | Feature | FeatureCollection;
100
102
  declare const isGeoJSON: _konfirm_guard.Guard<GeoJSON>;
@@ -128,10 +130,14 @@ declare class SimpleGeometryIterator {
128
130
  private unwrap;
129
131
  }
130
132
 
131
- type PointToPointCalculation = 'cartesian' | 'haversine' | 'vincenty' | ((a: Point['coordinates'], b: Point['coordinates']) => number);
133
+ type PointToPointCalculation = 'cartesian' | 'haversine' | 'vincenty' | 'karney' | ((a: Point['coordinates'], b: Point['coordinates']) => number);
132
134
 
135
+ declare function cartesian(a: GeoJSON, b: GeoJSON): number;
136
+ declare function haversine(a: GeoJSON, b: GeoJSON): number;
137
+ declare function vincenty(a: GeoJSON, b: GeoJSON): number;
138
+ declare function karney(a: GeoJSON, b: GeoJSON): number;
133
139
  declare function distance(a: GeoJSON, b: GeoJSON, calculation?: PointToPointCalculation): number;
134
140
 
135
141
  declare function intersect(a: GeoJSON, b: GeoJSON): boolean;
136
142
 
137
- export { type Feature, type FeatureCollection, type GeoJSON, type Geometry, type GeometryCollection, type LineString, type MultiLineString, type MultiPoint, type MultiPolygon, type Point, type Polygon, type Position, SimpleGeometryIterator, distance, intersect, isFeature, isFeatureCollection, isGeoJSON, isGeometry, isGeometryCollection, isLineString, isMultiLineString, isMultiPoint, isMultiPolygon, isPoint, isPolygon, isPosition, isStrictFeature, isStrictFeatureCollection, isStrictGeoJSON, isStrictGeometry, isStrictGeometryCollection, isStrictLineString, isStrictMultiLineString, isStrictMultiPoint, isStrictMultiPolygon, isStrictPoint, isStrictPolygon, isStrictPosition };
143
+ export { type Feature, type FeatureCollection, type GeoJSON, type Geometry, type GeometryCollection, type GeometryPrimitive, type LineString, type MultiLineString, type MultiPoint, type MultiPolygon, type Point, type Polygon, type Position, SimpleGeometryIterator, cartesian, distance, haversine, intersect, isFeature, isFeatureCollection, isGeoJSON, isGeometry, isGeometryCollection, isGeometryPrimitive, isLineString, isMultiLineString, isMultiPoint, isMultiPolygon, isPoint, isPolygon, isPosition, isStrictFeature, isStrictFeatureCollection, isStrictGeoJSON, isStrictGeometry, isStrictGeometryCollection, isStrictGeometryPrimitive, isStrictLineString, isStrictMultiLineString, isStrictMultiPoint, isStrictMultiPolygon, isStrictPoint, isStrictPolygon, isStrictPosition, karney, vincenty };
package/dist/main.d.ts CHANGED
@@ -7,9 +7,9 @@ type Latitude = number;
7
7
 
8
8
  type Longitude = number;
9
9
 
10
- type Position = [Longitude, Latitude, Altitude?];
11
- declare const isPosition: _konfirm_guard.Guard<Position>;
12
- declare const isStrictPosition: _konfirm_guard.Guard<Position>;
10
+ type Position = [Longitude, Latitude, Altitude?, ...Array<unknown>];
11
+ declare const isPosition: _konfirm_guard.Guard<[number, number, (number | undefined)?, ...unknown[]]>;
12
+ declare const isStrictPosition: _konfirm_guard.Guard<[number, number, (number | undefined)?, ...unknown[]]>;
13
13
 
14
14
  type BoundingBox = [Longitude, Latitude, Altitude, Longitude, Latitude, Altitude] | [Longitude, Latitude, Longitude, Latitude];
15
15
 
@@ -68,33 +68,35 @@ type MultiPolygon = MultiGeometryObject<Polygon>;
68
68
  declare const isMultiPolygon: _konfirm_guard.Guard<MultiPolygon>;
69
69
  declare const isStrictMultiPolygon: _konfirm_guard.Guard<MultiPolygon>;
70
70
 
71
- type Geometry = Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon;
72
- declare const isGeometry: _konfirm_guard.Guard<Geometry>;
73
- declare const isStrictGeometry: _konfirm_guard.Guard<Geometry>;
74
-
75
- type GeometryCollection = GeoJSONObject<{
71
+ type GeometryPrimitive = Point | MultiPoint | LineString | MultiLineString | Polygon | MultiPolygon;
72
+ declare const isGeometryPrimitive: Guard<GeometryPrimitive>;
73
+ declare const isStrictGeometryPrimitive: Guard<GeometryPrimitive>;
74
+ type GeometryCollection<G extends GeometryPrimitive = GeometryPrimitive> = GeoJSONObject<{
76
75
  type: 'GeometryCollection';
77
- geometries: Array<Geometry | GeometryCollection>;
76
+ geometries: Array<G | GeometryCollection<G>>;
78
77
  }>;
79
- declare function isGeometryCollection(value: unknown): value is GeometryCollection;
80
- declare function isStrictGeometryCollection(value: unknown): value is GeometryCollection;
78
+ type Geometry = GeometryPrimitive | GeometryCollection;
79
+ declare const isGeometry: Guard<Geometry>;
80
+ declare const isStrictGeometry: Guard<Geometry>;
81
+ declare function isGeometryCollection<G extends GeometryPrimitive = GeometryPrimitive>(value: unknown, isG?: Guard<G>): value is GeometryCollection<G>;
82
+ declare function isStrictGeometryCollection<G extends GeometryPrimitive = GeometryPrimitive>(value: unknown, isG?: Guard<G>): value is GeometryCollection<G>;
81
83
 
82
- type Feature = GeoJSONObject<{
84
+ type Feature<G extends Geometry | null = Geometry | null> = GeoJSONObject<{
83
85
  type: 'Feature';
84
- geometry: Geometry | GeometryCollection;
86
+ geometry: G;
85
87
  properties: {
86
88
  [key: string]: unknown;
87
89
  } | null;
88
90
  }>;
89
- declare const isFeature: _konfirm_guard.Guard<Feature>;
90
- declare const isStrictFeature: _konfirm_guard.Guard<Feature>;
91
+ declare function isFeature<G extends Geometry | null>(input: unknown, isG?: Guard<G>): input is Feature<G>;
92
+ declare function isStrictFeature<G extends Geometry | null>(input: unknown, isG?: Guard<G>): input is Feature<G>;
91
93
 
92
- type FeatureCollection = GeoJSONObject<{
94
+ type FeatureCollection<G extends Geometry | null = Geometry | null> = GeoJSONObject<{
93
95
  type: 'FeatureCollection';
94
- features: Array<Feature>;
96
+ features: Array<Feature<G>>;
95
97
  }>;
96
- declare const isFeatureCollection: _konfirm_guard.Guard<FeatureCollection>;
97
- declare const isStrictFeatureCollection: _konfirm_guard.Guard<FeatureCollection>;
98
+ declare function isFeatureCollection<G extends Geometry | null>(value: unknown, isG?: Guard<G>): value is FeatureCollection<G>;
99
+ declare function isStrictFeatureCollection<G extends Geometry | null>(value: unknown, isG?: Guard<G>): value is FeatureCollection<G>;
98
100
 
99
101
  type GeoJSON = Geometry | GeometryCollection | Feature | FeatureCollection;
100
102
  declare const isGeoJSON: _konfirm_guard.Guard<GeoJSON>;
@@ -128,10 +130,14 @@ declare class SimpleGeometryIterator {
128
130
  private unwrap;
129
131
  }
130
132
 
131
- type PointToPointCalculation = 'cartesian' | 'haversine' | 'vincenty' | ((a: Point['coordinates'], b: Point['coordinates']) => number);
133
+ type PointToPointCalculation = 'cartesian' | 'haversine' | 'vincenty' | 'karney' | ((a: Point['coordinates'], b: Point['coordinates']) => number);
132
134
 
135
+ declare function cartesian(a: GeoJSON, b: GeoJSON): number;
136
+ declare function haversine(a: GeoJSON, b: GeoJSON): number;
137
+ declare function vincenty(a: GeoJSON, b: GeoJSON): number;
138
+ declare function karney(a: GeoJSON, b: GeoJSON): number;
133
139
  declare function distance(a: GeoJSON, b: GeoJSON, calculation?: PointToPointCalculation): number;
134
140
 
135
141
  declare function intersect(a: GeoJSON, b: GeoJSON): boolean;
136
142
 
137
- export { type Feature, type FeatureCollection, type GeoJSON, type Geometry, type GeometryCollection, type LineString, type MultiLineString, type MultiPoint, type MultiPolygon, type Point, type Polygon, type Position, SimpleGeometryIterator, distance, intersect, isFeature, isFeatureCollection, isGeoJSON, isGeometry, isGeometryCollection, isLineString, isMultiLineString, isMultiPoint, isMultiPolygon, isPoint, isPolygon, isPosition, isStrictFeature, isStrictFeatureCollection, isStrictGeoJSON, isStrictGeometry, isStrictGeometryCollection, isStrictLineString, isStrictMultiLineString, isStrictMultiPoint, isStrictMultiPolygon, isStrictPoint, isStrictPolygon, isStrictPosition };
143
+ export { type Feature, type FeatureCollection, type GeoJSON, type Geometry, type GeometryCollection, type GeometryPrimitive, type LineString, type MultiLineString, type MultiPoint, type MultiPolygon, type Point, type Polygon, type Position, SimpleGeometryIterator, cartesian, distance, haversine, intersect, isFeature, isFeatureCollection, isGeoJSON, isGeometry, isGeometryCollection, isGeometryPrimitive, isLineString, isMultiLineString, isMultiPoint, isMultiPolygon, isPoint, isPolygon, isPosition, isStrictFeature, isStrictFeatureCollection, isStrictGeoJSON, isStrictGeometry, isStrictGeometryCollection, isStrictGeometryPrimitive, isStrictLineString, isStrictMultiLineString, isStrictMultiPoint, isStrictMultiPolygon, isStrictPoint, isStrictPolygon, isStrictPosition, karney, vincenty };