ol 10.2.2-dev.1730888074380 → 10.2.2-dev.1730916385053

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/proj/utm.js ADDED
@@ -0,0 +1,292 @@
1
+ /**
2
+ * @module ol/proj/utm
3
+ */
4
+
5
+ /**
6
+ * Adapted from https://github.com/Turbo87/utm
7
+ * Copyright (c) 2012-2017 Tobias Bieniek
8
+ *
9
+ * The functions here provide approximate transforms to and from UTM.
10
+ * They are not appropriate for use beyond the validity extend of a UTM
11
+ * zone, and the accuracy of the transform decreases toward the zone
12
+ * edges.
13
+ */
14
+
15
+ import Projection from './Projection.js';
16
+ import {toDegrees, toRadians, wrap} from '../math.js';
17
+
18
+ /**
19
+ * @typedef {Object} UTMZone
20
+ * @property {number} number The zone number (1 - 60).
21
+ * @property {boolean} north The northern hemisphere.
22
+ */
23
+
24
+ const K0 = 0.9996;
25
+
26
+ const E = 0.00669438;
27
+ const E2 = E * E;
28
+ const E3 = E2 * E;
29
+ const E_P2 = E / (1 - E);
30
+
31
+ const SQRT_E = Math.sqrt(1 - E);
32
+ const _E = (1 - SQRT_E) / (1 + SQRT_E);
33
+ const _E2 = _E * _E;
34
+ const _E3 = _E2 * _E;
35
+ const _E4 = _E3 * _E;
36
+ const _E5 = _E4 * _E;
37
+
38
+ const M1 = 1 - E / 4 - (3 * E2) / 64 - (5 * E3) / 256;
39
+ const M2 = (3 * E) / 8 + (3 * E2) / 32 + (45 * E3) / 1024;
40
+ const M3 = (15 * E2) / 256 + (45 * E3) / 1024;
41
+ const M4 = (35 * E3) / 3072;
42
+
43
+ const P2 = (3 / 2) * _E - (27 / 32) * _E3 + (269 / 512) * _E5;
44
+ const P3 = (21 / 16) * _E2 - (55 / 32) * _E4;
45
+ const P4 = (151 / 96) * _E3 - (417 / 128) * _E5;
46
+ const P5 = (1097 / 512) * _E4;
47
+
48
+ const R = 6378137;
49
+
50
+ /**
51
+ * @param {number} easting Easting value of coordinate.
52
+ * @param {number} northing Northing value of coordinate.
53
+ * @param {UTMZone} zone The UTM zone.
54
+ * @return {import("../coordinate.js").Coordinate} The transformed coordinate.
55
+ */
56
+ function toLonLat(easting, northing, zone) {
57
+ const x = easting - 500000;
58
+ const y = zone.north ? northing : northing - 10000000;
59
+
60
+ const m = y / K0;
61
+ const mu = m / (R * M1);
62
+
63
+ const pRad =
64
+ mu +
65
+ P2 * Math.sin(2 * mu) +
66
+ P3 * Math.sin(4 * mu) +
67
+ P4 * Math.sin(6 * mu) +
68
+ P5 * Math.sin(8 * mu);
69
+
70
+ const pSin = Math.sin(pRad);
71
+ const pSin2 = pSin * pSin;
72
+
73
+ const pCos = Math.cos(pRad);
74
+
75
+ const pTan = pSin / pCos;
76
+ const pTan2 = pTan * pTan;
77
+ const pTan4 = pTan2 * pTan2;
78
+
79
+ const epSin = 1 - E * pSin2;
80
+ const epSinSqrt = Math.sqrt(1 - E * pSin2);
81
+
82
+ const n = R / epSinSqrt;
83
+ const r = (1 - E) / epSin;
84
+
85
+ const c = E_P2 * pCos ** 2;
86
+ const c2 = c * c;
87
+
88
+ const d = x / (n * K0);
89
+ const d2 = d * d;
90
+ const d3 = d2 * d;
91
+ const d4 = d3 * d;
92
+ const d5 = d4 * d;
93
+ const d6 = d5 * d;
94
+
95
+ const latitude =
96
+ pRad -
97
+ (pTan / r) *
98
+ (d2 / 2 - (d4 / 24) * (5 + 3 * pTan2 + 10 * c - 4 * c2 - 9 * E_P2)) +
99
+ (d6 / 720) * (61 + 90 * pTan2 + 298 * c + 45 * pTan4 - 252 * E_P2 - 3 * c2);
100
+
101
+ let longitude =
102
+ (d -
103
+ (d3 / 6) * (1 + 2 * pTan2 + c) +
104
+ (d5 / 120) * (5 - 2 * c + 28 * pTan2 - 3 * c2 + 8 * E_P2 + 24 * pTan4)) /
105
+ pCos;
106
+
107
+ longitude = wrap(
108
+ longitude + toRadians(zoneToCentralLongitude(zone.number)),
109
+ -Math.PI,
110
+ Math.PI,
111
+ );
112
+
113
+ return [toDegrees(longitude), toDegrees(latitude)];
114
+ }
115
+
116
+ const MIN_LATITUDE = -80;
117
+ const MAX_LATITUDE = 84;
118
+ const MIN_LONGITUDE = -180;
119
+ const MAX_LONGITUDE = 180;
120
+
121
+ /**
122
+ * @param {number} longitude The longitude.
123
+ * @param {number} latitude The latitude.
124
+ * @param {UTMZone} zone The UTM zone.
125
+ * @return {import('../coordinate.js').Coordinate} The UTM coordinate.
126
+ */
127
+ function fromLonLat(longitude, latitude, zone) {
128
+ longitude = wrap(longitude, MIN_LONGITUDE, MAX_LONGITUDE);
129
+
130
+ if (latitude < MIN_LATITUDE) {
131
+ latitude = MIN_LATITUDE;
132
+ } else if (latitude > MAX_LATITUDE) {
133
+ latitude = MAX_LATITUDE;
134
+ }
135
+
136
+ const latRad = toRadians(latitude);
137
+ const latSin = Math.sin(latRad);
138
+ const latCos = Math.cos(latRad);
139
+
140
+ const latTan = latSin / latCos;
141
+ const latTan2 = latTan * latTan;
142
+ const latTan4 = latTan2 * latTan2;
143
+
144
+ const lonRad = toRadians(longitude);
145
+ const centralLon = zoneToCentralLongitude(zone.number);
146
+ const centralLonRad = toRadians(centralLon);
147
+
148
+ const n = R / Math.sqrt(1 - E * latSin ** 2);
149
+ const c = E_P2 * latCos ** 2;
150
+
151
+ const a = latCos * wrap(lonRad - centralLonRad, -Math.PI, Math.PI);
152
+ const a2 = a * a;
153
+ const a3 = a2 * a;
154
+ const a4 = a3 * a;
155
+ const a5 = a4 * a;
156
+ const a6 = a5 * a;
157
+
158
+ const m =
159
+ R *
160
+ (M1 * latRad -
161
+ M2 * Math.sin(2 * latRad) +
162
+ M3 * Math.sin(4 * latRad) -
163
+ M4 * Math.sin(6 * latRad));
164
+
165
+ const easting =
166
+ K0 *
167
+ n *
168
+ (a +
169
+ (a3 / 6) * (1 - latTan2 + c) +
170
+ (a5 / 120) * (5 - 18 * latTan2 + latTan4 + 72 * c - 58 * E_P2)) +
171
+ 500000;
172
+
173
+ let northing =
174
+ K0 *
175
+ (m +
176
+ n *
177
+ latTan *
178
+ (a2 / 2 +
179
+ (a4 / 24) * (5 - latTan2 + 9 * c + 4 * c ** 2) +
180
+ (a6 / 720) * (61 - 58 * latTan2 + latTan4 + 600 * c - 330 * E_P2)));
181
+
182
+ if (!zone.north) {
183
+ northing += 10000000;
184
+ }
185
+
186
+ return [easting, northing];
187
+ }
188
+
189
+ /**
190
+ * @param {number} zone The zone number.
191
+ * @return {number} The central longitude in degrees.
192
+ */
193
+ function zoneToCentralLongitude(zone) {
194
+ return (zone - 1) * 6 - 180 + 3;
195
+ }
196
+
197
+ /**
198
+ * @type {Array<RegExp>}
199
+ */
200
+ const epsgRegExes = [
201
+ /^EPSG:(\d+)$/,
202
+ /^urn:ogc:def:crs:EPSG::(\d+)$/,
203
+ /^http:\/\/www\.opengis\.net\/def\/crs\/EPSG\/0\/(\d+)$/,
204
+ ];
205
+
206
+ /**
207
+ * @param {string} code The projection code.
208
+ * @return {UTMZone|null} The UTM zone info (or null if not UTM).
209
+ */
210
+ export function zoneFromCode(code) {
211
+ let epsgId = 0;
212
+ for (const re of epsgRegExes) {
213
+ const match = code.match(re);
214
+ if (match) {
215
+ epsgId = parseInt(match[1]);
216
+ break;
217
+ }
218
+ }
219
+ if (!epsgId) {
220
+ return null;
221
+ }
222
+
223
+ let number = 0;
224
+ let north = false;
225
+ if (epsgId > 32700 && epsgId < 32761) {
226
+ number = epsgId - 32700;
227
+ } else if (epsgId > 32600 && epsgId < 32661) {
228
+ north = true;
229
+ number = epsgId - 32600;
230
+ }
231
+ if (!number) {
232
+ return null;
233
+ }
234
+
235
+ return {number, north};
236
+ }
237
+
238
+ /**
239
+ * @param {function(number, number, UTMZone): import('../coordinate.js').Coordinate} transformer The transformer.
240
+ * @param {UTMZone} zone The UTM zone.
241
+ * @return {import('../proj.js').TransformFunction} The transform function.
242
+ */
243
+ function makeTransformFunction(transformer, zone) {
244
+ return function (input, output, dimension, stride) {
245
+ const length = input.length;
246
+ dimension = dimension > 1 ? dimension : 2;
247
+ stride = stride ?? dimension;
248
+ if (!output) {
249
+ if (dimension > 2) {
250
+ output = input.slice();
251
+ } else {
252
+ output = new Array(length);
253
+ }
254
+ }
255
+ for (let i = 0; i < length; i += stride) {
256
+ const x = input[i];
257
+ const y = input[i + 1];
258
+ const coord = transformer(x, y, zone);
259
+ output[i] = coord[0];
260
+ output[i + 1] = coord[1];
261
+ }
262
+ return output;
263
+ };
264
+ }
265
+
266
+ /**
267
+ * @param {string} code The projection code.
268
+ * @return {import('./Projection.js').default|null} A projection or null if unable to create one.
269
+ */
270
+ export function makeProjection(code) {
271
+ const zone = zoneFromCode(code);
272
+ if (!zone) {
273
+ return null;
274
+ }
275
+ return new Projection({code, units: 'm'});
276
+ }
277
+
278
+ /**
279
+ * @param {import('./Projection.js').default} projection The projection.
280
+ * @return {import('../proj.js').Transforms|null} The transforms lookup or null if unable to handle projection.
281
+ */
282
+ export function makeTransforms(projection) {
283
+ const zone = zoneFromCode(projection.getCode());
284
+ if (!zone) {
285
+ return null;
286
+ }
287
+
288
+ return {
289
+ forward: makeTransformFunction(fromLonLat, zone),
290
+ inverse: makeTransformFunction(toLonLat, zone),
291
+ };
292
+ }
package/proj.d.ts CHANGED
@@ -156,12 +156,12 @@ export function equivalent(projection1: Projection, projection2: Projection): bo
156
156
  * Searches in the list of transform functions for the function for converting
157
157
  * coordinates from the source projection to the destination projection.
158
158
  *
159
- * @param {Projection} sourceProjection Source Projection object.
160
- * @param {Projection} destinationProjection Destination Projection
159
+ * @param {Projection} source Source Projection object.
160
+ * @param {Projection} destination Destination Projection
161
161
  * object.
162
- * @return {TransformFunction} Transform function.
162
+ * @return {TransformFunction|null} Transform function.
163
163
  */
164
- export function getTransformFromProjections(sourceProjection: Projection, destinationProjection: Projection): TransformFunction;
164
+ export function getTransformFromProjections(source: Projection, destination: Projection): TransformFunction | null;
165
165
  /**
166
166
  * Given the projection-like objects, searches for a transformation
167
167
  * function to convert a coordinates array from the source projection to the
@@ -175,7 +175,9 @@ export function getTransformFromProjections(sourceProjection: Projection, destin
175
175
  export function getTransform(source: ProjectionLike, destination: ProjectionLike): TransformFunction;
176
176
  /**
177
177
  * Transforms a coordinate from source projection to destination projection.
178
- * This returns a new coordinate (and does not modify the original).
178
+ * This returns a new coordinate (and does not modify the original). If there
179
+ * is no available transform between the two projection, the function will throw
180
+ * an error.
179
181
  *
180
182
  * See {@link module:ol/proj.transformExtent} for extent transformation.
181
183
  * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its
@@ -308,6 +310,16 @@ export function addCommon(): void;
308
310
  * string or undefined.
309
311
  */
310
312
  export type ProjectionLike = Projection | string | undefined;
313
+ export type Transforms = {
314
+ /**
315
+ * The forward transform (from geographic).
316
+ */
317
+ forward: TransformFunction;
318
+ /**
319
+ * The inverse transform (to geographic).
320
+ */
321
+ inverse: TransformFunction;
322
+ };
311
323
  /**
312
324
  * A transform function accepts an array of input coordinate values, an optional
313
325
  * output array, and an optional dimension (default should be 2). The function
package/proj.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"proj.d.ts","sourceRoot":"","sources":["proj.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"proj.d.ts","sourceRoot":"","sources":["proj.js"],"names":[],"mappings":"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"}
package/proj.js CHANGED
@@ -75,6 +75,10 @@ import {applyTransform, getWidth} from './extent.js';
75
75
  import {clamp, modulo} from './math.js';
76
76
  import {equals, getWorldsAway} from './coordinate.js';
77
77
  import {getDistance} from './sphere.js';
78
+ import {
79
+ makeProjection as makeUTMProjection,
80
+ makeTransforms as makeUTMTransforms,
81
+ } from './proj/utm.js';
78
82
  import {warn} from './console.js';
79
83
 
80
84
  /**
@@ -84,6 +88,22 @@ import {warn} from './console.js';
84
88
  * @api
85
89
  */
86
90
 
91
+ /**
92
+ * @typedef {Object} Transforms
93
+ * @property {TransformFunction} forward The forward transform (from geographic).
94
+ * @property {TransformFunction} inverse The inverse transform (to geographic).
95
+ */
96
+
97
+ /**
98
+ * @type {Array<function(Projection): Transforms|null>}
99
+ */
100
+ const transformFactories = [makeUTMTransforms];
101
+
102
+ /**
103
+ * @type {Array<function(string): Projection|null>}
104
+ */
105
+ const projectionFactories = [makeUTMProjection];
106
+
87
107
  /**
88
108
  * A transform function accepts an array of input coordinate values, an optional
89
109
  * output array, and an optional dimension (default should be 2). The function
@@ -176,9 +196,20 @@ export function addProjections(projections) {
176
196
  * @api
177
197
  */
178
198
  export function get(projectionLike) {
179
- return typeof projectionLike === 'string'
180
- ? getProj(/** @type {string} */ (projectionLike))
181
- : /** @type {Projection} */ (projectionLike) || null;
199
+ if (!(typeof projectionLike === 'string')) {
200
+ return projectionLike;
201
+ }
202
+ const projection = getProj(projectionLike);
203
+ if (projection) {
204
+ return projection;
205
+ }
206
+ for (const makeProjection of projectionFactories) {
207
+ const projection = makeProjection(projectionLike);
208
+ if (projection) {
209
+ return projection;
210
+ }
211
+ }
212
+ return null;
182
213
  }
183
214
 
184
215
  /**
@@ -226,7 +257,7 @@ export function getPointResolution(projection, resolution, point, units) {
226
257
  projection,
227
258
  get('EPSG:4326'),
228
259
  );
229
- if (toEPSG4326 === identityTransform && projUnits !== 'degrees') {
260
+ if (!toEPSG4326 && projUnits !== 'degrees') {
230
261
  // no transform is available
231
262
  pointResolution = resolution * projection.getMetersPerUnit();
232
263
  } else {
@@ -460,24 +491,88 @@ export function equivalent(projection1, projection2) {
460
491
  * Searches in the list of transform functions for the function for converting
461
492
  * coordinates from the source projection to the destination projection.
462
493
  *
463
- * @param {Projection} sourceProjection Source Projection object.
464
- * @param {Projection} destinationProjection Destination Projection
494
+ * @param {Projection} source Source Projection object.
495
+ * @param {Projection} destination Destination Projection
465
496
  * object.
466
- * @return {TransformFunction} Transform function.
497
+ * @return {TransformFunction|null} Transform function.
467
498
  */
468
- export function getTransformFromProjections(
469
- sourceProjection,
470
- destinationProjection,
471
- ) {
472
- const sourceCode = sourceProjection.getCode();
473
- const destinationCode = destinationProjection.getCode();
499
+ export function getTransformFromProjections(source, destination) {
500
+ const sourceCode = source.getCode();
501
+ const destinationCode = destination.getCode();
474
502
  let transformFunc = getTransformFunc(sourceCode, destinationCode);
475
- if (!transformFunc) {
476
- transformFunc = identityTransform;
503
+ if (transformFunc) {
504
+ return transformFunc;
505
+ }
506
+
507
+ /**
508
+ * @type {Transforms|null}
509
+ */
510
+ let sourceTransforms = null;
511
+
512
+ /**
513
+ * @type {Transforms|null}
514
+ */
515
+ let destinationTransforms = null;
516
+
517
+ // lazily add projections if we have supported transforms
518
+ for (const makeTransforms of transformFactories) {
519
+ if (!sourceTransforms) {
520
+ sourceTransforms = makeTransforms(source);
521
+ }
522
+ if (!destinationTransforms) {
523
+ destinationTransforms = makeTransforms(destination);
524
+ }
525
+ }
526
+
527
+ if (!sourceTransforms && !destinationTransforms) {
528
+ return null;
529
+ }
530
+
531
+ const intermediateCode = 'EPSG:4326';
532
+ if (!destinationTransforms) {
533
+ const toDestination = getTransformFunc(intermediateCode, destinationCode);
534
+ if (toDestination) {
535
+ transformFunc = composeTransformFuncs(
536
+ sourceTransforms.inverse,
537
+ toDestination,
538
+ );
539
+ }
540
+ } else if (!sourceTransforms) {
541
+ const fromSource = getTransformFunc(sourceCode, intermediateCode);
542
+ if (fromSource) {
543
+ transformFunc = composeTransformFuncs(
544
+ fromSource,
545
+ destinationTransforms.forward,
546
+ );
547
+ }
548
+ } else {
549
+ transformFunc = composeTransformFuncs(
550
+ sourceTransforms.inverse,
551
+ destinationTransforms.forward,
552
+ );
553
+ }
554
+
555
+ if (transformFunc) {
556
+ addProjection(source);
557
+ addProjection(destination);
558
+ addTransformFunc(source, destination, transformFunc);
477
559
  }
560
+
478
561
  return transformFunc;
479
562
  }
480
563
 
564
+ /**
565
+ * @param {TransformFunction} t1 The first transform function.
566
+ * @param {TransformFunction} t2 The second transform function.
567
+ * @return {TransformFunction} The composed transform function.
568
+ */
569
+ function composeTransformFuncs(t1, t2) {
570
+ return function (input, output, dimensions, stride) {
571
+ output = t1(input, output, dimensions, stride);
572
+ return t2(output, output, dimensions, stride);
573
+ };
574
+ }
575
+
481
576
  /**
482
577
  * Given the projection-like objects, searches for a transformation
483
578
  * function to convert a coordinates array from the source projection to the
@@ -496,7 +591,9 @@ export function getTransform(source, destination) {
496
591
 
497
592
  /**
498
593
  * Transforms a coordinate from source projection to destination projection.
499
- * This returns a new coordinate (and does not modify the original).
594
+ * This returns a new coordinate (and does not modify the original). If there
595
+ * is no available transform between the two projection, the function will throw
596
+ * an error.
500
597
  *
501
598
  * See {@link module:ol/proj.transformExtent} for extent transformation.
502
599
  * See the transform method of {@link module:ol/geom/Geometry~Geometry} and its
@@ -510,6 +607,13 @@ export function getTransform(source, destination) {
510
607
  */
511
608
  export function transform(coordinate, source, destination) {
512
609
  const transformFunc = getTransform(source, destination);
610
+ if (!transformFunc) {
611
+ const sourceCode = get(source).getCode();
612
+ const destinationCode = get(destination).getCode();
613
+ throw new Error(
614
+ `No transform available between ${sourceCode} and ${destinationCode}`,
615
+ );
616
+ }
513
617
  return transformFunc(coordinate, undefined, coordinate.length);
514
618
  }
515
619
 
package/util.js CHANGED
@@ -33,4 +33,4 @@ export function getUid(obj) {
33
33
  * OpenLayers version.
34
34
  * @type {string}
35
35
  */
36
- export const VERSION = '10.2.2-dev.1730888074380';
36
+ export const VERSION = '10.2.2-dev.1730916385053';