@mailwoman/spatial 4.9.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 +3 -0
- package/bbox.ts +445 -0
- package/countries/codes.ts +531 -0
- package/countries/index.ts +8 -0
- package/countries/names.ts +274 -0
- package/feature.ts +90 -0
- package/geometries/collection.ts +37 -0
- package/geometries/index.ts +12 -0
- package/geometries/line-string.ts +47 -0
- package/geometries/point.ts +419 -0
- package/geometries/polygon.ts +237 -0
- package/google/index.ts +7 -0
- package/google/place-id.ts +44 -0
- package/h3/index.ts +90 -0
- package/index.ts +16 -0
- package/objects.ts +116 -0
- package/package.json +44 -0
- package/position.ts +269 -0
- package/projection.ts +23 -0
- package/regions/codes.ts +43 -0
- package/regions/index.ts +8 -0
- package/regions/names.ts +29 -0
- package/sdk/index.ts +7 -0
- package/sdk/well-known-text.ts +86 -0
- package/tsconfig.json +15 -0
- package/typedoc.json +4 -0
package/README.md
ADDED
package/bbox.ts
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @copyright Sister Software.
|
|
3
|
+
* @license AGPL-3.0
|
|
4
|
+
* @author Teffen Ellis, et al.
|
|
5
|
+
*
|
|
6
|
+
* GeoJSON Bounding Boxes
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { PolygonLiteral, SolidPolygonPath } from "./geometries/polygon.js"
|
|
10
|
+
import { clampLatitude, wrapLongitude } from "./position.js"
|
|
11
|
+
import { CoordinateProjection } from "./projection.js"
|
|
12
|
+
|
|
13
|
+
//#region Bounding Box Literals
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A 2-dimensional rectangular area that can be determined by two longitudes and two latitudes.
|
|
17
|
+
*
|
|
18
|
+
* @category GeoJSON
|
|
19
|
+
* @category Bounding Box
|
|
20
|
+
* @see {@linkcode BBox} for additional information.
|
|
21
|
+
* @see {@linkcode BBox3DLiteral} for 3-dimensional bounding boxes.
|
|
22
|
+
* @see {@linkcode isBBox} for type-predicates.
|
|
23
|
+
* @see {@link https://tools.ietf.org/html/rfc7946#section-5 GeoJSON Bounding Boxes}
|
|
24
|
+
*/
|
|
25
|
+
export type BBox2DLiteral = [
|
|
26
|
+
/**
|
|
27
|
+
* The most western longitude (in decimal degrees) of the coordinate range.
|
|
28
|
+
*
|
|
29
|
+
* @minimum -180.0
|
|
30
|
+
* @maximum 180.0
|
|
31
|
+
*/
|
|
32
|
+
minLongitude: number,
|
|
33
|
+
/**
|
|
34
|
+
* The most southern latitude (in decimal degrees) of the coordinate range.
|
|
35
|
+
*
|
|
36
|
+
* @minimum -90.0
|
|
37
|
+
* @maximum 90.0
|
|
38
|
+
*/
|
|
39
|
+
minLatitude: number,
|
|
40
|
+
/**
|
|
41
|
+
* The most eastern longitude (in decimal degrees) of the coordinate range.
|
|
42
|
+
*
|
|
43
|
+
* @minimum -180.0
|
|
44
|
+
* @maximum 180.0
|
|
45
|
+
*/
|
|
46
|
+
maxLongitude: number,
|
|
47
|
+
/**
|
|
48
|
+
* The most northern latitude (in decimal degrees) of the coordinate range.
|
|
49
|
+
*
|
|
50
|
+
* @minimum -90.0
|
|
51
|
+
* @maximum 90.0
|
|
52
|
+
*/
|
|
53
|
+
maxLatitude: number,
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* A 3-dimensional rectangular area that can be determined by two longitudes, two latitudes, and two
|
|
58
|
+
* altitudes.
|
|
59
|
+
*
|
|
60
|
+
* @category GeoJSON
|
|
61
|
+
* @category Bounding Box
|
|
62
|
+
* @see {@linkcode BBox} for additional information.
|
|
63
|
+
* @see {@linkcode BBox2DLiteral} for a 2-dimensional bounding box.
|
|
64
|
+
* @see {@link https://tools.ietf.org/html/rfc7946#section-5 GeoJSON Bounding Boxes}
|
|
65
|
+
*/
|
|
66
|
+
export type BBox3DLiteral = [
|
|
67
|
+
/**
|
|
68
|
+
* The most western longitude (in decimal degrees) of the coordinate range.
|
|
69
|
+
*
|
|
70
|
+
* @minimum -180.0
|
|
71
|
+
* @maximum 180.0
|
|
72
|
+
*/
|
|
73
|
+
minLongitude: number,
|
|
74
|
+
/**
|
|
75
|
+
* The most southern latitude (in decimal degrees) of the coordinate range.
|
|
76
|
+
*
|
|
77
|
+
* @minimum -90.0
|
|
78
|
+
* @maximum 90.0
|
|
79
|
+
*/
|
|
80
|
+
minLatitude: number,
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Altitude of the most western longitude (in decimal degrees) of the coordinate range.
|
|
84
|
+
*/
|
|
85
|
+
minAltitude: number,
|
|
86
|
+
/**
|
|
87
|
+
* The most eastern longitude (in decimal degrees) of the coordinate range.
|
|
88
|
+
*
|
|
89
|
+
* @minimum -180.0
|
|
90
|
+
* @maximum 180.0
|
|
91
|
+
*/
|
|
92
|
+
maxLongitude: number,
|
|
93
|
+
/**
|
|
94
|
+
* The most northern latitude (in decimal degrees) of the coordinate range.
|
|
95
|
+
*
|
|
96
|
+
* @minimum -90.0
|
|
97
|
+
* @maximum 90.0
|
|
98
|
+
*/
|
|
99
|
+
maxLatitude: number,
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Altitude of the most eastern longitude (in decimal degrees) of the coordinate range.
|
|
103
|
+
*/
|
|
104
|
+
maxAltitude: number,
|
|
105
|
+
]
|
|
106
|
+
|
|
107
|
+
//#endregion
|
|
108
|
+
|
|
109
|
+
//#region Type Predicates
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Type-predicate for 3-dimensional bounding boxes.
|
|
113
|
+
*
|
|
114
|
+
* This is useful when determining the type of bounding box in a GeoJSON object.
|
|
115
|
+
*
|
|
116
|
+
* @category GeoJSON
|
|
117
|
+
* @category Bounding Box
|
|
118
|
+
*/
|
|
119
|
+
export function is2DBBox(input: unknown): input is BBox3DLiteral {
|
|
120
|
+
return Array.isArray(input) && input.length === 6
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Type-predicate for 3-dimensional bounding boxes.
|
|
125
|
+
*
|
|
126
|
+
* This is useful when determining the type of bounding box in a GeoJSON object.
|
|
127
|
+
*
|
|
128
|
+
* @category GeoJSON
|
|
129
|
+
* @category Bounding Box
|
|
130
|
+
*/
|
|
131
|
+
export function is3DBBox(input: unknown): input is BBox3DLiteral {
|
|
132
|
+
return Array.isArray(input) && input.length === 6
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Type-predicate to determine if the given input is a bounding box.
|
|
137
|
+
*
|
|
138
|
+
* @category GeoJSON
|
|
139
|
+
* @category Bounding Box
|
|
140
|
+
*/
|
|
141
|
+
export function isBBox(input: unknown): input is BBox2DLiteral | BBox3DLiteral {
|
|
142
|
+
return Array.isArray(input) && (input.length === 4 || input.length === 6)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Type-predicate to determine if the given input is a GeoBoundingBox instance.
|
|
147
|
+
*
|
|
148
|
+
* Note that this function only checks if the input is an instance of the GeoBoundingBox class.
|
|
149
|
+
* `instanceof` checks are not reliable in JavaScript, so this function should be used with
|
|
150
|
+
* caution.
|
|
151
|
+
*
|
|
152
|
+
* @category GeoJSON
|
|
153
|
+
*/
|
|
154
|
+
export function isGeoBoundingBox(input: unknown): input is GeoBoundingBox {
|
|
155
|
+
return input instanceof GeoBoundingBox
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Input for creating a GeoBoundingBox instance.
|
|
162
|
+
*/
|
|
163
|
+
export type GeoBoundingBoxInput = BBox2DLiteral | BBox3DLiteral | GeoBoundingBox
|
|
164
|
+
|
|
165
|
+
// MARK: - GeoBoundingBox
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* A bounding box to represent the coordinate range of a GeoJSON object.
|
|
169
|
+
*
|
|
170
|
+
* This is useful when defining the extent of a GeoJSON object, such as the minimum and maximum
|
|
171
|
+
* coordinates of the object's Geometries, Features, or Feature Collections.
|
|
172
|
+
*/
|
|
173
|
+
export class GeoBoundingBox {
|
|
174
|
+
//#region Properties
|
|
175
|
+
|
|
176
|
+
public projection: CoordinateProjection
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The most western longitude (in decimal degrees) of the coordinate range.
|
|
180
|
+
*
|
|
181
|
+
* @minimum -180.0
|
|
182
|
+
* @maximum 180.0
|
|
183
|
+
*/
|
|
184
|
+
#minLongitude: number
|
|
185
|
+
/**
|
|
186
|
+
* The most southern latitude (in decimal degrees) of the coordinate range.
|
|
187
|
+
*
|
|
188
|
+
* @minimum -90.0
|
|
189
|
+
* @maximum 90.0
|
|
190
|
+
*/
|
|
191
|
+
#minLatitude: number
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Altitude of the most western longitude (in decimal degrees) of the coordinate range.
|
|
195
|
+
*/
|
|
196
|
+
#minAltitude: number
|
|
197
|
+
/**
|
|
198
|
+
* The most eastern longitude (in decimal degrees) of the coordinate range.
|
|
199
|
+
*
|
|
200
|
+
* @minimum -180.0
|
|
201
|
+
* @maximum 180.0
|
|
202
|
+
*/
|
|
203
|
+
#maxLongitude: number
|
|
204
|
+
/**
|
|
205
|
+
* The most northern latitude (in decimal degrees) of the coordinate range.
|
|
206
|
+
*
|
|
207
|
+
* @minimum -90.0
|
|
208
|
+
* @maximum 90.0
|
|
209
|
+
*/
|
|
210
|
+
#maxLatitude: number
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Altitude of the most eastern longitude (in decimal degrees) of the coordinate range.
|
|
214
|
+
*/
|
|
215
|
+
#maxAltitude: number
|
|
216
|
+
|
|
217
|
+
//#endregion
|
|
218
|
+
|
|
219
|
+
//#region Accessors
|
|
220
|
+
|
|
221
|
+
public get minLongitude() {
|
|
222
|
+
return this.#minLongitude
|
|
223
|
+
}
|
|
224
|
+
public set minLongitude(value: number) {
|
|
225
|
+
this.#minLongitude = wrapLongitude(value)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
public get minLatitude() {
|
|
229
|
+
return this.#minLatitude
|
|
230
|
+
}
|
|
231
|
+
public set minLatitude(value: number) {
|
|
232
|
+
this.#minLatitude = clampLatitude(value)
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public get maxLongitude() {
|
|
236
|
+
return this.#maxLongitude
|
|
237
|
+
}
|
|
238
|
+
public set maxLongitude(value: number) {
|
|
239
|
+
this.#maxLongitude = wrapLongitude(value)
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public get maxLatitude() {
|
|
243
|
+
return this.#maxLatitude
|
|
244
|
+
}
|
|
245
|
+
public set maxLatitude(value: number) {
|
|
246
|
+
this.#maxLatitude = clampLatitude(value)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
public get minAltitude() {
|
|
250
|
+
return this.#minAltitude
|
|
251
|
+
}
|
|
252
|
+
public set minAltitude(value: number) {
|
|
253
|
+
this.#minAltitude = value
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
public get maxAltitude() {
|
|
257
|
+
return this.#maxAltitude
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public set maxAltitude(value: number) {
|
|
261
|
+
this.#maxAltitude = value
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
public get east(): number {
|
|
265
|
+
return this.#maxLongitude
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
public set east(value: number) {
|
|
269
|
+
this.#maxLongitude = wrapLongitude(value)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
public get north(): number {
|
|
273
|
+
return this.#maxLatitude
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public set north(value: number) {
|
|
277
|
+
this.#maxLatitude = clampLatitude(value)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
public get south(): number {
|
|
281
|
+
return this.#minLatitude
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
public set south(value: number) {
|
|
285
|
+
this.#minLatitude = clampLatitude(value)
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
public get west(): number {
|
|
289
|
+
return this.#minLongitude
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public set west(value: number) {
|
|
293
|
+
this.#minLongitude = wrapLongitude(value)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
public get elevation(): number {
|
|
297
|
+
return this.#maxAltitude
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public set elevation(value: number) {
|
|
301
|
+
this.#maxAltitude = value
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
public get depth(): number {
|
|
305
|
+
return this.#minAltitude
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
public set depth(value: number) {
|
|
309
|
+
this.#minAltitude = value
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
public [Symbol.iterator]() {
|
|
313
|
+
return this.toJSON()[Symbol.iterator]()
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
//#endregion
|
|
317
|
+
|
|
318
|
+
//#region Constructors
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Creates a blank GeoBoundingBox instance.
|
|
322
|
+
*/
|
|
323
|
+
constructor()
|
|
324
|
+
/**
|
|
325
|
+
* Creates a new GeoBoundingBox instance from the given 2D bounding box.
|
|
326
|
+
*/
|
|
327
|
+
constructor(bbox: BBox2DLiteral, projection?: CoordinateProjection)
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Creates a new GeoBoundingBox instance from the given 3D bounding box.
|
|
331
|
+
*/
|
|
332
|
+
constructor(bbox: BBox3DLiteral, projection?: CoordinateProjection)
|
|
333
|
+
|
|
334
|
+
constructor(input?: GeoBoundingBoxInput, projection?: CoordinateProjection)
|
|
335
|
+
constructor(input?: GeoBoundingBoxInput, projection?: CoordinateProjection) {
|
|
336
|
+
let bbox: BBox2DLiteral | BBox3DLiteral
|
|
337
|
+
|
|
338
|
+
if (input instanceof GeoBoundingBox) {
|
|
339
|
+
bbox = input.toJSON()
|
|
340
|
+
} else if (isBBox(input)) {
|
|
341
|
+
bbox = input
|
|
342
|
+
} else {
|
|
343
|
+
bbox = [0, 0, 0, 0]
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const [
|
|
347
|
+
// ---
|
|
348
|
+
minLongitude = 0,
|
|
349
|
+
minLatitude = 0,
|
|
350
|
+
maxLongitude = 0,
|
|
351
|
+
maxLatitude = 0,
|
|
352
|
+
minAltitude = 0,
|
|
353
|
+
maxAltitude = 0,
|
|
354
|
+
] = bbox
|
|
355
|
+
|
|
356
|
+
this.#minLongitude = minLongitude
|
|
357
|
+
this.#minLatitude = minLatitude
|
|
358
|
+
this.#maxLongitude = maxLongitude
|
|
359
|
+
this.#maxLatitude = maxLatitude
|
|
360
|
+
this.#minAltitude = minAltitude
|
|
361
|
+
this.#maxAltitude = maxAltitude
|
|
362
|
+
this.projection = projection ?? CoordinateProjection.WGS84
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
//#endregion
|
|
366
|
+
|
|
367
|
+
//#region Predicates
|
|
368
|
+
|
|
369
|
+
public is3D() {
|
|
370
|
+
return this.#minAltitude !== 0 || this.#maxAltitude !== 0
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
public is2D() {
|
|
374
|
+
return !this.is3D()
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
//#endregion
|
|
378
|
+
|
|
379
|
+
//#region Conversion
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Converts the 2D GeoBoundingBox to an array literal.
|
|
383
|
+
*/
|
|
384
|
+
public toJSON2D(): BBox2DLiteral {
|
|
385
|
+
return [
|
|
386
|
+
// ---
|
|
387
|
+
this.#minLongitude,
|
|
388
|
+
this.#minLatitude,
|
|
389
|
+
this.#maxLongitude,
|
|
390
|
+
this.#maxLatitude,
|
|
391
|
+
]
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Converts the 3D GeoBoundingBox to an array literal.
|
|
396
|
+
*/
|
|
397
|
+
public toJSON3D(): BBox3DLiteral {
|
|
398
|
+
return [
|
|
399
|
+
// ---
|
|
400
|
+
this.#minLongitude,
|
|
401
|
+
this.#minLatitude,
|
|
402
|
+
this.#minAltitude,
|
|
403
|
+
this.#maxLongitude,
|
|
404
|
+
this.#maxLatitude,
|
|
405
|
+
this.#maxAltitude,
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
public toJSON(): BBox2DLiteral | BBox3DLiteral {
|
|
410
|
+
if (this.is3D()) return this.toJSON3D()
|
|
411
|
+
|
|
412
|
+
return this.toJSON2D()
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Converts the GeoBoundingBox to a GeoJSON Polygon, omitting the altitude.
|
|
417
|
+
*/
|
|
418
|
+
public to2DPolygon(): PolygonLiteral {
|
|
419
|
+
const { minLatitude, maxLatitude, minLongitude, maxLongitude } = this
|
|
420
|
+
const path: SolidPolygonPath = [
|
|
421
|
+
[
|
|
422
|
+
[minLongitude, minLatitude],
|
|
423
|
+
[maxLongitude, minLatitude],
|
|
424
|
+
[maxLongitude, maxLatitude],
|
|
425
|
+
[minLongitude, maxLatitude],
|
|
426
|
+
[minLongitude, minLatitude],
|
|
427
|
+
],
|
|
428
|
+
]
|
|
429
|
+
|
|
430
|
+
return { type: "Polygon", coordinates: path }
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Converts the GeoBoundingBox to a Well-Known-Text (WKT) string.
|
|
435
|
+
*
|
|
436
|
+
* This is useful when building Spatialite query parameters.
|
|
437
|
+
*/
|
|
438
|
+
public to2DEWKT(): string {
|
|
439
|
+
const { minLatitude, maxLatitude, minLongitude, maxLongitude } = this
|
|
440
|
+
|
|
441
|
+
return `SRID=${this.projection};POLYGON((${minLongitude} ${minLatitude}, ${maxLongitude} ${minLatitude}, ${maxLongitude} ${maxLatitude}, ${minLongitude} ${maxLatitude}, ${minLongitude} ${minLatitude}))`
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
//#endregion
|
|
445
|
+
}
|