@swissgeo/coordinates 1.0.0-beta.1

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.
@@ -0,0 +1,647 @@
1
+ import { proj4 as proj4_2 } from 'proj4';
2
+
3
+ /** Representation of many (available in this app) projection systems */
4
+ export declare const allCoordinateSystems: CoordinateSystem[];
5
+
6
+ declare interface ConfigCreatePixelExtentAround {
7
+ /**
8
+ * Number of pixels the extent should be (if s100 is given, a box of 100x100 pixels with the
9
+ * coordinate at its center will be returned)
10
+ */
11
+ size: number;
12
+ /** Where the center of the "size" pixel(s) extent should be. */
13
+ coordinate: SingleCoordinate;
14
+ /** Projection used to describe the coordinates */
15
+ projection: CoordinateSystem;
16
+ /** Current map resolution, necessary to calculate how much distance "size" pixel(s) means. */
17
+ resolution: number;
18
+ /** Tells if the extent's value should be rounded before being returned. Default is `false` */
19
+ rounded?: boolean;
20
+ }
21
+
22
+ export declare const constants: SwissGeoCoordinateConstants;
23
+
24
+ declare const coordinates: SwissGeoCoordinates;
25
+ export default coordinates;
26
+
27
+ /**
28
+ * Group of coordinates resulting in a "split by bounds" function. Will also contain information if
29
+ * this chunk is within or outside the bounds from which it was cut from.
30
+ */
31
+ export declare interface CoordinatesChunk {
32
+ /** Coordinates of this chunk */
33
+ coordinates: SingleCoordinate[];
34
+ /** Will be true if this chunk contains coordinates that are located within bounds */
35
+ isWithinBounds: boolean;
36
+ }
37
+
38
+ /**
39
+ * Group of coordinates resulting in a "split by bounds" function. Will also contain information if
40
+ * this chunk is within or outside the bounds from which it was cut from.
41
+ */
42
+ declare interface CoordinatesChunk_2 {
43
+ /** Coordinates of this chunk */
44
+ coordinates: SingleCoordinate[];
45
+ /** Will be true if this chunk contains coordinates that are located within bounds */
46
+ isWithinBounds: boolean;
47
+ }
48
+
49
+ export declare const coordinatesUtils: SwissGeoCoordinatesUtils;
50
+
51
+ /**
52
+ * Representation of a coordinate system (or also called projection system) in the context of this
53
+ * application.
54
+ *
55
+ * These coordinate systems will be used to drive the mapping framework, helping it grasp which zoom
56
+ * level or resolution to show, where to start the view (with the center of bounds), how to handle a
57
+ * projection change, etc...
58
+ *
59
+ * @abstract
60
+ */
61
+ export declare abstract class CoordinateSystem {
62
+ /**
63
+ * EPSG:xxxx representation of this coordinate system, but only the numerical part (without the
64
+ * "EPSG:")
65
+ */
66
+ readonly epsgNumber: number;
67
+ /** EPSG:xxxx representation of this coordinate system */
68
+ readonly epsg: string;
69
+ /**
70
+ * Label to show users when they are dealing with this coordinate system (can be a translation
71
+ * key)
72
+ */
73
+ readonly label: string;
74
+ /**
75
+ * Name of this projection, if applicable, so that it can be tested against name in fields such
76
+ * as COG metadata parsing.
77
+ */
78
+ readonly technicalName?: string;
79
+ /**
80
+ * A string describing how proj4 should handle projection/reprojection of this coordinate
81
+ * system, in regard to WGS84. These matrices can be found on the EPSG website for each
82
+ * projection in the Export section, inside the PROJ.4 export type (can be directly accessed by
83
+ * adding .proj4 to the URL of one projection's page on the EPSG website, i.e.
84
+ * https://epsg.io/3857.proj4 for WebMercator)
85
+ */
86
+ readonly proj4transformationMatrix: string;
87
+ /**
88
+ * Bounds of this projection system, expressed as in its own coordinate system. These boundaries
89
+ * can also be found on the EPSG website, in the section "Projected bounds" of a projection's
90
+ * page. It is possible to specify a custom center to these bounds, so that the application
91
+ * starts at this custom center instead of the natural center (when no coordinates are specified
92
+ * at startup).
93
+ */
94
+ readonly bounds?: CoordinateSystemBounds;
95
+ /**
96
+ * A boolean variable indicating whether the Mercator projection pyramid is used.
97
+ *
98
+ * The Mercator projection pyramid is a specific spatial reference system commonly used in
99
+ * mapping and geographic information systems (GIS) applications.
100
+ *
101
+ * If set to `true`, it signifies that the system or dataset is leveraging this projection
102
+ * methodology.
103
+ *
104
+ * If set to `false`, it indicates that the dataset uses an alternative projection or tiling
105
+ * scheme.
106
+ */
107
+ readonly usesMercatorPyramid: boolean;
108
+ constructor(args: CoordinateSystemProps);
109
+ /**
110
+ * Transforms the bounds of this coordinates system to be expressed in the wanted coordinate
111
+ * system
112
+ *
113
+ * If the coordinate system is invalid, or if bounds are not defined, it will return null
114
+ *
115
+ * @param {CoordinateSystem} coordinateSystem The target coordinate system we want bounds
116
+ * expressed in
117
+ * @returns {CoordinateSystemBounds | undefined} Bounds, expressed in the coordinate system, or
118
+ * undefined if bounds are undefined or the coordinate system is invalid
119
+ */
120
+ getBoundsAs(coordinateSystem: CoordinateSystem): CoordinateSystemBounds | undefined;
121
+ isInBounds(x: number, y: number): boolean;
122
+ isInBounds(coordinate: SingleCoordinate): boolean;
123
+ /**
124
+ * @abstract
125
+ * @returns The Index in the resolution list where the 1:25000 zoom level is
126
+ */
127
+ abstract get1_25000ZoomLevel(): number;
128
+ /**
129
+ * @abstract
130
+ * @returns The default zoom to use when starting the map in this coordinate system (if none are
131
+ * set so far)
132
+ */
133
+ abstract getDefaultZoom(): number;
134
+ /**
135
+ * Rounds a zoom level.
136
+ *
137
+ * You can, by overwriting this function, add custom zoom level roundings or similar function in
138
+ * your custom coordinate systems.
139
+ *
140
+ * @param zoom A zoom level in this coordinate system
141
+ * @returns The given zoom level after rounding
142
+ */
143
+ roundZoomLevel(zoom: number): number;
144
+ /**
145
+ * Returns the corresponding resolution to the given zoom level and center (some coordinate
146
+ * system must take some deformation into account the further north we are)
147
+ *
148
+ * @abstract
149
+ * @param zoom A zoom level
150
+ * @param center The current center of view, expressed with this coordinate system
151
+ * @returns The resolution at the given zoom level, in the context of this coordinate system
152
+ */
153
+ abstract getResolutionForZoomAndCenter(zoom: number, center: SingleCoordinate): number;
154
+ /**
155
+ * Returns the zoom level to match the given resolution and center (some coordinate system must
156
+ * take some deformation into account the further north we are)
157
+ *
158
+ * @abstract
159
+ * @param resolution The resolution of the map, expressed in meter per pixel
160
+ * @param center The current center of view, expressed in this coordinate system
161
+ * @returns The corresponding zoom level, in the context of this coordinate system
162
+ */
163
+ abstract getZoomForResolutionAndCenter(resolution: number, center: SingleCoordinate): number;
164
+ /**
165
+ * Returns a rounded value of a coordinate value, in the context of this coordinate system. This
166
+ * enables us to decide how many decimal points we want to keep for numbers after calculation
167
+ * within this coordinate system (no need to keep values that are irrelevant to precision for
168
+ * most maps, such as below 1cm)
169
+ *
170
+ * @abstract
171
+ * @param {Number} value A value to be rounded
172
+ * @returns {Number} The rounded value, with desired remaining decimal point for this coordinate
173
+ * system
174
+ */
175
+ abstract roundCoordinateValue(value: number): number;
176
+ /**
177
+ * A (descending) list of all the available resolution steps for this coordinate system. If this
178
+ * is not the behavior you want, you have to override this function.
179
+ */
180
+ getResolutionSteps(latitude?: number): ResolutionStep[];
181
+ /**
182
+ * The origin to use as anchor for tile coordinate calculations. It will return the bound's
183
+ * [lowerX, upperY] as default value (meaning the top-left corner of bounds). If this is not the
184
+ * behavior you want, you have to override this function.
185
+ *
186
+ * If no bounds are defined, it will return [0, 0]
187
+ */
188
+ getTileOrigin(): SingleCoordinate;
189
+ /**
190
+ * List of matrix identifiers for this coordinate system. If this is not the behavior you want,
191
+ * you have to override this function.
192
+ */
193
+ getMatrixIds(): number[];
194
+ }
195
+
196
+ /**
197
+ * Representation of boundaries of a coordinate system (also sometime called extent)
198
+ *
199
+ * It is expressed by the most bottom left points possible / top right point possible, meaning that
200
+ * a combination of these two gives us the area in which the coordinate system can produce valid
201
+ * coordinates
202
+ */
203
+ export declare class CoordinateSystemBounds {
204
+ readonly lowerX: number;
205
+ readonly upperX: number;
206
+ readonly lowerY: number;
207
+ readonly upperY: number;
208
+ readonly customCenter?: SingleCoordinate;
209
+ readonly bottomLeft: SingleCoordinate;
210
+ readonly bottomRight: SingleCoordinate;
211
+ readonly topLeft: SingleCoordinate;
212
+ readonly topRight: SingleCoordinate;
213
+ readonly center: SingleCoordinate;
214
+ /** A flattened version of the bounds such as [lowerX, lowerY, upperX, upperY] */
215
+ readonly flatten: [number, number, number, number];
216
+ /**
217
+ * @param args.lowerX
218
+ * @param args.upperX
219
+ * @param args.lowerY
220
+ * @param args.upperY
221
+ * @param args.customCenter If this bounds must have a different center (if we want to offset
222
+ * the natural center of those bounds). If no custom center is given, the center will be
223
+ * calculated relative to the bounds.
224
+ */
225
+ constructor(args: CoordinateSystemBoundsProps);
226
+ isInBounds(x: number, y: number): boolean;
227
+ isInBounds(coordinate: SingleCoordinate): boolean;
228
+ /**
229
+ * Will split the coordinates in chunks if some portion of the coordinates are outside bounds
230
+ * (one chunk for the portion inside, one for the portion outside, rinse and repeat if
231
+ * necessary)
232
+ *
233
+ * Can be helpful when requesting information from our backends, but said backend doesn't
234
+ * support world-wide coverage. Typical example is service-profile, if we give it coordinates
235
+ * outside LV95 bounds it will fill what it doesn't know with coordinates following LV95 extent
236
+ * instead of returning undefined
237
+ *
238
+ * @param {[Number, Number][]} coordinates Coordinates `[[x1,y1],[x2,y2],...]` expressed in the
239
+ * same coordinate system (projection) as the bounds
240
+ * @returns {CoordinatesChunk[] | undefined}
241
+ */
242
+ splitIfOutOfBounds(coordinates: SingleCoordinate[]): CoordinatesChunk_2[] | undefined;
243
+ }
244
+
245
+ declare interface CoordinateSystemBoundsProps {
246
+ lowerX: number;
247
+ upperX: number;
248
+ lowerY: number;
249
+ upperY: number;
250
+ customCenter?: SingleCoordinate;
251
+ }
252
+
253
+ declare interface CoordinateSystemProps {
254
+ /**
255
+ * EPSG:xxxx representation of this coordinate system, but only the numerical part (without the
256
+ * "EPSG:")
257
+ */
258
+ epsgNumber: number;
259
+ /**
260
+ * Label to show users when they are dealing with this coordinate system (can be a translation
261
+ * key)
262
+ */
263
+ label: string;
264
+ /**
265
+ * Name of this projection, if applicable, so that it can be tested against name in fields such
266
+ * as COG metadata parsing.
267
+ */
268
+ technicalName?: string;
269
+ /**
270
+ * A string describing how proj4 should handle projection/reprojection of this coordinate
271
+ * system, in regard to WGS84. These matrices can be found on the EPSG website for each
272
+ * projection in the Export section, inside the PROJ.4 export type (can be directly accessed by
273
+ * adding .proj4 to the URL of one projection's page on the EPSG website, i.e.
274
+ * https://epsg.io/3857.proj4 for WebMercator)
275
+ */
276
+ proj4transformationMatrix: string;
277
+ /**
278
+ * Bounds of this projection system, expressed as in its own coordinate system. These boundaries
279
+ * can also be found on the EPSG website, in the section "Projected bounds" of a projection's
280
+ * page. It is possible to specify a custom center to these bounds, so that the application
281
+ * starts at this custom center instead of the natural center (when no coordinates are specified
282
+ * at startup).
283
+ */
284
+ bounds?: CoordinateSystemBounds;
285
+ /**
286
+ * A boolean variable indicating whether the Mercator projection pyramid is used.
287
+ *
288
+ * The Mercator projection pyramid is a specific spatial reference system commonly used in
289
+ * mapping and geographic information systems (GIS) applications.
290
+ *
291
+ * If set to `true`, it signifies that the system or dataset is leveraging this projection
292
+ * methodology.
293
+ *
294
+ * If set to `false`, it indicates that the dataset uses an alternative projection or tiling
295
+ * scheme.
296
+ */
297
+ usesMercatorPyramid: boolean;
298
+ }
299
+
300
+ export declare function createPixelExtentAround(config: ConfigCreatePixelExtentAround): FlatExtent | undefined;
301
+
302
+ export declare const crs: SwissGeoCoordinateCRS;
303
+
304
+ /**
305
+ * Description of a coordinate system that will not use the standard resolution and zoom level
306
+ * (a.k.a. mercator pyramid).
307
+ *
308
+ * This can be used to describe national coordinate systems that are built to represent a subset of
309
+ * the World, with a custom zoom pyramid to match their map resolutions.
310
+ *
311
+ * You can see examples by following {@link SwissCoordinateSystem} and its children.
312
+ *
313
+ * @abstract
314
+ * @see https://wiki.openstreetmap.org/wiki/Zoom_levels
315
+ */
316
+ export declare abstract class CustomCoordinateSystem extends CoordinateSystem {
317
+ readonly bounds: CoordinateSystemBounds;
318
+ protected constructor(args: CustomCoordinateSystemProps);
319
+ /**
320
+ * The origin to use as anchor for tile coordinate calculations. It will return the bound's
321
+ * [lowerX, upperY] as default value (meaning the top-left corner of bounds). If this is not the
322
+ * behavior you want, you have to override this function.
323
+ */
324
+ getTileOrigin(): SingleCoordinate;
325
+ /**
326
+ * Transforms a zoom level from this custom coordinate system, back to a zoom level such as
327
+ * described in https://wiki.openstreetmap.org/wiki/Zoom_levels
328
+ *
329
+ * @abstract
330
+ * @param customZoomLevel A zoom level in this custom coordinate system
331
+ * @returns A standard (or OpenStreetMap) zoom level
332
+ */
333
+ abstract transformCustomZoomLevelToStandard(customZoomLevel: number): number;
334
+ /**
335
+ * Transforms a standard (or OpenStreetMap) zoom level into a zoom level in this coordinate
336
+ * system
337
+ *
338
+ * @param standardZoomLevel A standard zoom level
339
+ * @returns A zoom level in this custom coordinate system
340
+ */
341
+ abstract transformStandardZoomLevelToCustom(standardZoomLevel: number): number;
342
+ }
343
+
344
+ declare interface CustomCoordinateSystemProps extends CoordinateSystemProps {
345
+ /** With a custom coordinate system, bounds are mandatory. */
346
+ bounds: CoordinateSystemBounds;
347
+ }
348
+
349
+ export declare const extentUtils: SwissGeoExtentUtils;
350
+
351
+ export declare type FlatExtent = [number, number, number, number];
352
+
353
+ /**
354
+ * Flatten extent
355
+ *
356
+ * @param extent Extent to flatten
357
+ * @returns Flatten extent in from [minx, miny, maxx, maxy]
358
+ */
359
+ export declare function flattenExtent(extent: FlatExtent | NormalizedExtent): FlatExtent;
360
+
361
+ export declare function getExtentCenter(extent: FlatExtent | NormalizedExtent): SingleCoordinate;
362
+
363
+ /**
364
+ * Get the intersection of the extent with the current projection, as a flatten extent expressed in
365
+ * the current projection
366
+ *
367
+ * @param extent Such as [minx, miny, maxx, maxy]. or [bottomLeft, topRight]
368
+ * @param extentProjection
369
+ * @param currentProjection
370
+ */
371
+ export declare function getExtentIntersectionWithCurrentProjection(extent: FlatExtent | NormalizedExtent, extentProjection: CoordinateSystem, currentProjection: CoordinateSystem): FlatExtent | undefined;
372
+
373
+ export declare const LV03: LV03CoordinateSystem;
374
+
375
+ declare class LV03CoordinateSystem extends SwissCoordinateSystem {
376
+ constructor();
377
+ }
378
+
379
+ export declare const LV95: LV95CoordinateSystem;
380
+
381
+ declare class LV95CoordinateSystem extends SwissCoordinateSystem {
382
+ constructor();
383
+ }
384
+
385
+ export declare type NormalizedExtent = [[number, number], [number, number]];
386
+
387
+ /**
388
+ * Return an extent normalized to [[x, y], [x, y]] from a flat extent
389
+ *
390
+ * @param extent Extent to normalize
391
+ * @returns Extent in the form [[x, y], [x, y]]
392
+ */
393
+ export declare function normalizeExtent(extent: FlatExtent | NormalizedExtent): NormalizedExtent;
394
+
395
+ declare function parseCRS(crs?: string): CoordinateSystem | undefined;
396
+
397
+ /**
398
+ * @param fromProj Current projection used to describe the extent
399
+ * @param toProj Target projection we want the extent be expressed in
400
+ * @param extent An extent, described as `[minx, miny, maxx, maxy].` or `[[minx, miny], [maxx,
401
+ * maxy]]`
402
+ * @returns The reprojected extent
403
+ */
404
+ export declare function projExtent<T extends FlatExtent | NormalizedExtent>(fromProj: CoordinateSystem, toProj: CoordinateSystem, extent: T): T;
405
+
406
+ /**
407
+ * Proj4 comes with [EPSG:4326]{@link https://epsg.io/4326} as default projection.
408
+ *
409
+ * By default, this adds the two Swiss projections ([LV95/EPSG:2056]{@link https://epsg.io/2056} and
410
+ * [LV03/EPSG:21781]{@link https://epsg.io/21781}) and metric Web Mercator
411
+ * ([EPSG:3857]{@link https://epsg.io/3857}) definitions to proj4
412
+ *
413
+ * Further projection can be added by settings the param projections (do not forget to include LV95,
414
+ * LV03 and/or WebMercator if you intended to use them too)
415
+ */
416
+ export declare const registerProj4: (proj4: proj4_2, projections?: CoordinateSystem[]) => void;
417
+
418
+ /**
419
+ * Remove any Z value from a set of coordinates
420
+ *
421
+ * @param coordinates
422
+ */
423
+ declare function removeZValues(coordinates: SingleCoordinate[] | Single3DCoordinate[]): SingleCoordinate[];
424
+
425
+ declare function reprojectAndRound<T extends SingleCoordinate | SingleCoordinate[]>(from: CoordinateSystem, into: CoordinateSystem, coordinates: T): T;
426
+
427
+ /** Representation of a resolution step in a coordinate system. Can be linked to a zoom level or not. */
428
+ export declare interface ResolutionStep {
429
+ /** Resolution of this step, in meters/pixel */
430
+ resolution: number;
431
+ /** Corresponding zoom level for this resolution step */
432
+ zoom?: number;
433
+ /** Name of the map product shown at this resolution/zoom */
434
+ label?: string;
435
+ }
436
+
437
+ export declare type Single3DCoordinate = [number, number, number];
438
+
439
+ export declare type SingleCoordinate = [number, number];
440
+
441
+ /**
442
+ * Coordinate system with a zoom level/resolution calculation based on the size of the Earth at the
443
+ * equator.
444
+ *
445
+ * These will be used to represent WebMercator and WGS84 among others.
446
+ *
447
+ * @abstract
448
+ * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale
449
+ * @see https://wiki.openstreetmap.org/wiki/Zoom_levels
450
+ */
451
+ export declare abstract class StandardCoordinateSystem extends CoordinateSystem {
452
+ /** The index in the resolution list where the 1:25000 zoom level is */
453
+ get1_25000ZoomLevel(): number;
454
+ getDefaultZoom(): number;
455
+ }
456
+
457
+ /**
458
+ * This specialization will be used to represent LV95 and LV03, that use a custom zoom/resolution
459
+ * pyramid to match all our printable products (in contrast to {@link StandardCoordinateSystem} which
460
+ * bases its zoom/resolution on the radius of the Earth at the equator and latitude positioning of
461
+ * the map).
462
+ *
463
+ * @abstract
464
+ * @see https://api3.geo.admin.ch/services/sdiservices.html#wmts
465
+ * @see https://wiki.openstreetmap.org/wiki/Zoom_levels
466
+ */
467
+ export declare class SwissCoordinateSystem extends CustomCoordinateSystem {
468
+ getResolutionSteps(): ResolutionStep[];
469
+ get1_25000ZoomLevel(): number;
470
+ getDefaultZoom(): number;
471
+ transformStandardZoomLevelToCustom(standardZoomLevel: number): number;
472
+ /**
473
+ * Mapping between Swiss map zooms and standard zooms. Heavily inspired by
474
+ * {@link https://github.com/geoadmin/mf-geoadmin3/blob/ce885985e4af5e3e20c87321e67a650388af3602/src/components/map/MapUtilsService.js#L603-L631 MapUtilsService.js on mf-geoadmin3}
475
+ *
476
+ * @param customZoomLevel A zoom level as desribed in
477
+ * {@link http://api3.geo.admin.ch/services/sdiservices.html#wmts our backend's doc}
478
+ * @returns A web-mercator zoom level (as described on
479
+ * {@link https://wiki.openstreetmap.org/wiki/Zoom_levels | OpenStreetMap's wiki}) or the zoom
480
+ * level to show the 1:25'000 map if the input is invalid
481
+ */
482
+ transformCustomZoomLevelToStandard(customZoomLevel: number): number;
483
+ getResolutionForZoomAndCenter(zoom: number): number;
484
+ getZoomForResolutionAndCenter(resolution: number): number;
485
+ roundCoordinateValue(value: number): number;
486
+ /**
487
+ * Rounding to the zoom level
488
+ *
489
+ * @param customZoomLevel A zoom level, that could be a floating number
490
+ * @param normalize Normalize the zoom level to the closest swisstopo zoom level, by default it
491
+ * only round the zoom level to 3 decimal
492
+ * @returns A zoom level matching one of our national maps
493
+ */
494
+ roundZoomLevel(customZoomLevel: number, normalize?: boolean): number;
495
+ }
496
+
497
+ declare interface SwissGeoCoordinateConstants {
498
+ STANDARD_ZOOM_LEVEL_1_25000_MAP: number;
499
+ SWISS_ZOOM_LEVEL_1_25000_MAP: number;
500
+ LV95_RESOLUTIONS: number[];
501
+ SWISSTOPO_TILEGRID_RESOLUTIONS: number[];
502
+ }
503
+
504
+ export declare interface SwissGeoCoordinateCRS {
505
+ LV95: LV95CoordinateSystem;
506
+ LV03: LV03CoordinateSystem;
507
+ WGS84: WGS84CoordinateSystem;
508
+ WEBMERCATOR: WebMercatorCoordinateSystem;
509
+ allCoordinateSystems: CoordinateSystem[];
510
+ }
511
+
512
+ declare interface SwissGeoCoordinates extends SwissGeoCoordinateCRS {
513
+ coordinatesUtils: SwissGeoCoordinatesUtils;
514
+ extentUtils: SwissGeoExtentUtils;
515
+ registerProj4: typeof registerProj4;
516
+ }
517
+
518
+ export declare interface SwissGeoCoordinatesUtils {
519
+ toRoundedString: typeof toRoundedString;
520
+ wrapXCoordinates: typeof wrapXCoordinates;
521
+ unwrapGeometryCoordinates: typeof unwrapGeometryCoordinates;
522
+ removeZValues: typeof removeZValues;
523
+ reprojectAndRound: typeof reprojectAndRound;
524
+ parseCRS: typeof parseCRS;
525
+ }
526
+
527
+ export declare interface SwissGeoExtentUtils {
528
+ projExtent: typeof projExtent;
529
+ normalizeExtent: typeof normalizeExtent;
530
+ flattenExtent: typeof flattenExtent;
531
+ getExtentIntersectionWithCurrentProjection: typeof getExtentIntersectionWithCurrentProjection;
532
+ createPixelExtentAround: typeof createPixelExtentAround;
533
+ getExtentCenter: typeof getExtentCenter;
534
+ }
535
+
536
+ /**
537
+ * Returns rounded coordinate with thousands separator and comma.
538
+ *
539
+ * @param coordinate The raw coordinate as array.
540
+ * @param digits Decimal digits to round to.
541
+ * @param [withThousandsSeparator=true] If thousands should be separated with a single quote
542
+ * character. Default is `true`
543
+ * @param [enforceDigit=false] If set to true, we want to have that many figures after the period.
544
+ * Otherwise, we don't care. Default is `false`
545
+ * @returns Formatted coordinate.
546
+ * @see https://stackoverflow.com/a/2901298/4840446
547
+ */
548
+ declare function toRoundedString(coordinate: SingleCoordinate, digits: number, withThousandsSeparator?: boolean, enforceDigit?: boolean): string | undefined;
549
+
550
+ /**
551
+ * Returns the coordinates unwrapped if they were placed into an extra array. This can happen when
552
+ * dealing with GeoJSON coordinate, where some geometry types require coordinate in a format such as
553
+ * [ [ [x,y], [x,y] ], [...feature2...] ]
554
+ *
555
+ * Most of our backends only deal with the first feature of such array, this function will unwrap
556
+ * it, or return the array as is if it is not required
557
+ */
558
+ declare function unwrapGeometryCoordinates(geometryCoordinates?: SingleCoordinate[] | SingleCoordinate[][] | SingleCoordinate[][][]): SingleCoordinate[];
559
+
560
+ export declare const WEBMERCATOR: WebMercatorCoordinateSystem;
561
+
562
+ declare class WebMercatorCoordinateSystem extends StandardCoordinateSystem {
563
+ constructor();
564
+ roundCoordinateValue(value: number): number;
565
+ /**
566
+ * Formula comes from
567
+ * https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale
568
+ *
569
+ * resolution = 156543.03 meters / pixel * cos(latitude) / (2 ^ zoom level)
570
+ */
571
+ getResolutionForZoomAndCenter(zoom: number, center: SingleCoordinate): number;
572
+ /**
573
+ * Calculating zoom level by reversing formula from
574
+ * https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale :
575
+ *
576
+ * resolution = 156543.03 * cos(latitude) / (2 ^ zoom level)
577
+ *
578
+ * So that
579
+ *
580
+ * zoom level = log2( resolution / 156543.03 / cos(latitude) )
581
+ *
582
+ * @param resolution Resolution in meter/pixel
583
+ * @param center As the use an equatorial constant to calculate the zoom level, we need to know
584
+ * the latitude of the position the resolution must be calculated at, as we need to take into
585
+ * account the deformation of the WebMercator projection (that is greater the further north we
586
+ * are)
587
+ */
588
+ getZoomForResolutionAndCenter(resolution: number, center: SingleCoordinate): number;
589
+ }
590
+
591
+ export declare const WGS84: WGS84CoordinateSystem;
592
+
593
+ declare class WGS84CoordinateSystem extends StandardCoordinateSystem {
594
+ constructor();
595
+ roundCoordinateValue(value: number): number;
596
+ /**
597
+ * Formula comes from
598
+ * https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale
599
+ *
600
+ * resolution = 156543.03 meters / pixel * cos(latitude) / (2 ^ zoom level)
601
+ */
602
+ getResolutionForZoomAndCenter(zoom: number, center: SingleCoordinate): number;
603
+ /**
604
+ * Ensures an extent is in X,Y order (longitude, latitude). If coordinates are in Y,X order
605
+ * (latitude, longitude), swaps them. WGS84 traditionally uses latitude-first (Y,X) axis order
606
+ * [minY, minX, maxY, maxX] Some WGS84 implementations may use X,Y order therefore we need to
607
+ * check and swap if needed.
608
+ *
609
+ * TODO: This method works for the common coordinates in and around switzerland but will not
610
+ * work for the whole world. Therefore a better solution should be implemented if we want to
611
+ * support coordinates and extents of the whole world.
612
+ *
613
+ * @param extent - Input extent [minX, minY, maxX, maxY] or [minY, minX, maxY, maxX]
614
+ * @returns Extent guaranteed to be in [minX, minY, maxX, maxY] order
615
+ * @link Problem description https://docs.geotools.org/latest/userguide/library/referencing/order.html
616
+ */
617
+ getExtentInOrderXY(extent: [number, number, number, number]): [number, number, number, number];
618
+ /**
619
+ * Calculating zoom level by reversing formula from
620
+ * https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale :
621
+ *
622
+ * resolution = 156543.03 * cos(latitude) / (2 ^ zoom level)
623
+ *
624
+ * So that
625
+ *
626
+ * zoom level = log2( resolution / 156543.03 / cos(latitude) )
627
+ *
628
+ * @param resolution Resolution in meter/pixel
629
+ * @param center As the use an equatorial constant to calculate the zoom level, we need to know
630
+ * the latitude of the position the resolution must be calculated at, as we need to take into
631
+ * account the deformation of the WebMercator projection (that is greater the further north we
632
+ * are)
633
+ */
634
+ getZoomForResolutionAndCenter(resolution: number, center: SingleCoordinate): number;
635
+ }
636
+
637
+ /**
638
+ * Wraps the provided coordinates in the world extents (i.e. the coordinate range that if equivalent
639
+ * to the wgs84 [-180, 180])
640
+ *
641
+ * @param coordinates The coordinates (or array of coordinates) to wrap
642
+ * @param projection Projection of the coordinates
643
+ * @returns Coordinates wrapped on the X axis
644
+ */
645
+ declare function wrapXCoordinates<T extends SingleCoordinate | SingleCoordinate[]>(coordinates: T, projection: CoordinateSystem): T;
646
+
647
+ export { }