proj4 2.20.2 → 2.20.3
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/bower.json +1 -1
- package/component.json +1 -1
- package/dist/proj4-src.js +133 -119
- package/dist/proj4.js +1 -1
- package/lib/parseCode.js +3 -0
- package/lib/projections/ortho.js +16 -13
- package/package.json +2 -2
package/bower.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "proj4",
|
|
3
|
-
"version": "2.20.
|
|
3
|
+
"version": "2.20.3",
|
|
4
4
|
"description": "Proj4js is a JavaScript library to transform point coordinates from one coordinate system to another, including datum transformations.",
|
|
5
5
|
"homepage": "https://github.com/proj4js/proj4js",
|
|
6
6
|
"main": "dist/proj4.js",
|
package/component.json
CHANGED
package/dist/proj4-src.js
CHANGED
|
@@ -259,7 +259,7 @@
|
|
|
259
259
|
|
|
260
260
|
class PROJJSONBuilderBase {
|
|
261
261
|
static getId(node) {
|
|
262
|
-
const idNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
262
|
+
const idNode = node.find((child) => Array.isArray(child) && child[0] === 'ID');
|
|
263
263
|
if (idNode && idNode.length >= 3) {
|
|
264
264
|
return {
|
|
265
265
|
authority: idNode[1],
|
|
@@ -269,20 +269,20 @@
|
|
|
269
269
|
return null;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
static convertUnit(node, type =
|
|
272
|
+
static convertUnit(node, type = 'unit') {
|
|
273
273
|
if (!node || node.length < 3) {
|
|
274
|
-
return { type, name:
|
|
274
|
+
return { type, name: 'unknown', conversion_factor: null };
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
const name = node[1];
|
|
278
278
|
const conversionFactor = parseFloat(node[2]) || null;
|
|
279
279
|
|
|
280
|
-
const idNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
280
|
+
const idNode = node.find((child) => Array.isArray(child) && child[0] === 'ID');
|
|
281
281
|
const id = idNode
|
|
282
282
|
? {
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
authority: idNode[1],
|
|
284
|
+
code: parseInt(idNode[2], 10),
|
|
285
|
+
}
|
|
286
286
|
: null;
|
|
287
287
|
|
|
288
288
|
return {
|
|
@@ -294,7 +294,7 @@
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
static convertAxis(node) {
|
|
297
|
-
const name = node[1] ||
|
|
297
|
+
const name = node[1] || 'Unknown';
|
|
298
298
|
|
|
299
299
|
// Determine the direction
|
|
300
300
|
let direction;
|
|
@@ -308,16 +308,16 @@
|
|
|
308
308
|
else throw new Error(`Unknown axis abbreviation: ${abbreviation}`);
|
|
309
309
|
} else {
|
|
310
310
|
// Use the explicit direction provided in the AXIS node
|
|
311
|
-
direction = node[2]
|
|
311
|
+
direction = node[2] ? node[2].toLowerCase() : 'unknown';
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
const orderNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
314
|
+
const orderNode = node.find((child) => Array.isArray(child) && child[0] === 'ORDER');
|
|
315
315
|
const order = orderNode ? parseInt(orderNode[1], 10) : null;
|
|
316
316
|
|
|
317
317
|
const unitNode = node.find(
|
|
318
318
|
(child) =>
|
|
319
319
|
Array.isArray(child) &&
|
|
320
|
-
(child[0] ===
|
|
320
|
+
(child[0] === 'LENGTHUNIT' || child[0] === 'ANGLEUNIT' || child[0] === 'SCALEUNIT')
|
|
321
321
|
);
|
|
322
322
|
const unit = this.convertUnit(unitNode);
|
|
323
323
|
|
|
@@ -331,7 +331,7 @@
|
|
|
331
331
|
|
|
332
332
|
static extractAxes(node) {
|
|
333
333
|
return node
|
|
334
|
-
.filter((child) => Array.isArray(child) && child[0] ===
|
|
334
|
+
.filter((child) => Array.isArray(child) && child[0] === 'AXIS')
|
|
335
335
|
.map((axis) => this.convertAxis(axis))
|
|
336
336
|
.sort((a, b) => (a.order || 0) - (b.order || 0)); // Sort by the "order" property
|
|
337
337
|
}
|
|
@@ -339,17 +339,17 @@
|
|
|
339
339
|
static convert(node, result = {}) {
|
|
340
340
|
|
|
341
341
|
switch (node[0]) {
|
|
342
|
-
case
|
|
343
|
-
result.type =
|
|
342
|
+
case 'PROJCRS':
|
|
343
|
+
result.type = 'ProjectedCRS';
|
|
344
344
|
result.name = node[1];
|
|
345
|
-
result.base_crs = node.find((child) => Array.isArray(child) && child[0] ===
|
|
346
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
345
|
+
result.base_crs = node.find((child) => Array.isArray(child) && child[0] === 'BASEGEOGCRS')
|
|
346
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'BASEGEOGCRS'))
|
|
347
347
|
: null;
|
|
348
|
-
result.conversion = node.find((child) => Array.isArray(child) && child[0] ===
|
|
349
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
348
|
+
result.conversion = node.find((child) => Array.isArray(child) && child[0] === 'CONVERSION')
|
|
349
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'CONVERSION'))
|
|
350
350
|
: null;
|
|
351
351
|
|
|
352
|
-
const csNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
352
|
+
const csNode = node.find((child) => Array.isArray(child) && child[0] === 'CS');
|
|
353
353
|
if (csNode) {
|
|
354
354
|
result.coordinate_system = {
|
|
355
355
|
type: csNode[1],
|
|
@@ -357,7 +357,7 @@
|
|
|
357
357
|
};
|
|
358
358
|
}
|
|
359
359
|
|
|
360
|
-
const lengthUnitNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
360
|
+
const lengthUnitNode = node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT');
|
|
361
361
|
if (lengthUnitNode) {
|
|
362
362
|
const unit = this.convertUnit(lengthUnitNode);
|
|
363
363
|
result.coordinate_system.unit = unit; // Add unit to coordinate_system
|
|
@@ -366,23 +366,23 @@
|
|
|
366
366
|
result.id = this.getId(node);
|
|
367
367
|
break;
|
|
368
368
|
|
|
369
|
-
case
|
|
370
|
-
case
|
|
371
|
-
result.type =
|
|
369
|
+
case 'BASEGEOGCRS':
|
|
370
|
+
case 'GEOGCRS':
|
|
371
|
+
result.type = 'GeographicCRS';
|
|
372
372
|
result.name = node[1];
|
|
373
373
|
|
|
374
374
|
// Handle DATUM or ENSEMBLE
|
|
375
375
|
const datumOrEnsembleNode = node.find(
|
|
376
|
-
(child) => Array.isArray(child) && (child[0] ===
|
|
376
|
+
(child) => Array.isArray(child) && (child[0] === 'DATUM' || child[0] === 'ENSEMBLE')
|
|
377
377
|
);
|
|
378
378
|
if (datumOrEnsembleNode) {
|
|
379
379
|
const datumOrEnsemble = this.convert(datumOrEnsembleNode);
|
|
380
|
-
if (datumOrEnsembleNode[0] ===
|
|
380
|
+
if (datumOrEnsembleNode[0] === 'ENSEMBLE') {
|
|
381
381
|
result.datum_ensemble = datumOrEnsemble;
|
|
382
382
|
} else {
|
|
383
383
|
result.datum = datumOrEnsemble;
|
|
384
384
|
}
|
|
385
|
-
const primem = node.find((child) => Array.isArray(child) && child[0] ===
|
|
385
|
+
const primem = node.find((child) => Array.isArray(child) && child[0] === 'PRIMEM');
|
|
386
386
|
if (primem && primem[1] !== 'Greenwich') {
|
|
387
387
|
datumOrEnsemble.prime_meridian = {
|
|
388
388
|
name: primem[1],
|
|
@@ -392,42 +392,42 @@
|
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
result.coordinate_system = {
|
|
395
|
-
type:
|
|
395
|
+
type: 'ellipsoidal',
|
|
396
396
|
axis: this.extractAxes(node),
|
|
397
397
|
};
|
|
398
398
|
|
|
399
399
|
result.id = this.getId(node);
|
|
400
400
|
break;
|
|
401
401
|
|
|
402
|
-
case
|
|
403
|
-
result.type =
|
|
402
|
+
case 'DATUM':
|
|
403
|
+
result.type = 'GeodeticReferenceFrame';
|
|
404
404
|
result.name = node[1];
|
|
405
|
-
result.ellipsoid = node.find((child) => Array.isArray(child) && child[0] ===
|
|
406
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
405
|
+
result.ellipsoid = node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID')
|
|
406
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID'))
|
|
407
407
|
: null;
|
|
408
408
|
break;
|
|
409
409
|
|
|
410
|
-
case
|
|
411
|
-
result.type =
|
|
410
|
+
case 'ENSEMBLE':
|
|
411
|
+
result.type = 'DatumEnsemble';
|
|
412
412
|
result.name = node[1];
|
|
413
413
|
|
|
414
414
|
// Extract ensemble members
|
|
415
415
|
result.members = node
|
|
416
|
-
.filter((child) => Array.isArray(child) && child[0] ===
|
|
416
|
+
.filter((child) => Array.isArray(child) && child[0] === 'MEMBER')
|
|
417
417
|
.map((member) => ({
|
|
418
|
-
type:
|
|
418
|
+
type: 'DatumEnsembleMember',
|
|
419
419
|
name: member[1],
|
|
420
420
|
id: this.getId(member), // Extract ID as { authority, code }
|
|
421
421
|
}));
|
|
422
422
|
|
|
423
423
|
// Extract accuracy
|
|
424
|
-
const accuracyNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
424
|
+
const accuracyNode = node.find((child) => Array.isArray(child) && child[0] === 'ENSEMBLEACCURACY');
|
|
425
425
|
if (accuracyNode) {
|
|
426
426
|
result.accuracy = parseFloat(accuracyNode[1]);
|
|
427
427
|
}
|
|
428
428
|
|
|
429
429
|
// Extract ellipsoid
|
|
430
|
-
const ellipsoidNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
430
|
+
const ellipsoidNode = node.find((child) => Array.isArray(child) && child[0] === 'ELLIPSOID');
|
|
431
431
|
if (ellipsoidNode) {
|
|
432
432
|
result.ellipsoid = this.convert(ellipsoidNode); // Convert the ellipsoid node
|
|
433
433
|
}
|
|
@@ -436,66 +436,66 @@
|
|
|
436
436
|
result.id = this.getId(node);
|
|
437
437
|
break;
|
|
438
438
|
|
|
439
|
-
case
|
|
440
|
-
result.type =
|
|
439
|
+
case 'ELLIPSOID':
|
|
440
|
+
result.type = 'Ellipsoid';
|
|
441
441
|
result.name = node[1];
|
|
442
442
|
result.semi_major_axis = parseFloat(node[2]);
|
|
443
443
|
result.inverse_flattening = parseFloat(node[3]);
|
|
444
|
-
node.find((child) => Array.isArray(child) && child[0] ===
|
|
445
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
444
|
+
node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT')
|
|
445
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'LENGTHUNIT'), result)
|
|
446
446
|
: null;
|
|
447
447
|
break;
|
|
448
448
|
|
|
449
|
-
case
|
|
450
|
-
result.type =
|
|
449
|
+
case 'CONVERSION':
|
|
450
|
+
result.type = 'Conversion';
|
|
451
451
|
result.name = node[1];
|
|
452
|
-
result.method = node.find((child) => Array.isArray(child) && child[0] ===
|
|
453
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
452
|
+
result.method = node.find((child) => Array.isArray(child) && child[0] === 'METHOD')
|
|
453
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'METHOD'))
|
|
454
454
|
: null;
|
|
455
455
|
result.parameters = node
|
|
456
|
-
.filter((child) => Array.isArray(child) && child[0] ===
|
|
456
|
+
.filter((child) => Array.isArray(child) && child[0] === 'PARAMETER')
|
|
457
457
|
.map((param) => this.convert(param));
|
|
458
458
|
break;
|
|
459
459
|
|
|
460
|
-
case
|
|
461
|
-
result.type =
|
|
460
|
+
case 'METHOD':
|
|
461
|
+
result.type = 'Method';
|
|
462
462
|
result.name = node[1];
|
|
463
463
|
result.id = this.getId(node);
|
|
464
464
|
break;
|
|
465
465
|
|
|
466
|
-
case
|
|
467
|
-
result.type =
|
|
466
|
+
case 'PARAMETER':
|
|
467
|
+
result.type = 'Parameter';
|
|
468
468
|
result.name = node[1];
|
|
469
469
|
result.value = parseFloat(node[2]);
|
|
470
470
|
result.unit = this.convertUnit(
|
|
471
471
|
node.find(
|
|
472
472
|
(child) =>
|
|
473
473
|
Array.isArray(child) &&
|
|
474
|
-
(child[0] ===
|
|
474
|
+
(child[0] === 'LENGTHUNIT' || child[0] === 'ANGLEUNIT' || child[0] === 'SCALEUNIT')
|
|
475
475
|
)
|
|
476
476
|
);
|
|
477
477
|
result.id = this.getId(node);
|
|
478
478
|
break;
|
|
479
479
|
|
|
480
|
-
case
|
|
481
|
-
result.type =
|
|
480
|
+
case 'BOUNDCRS':
|
|
481
|
+
result.type = 'BoundCRS';
|
|
482
482
|
|
|
483
483
|
// Process SOURCECRS
|
|
484
|
-
const sourceCrsNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
484
|
+
const sourceCrsNode = node.find((child) => Array.isArray(child) && child[0] === 'SOURCECRS');
|
|
485
485
|
if (sourceCrsNode) {
|
|
486
486
|
const sourceCrsContent = sourceCrsNode.find((child) => Array.isArray(child));
|
|
487
487
|
result.source_crs = sourceCrsContent ? this.convert(sourceCrsContent) : null;
|
|
488
488
|
}
|
|
489
489
|
|
|
490
490
|
// Process TARGETCRS
|
|
491
|
-
const targetCrsNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
491
|
+
const targetCrsNode = node.find((child) => Array.isArray(child) && child[0] === 'TARGETCRS');
|
|
492
492
|
if (targetCrsNode) {
|
|
493
493
|
const targetCrsContent = targetCrsNode.find((child) => Array.isArray(child));
|
|
494
494
|
result.target_crs = targetCrsContent ? this.convert(targetCrsContent) : null;
|
|
495
495
|
}
|
|
496
496
|
|
|
497
497
|
// Process ABRIDGEDTRANSFORMATION
|
|
498
|
-
const transformationNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
498
|
+
const transformationNode = node.find((child) => Array.isArray(child) && child[0] === 'ABRIDGEDTRANSFORMATION');
|
|
499
499
|
if (transformationNode) {
|
|
500
500
|
result.transformation = this.convert(transformationNode);
|
|
501
501
|
} else {
|
|
@@ -503,25 +503,25 @@
|
|
|
503
503
|
}
|
|
504
504
|
break;
|
|
505
505
|
|
|
506
|
-
case
|
|
507
|
-
result.type =
|
|
506
|
+
case 'ABRIDGEDTRANSFORMATION':
|
|
507
|
+
result.type = 'Transformation';
|
|
508
508
|
result.name = node[1];
|
|
509
|
-
result.method = node.find((child) => Array.isArray(child) && child[0] ===
|
|
510
|
-
? this.convert(node.find((child) => Array.isArray(child) && child[0] ===
|
|
509
|
+
result.method = node.find((child) => Array.isArray(child) && child[0] === 'METHOD')
|
|
510
|
+
? this.convert(node.find((child) => Array.isArray(child) && child[0] === 'METHOD'))
|
|
511
511
|
: null;
|
|
512
512
|
|
|
513
513
|
result.parameters = node
|
|
514
|
-
.filter((child) => Array.isArray(child) && (child[0] ===
|
|
514
|
+
.filter((child) => Array.isArray(child) && (child[0] === 'PARAMETER' || child[0] === 'PARAMETERFILE'))
|
|
515
515
|
.map((param) => {
|
|
516
|
-
if (param[0] ===
|
|
516
|
+
if (param[0] === 'PARAMETER') {
|
|
517
517
|
return this.convert(param);
|
|
518
|
-
} else if (param[0] ===
|
|
518
|
+
} else if (param[0] === 'PARAMETERFILE') {
|
|
519
519
|
return {
|
|
520
520
|
name: param[1],
|
|
521
521
|
value: param[2],
|
|
522
522
|
id: {
|
|
523
|
-
|
|
524
|
-
|
|
523
|
+
'authority': 'EPSG',
|
|
524
|
+
'code': 8656
|
|
525
525
|
}
|
|
526
526
|
};
|
|
527
527
|
}
|
|
@@ -530,7 +530,7 @@
|
|
|
530
530
|
// Adjust the Scale difference parameter if present
|
|
531
531
|
if (result.parameters.length === 7) {
|
|
532
532
|
const scaleDifference = result.parameters[6];
|
|
533
|
-
if (scaleDifference.name ===
|
|
533
|
+
if (scaleDifference.name === 'Scale difference') {
|
|
534
534
|
scaleDifference.value = Math.round((scaleDifference.value - 1) * 1e12) / 1e6;
|
|
535
535
|
}
|
|
536
536
|
}
|
|
@@ -538,14 +538,14 @@
|
|
|
538
538
|
result.id = this.getId(node);
|
|
539
539
|
break;
|
|
540
540
|
|
|
541
|
-
case
|
|
541
|
+
case 'AXIS':
|
|
542
542
|
if (!result.coordinate_system) {
|
|
543
|
-
result.coordinate_system = { type:
|
|
543
|
+
result.coordinate_system = { type: 'unspecified', axis: [] };
|
|
544
544
|
}
|
|
545
545
|
result.coordinate_system.axis.push(this.convertAxis(node));
|
|
546
546
|
break;
|
|
547
547
|
|
|
548
|
-
case
|
|
548
|
+
case 'LENGTHUNIT':
|
|
549
549
|
const unit = this.convertUnit(node, 'LinearUnit');
|
|
550
550
|
if (result.coordinate_system && result.coordinate_system.axis) {
|
|
551
551
|
result.coordinate_system.axis.forEach((axis) => {
|
|
@@ -578,7 +578,7 @@
|
|
|
578
578
|
super.convert(node, result);
|
|
579
579
|
|
|
580
580
|
// Skip `CS` and `USAGE` nodes for WKT2-2015
|
|
581
|
-
if (result.coordinate_system
|
|
581
|
+
if (result.coordinate_system && result.coordinate_system.subtype === 'Cartesian') {
|
|
582
582
|
delete result.coordinate_system;
|
|
583
583
|
}
|
|
584
584
|
if (result.usage) {
|
|
@@ -594,7 +594,7 @@
|
|
|
594
594
|
super.convert(node, result);
|
|
595
595
|
|
|
596
596
|
// Handle `CS` node for WKT2-2019
|
|
597
|
-
const csNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
597
|
+
const csNode = node.find((child) => Array.isArray(child) && child[0] === 'CS');
|
|
598
598
|
if (csNode) {
|
|
599
599
|
result.coordinate_system = {
|
|
600
600
|
subtype: csNode[1],
|
|
@@ -603,13 +603,21 @@
|
|
|
603
603
|
}
|
|
604
604
|
|
|
605
605
|
// Handle `USAGE` node for WKT2-2019
|
|
606
|
-
const usageNode = node.find((child) => Array.isArray(child) && child[0] ===
|
|
606
|
+
const usageNode = node.find((child) => Array.isArray(child) && child[0] === 'USAGE');
|
|
607
607
|
if (usageNode) {
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
608
|
+
const scope = usageNode.find((child) => Array.isArray(child) && child[0] === 'SCOPE');
|
|
609
|
+
const area = usageNode.find((child) => Array.isArray(child) && child[0] === 'AREA');
|
|
610
|
+
const bbox = usageNode.find((child) => Array.isArray(child) && child[0] === 'BBOX');
|
|
611
|
+
result.usage = {};
|
|
612
|
+
if (scope) {
|
|
613
|
+
result.usage.scope = scope[1];
|
|
614
|
+
}
|
|
615
|
+
if (area) {
|
|
616
|
+
result.usage.area = area[1];
|
|
617
|
+
}
|
|
618
|
+
if (bbox) {
|
|
619
|
+
result.usage.bbox = bbox.slice(1);
|
|
620
|
+
}
|
|
613
621
|
}
|
|
614
622
|
|
|
615
623
|
return result;
|
|
@@ -623,21 +631,21 @@
|
|
|
623
631
|
*/
|
|
624
632
|
function detectWKT2Version(root) {
|
|
625
633
|
// Check for WKT2-2019-specific nodes
|
|
626
|
-
if (root.find((child) => Array.isArray(child) && child[0] ===
|
|
627
|
-
return
|
|
634
|
+
if (root.find((child) => Array.isArray(child) && child[0] === 'USAGE')) {
|
|
635
|
+
return '2019'; // `USAGE` is specific to WKT2-2019
|
|
628
636
|
}
|
|
629
637
|
|
|
630
638
|
// Check for WKT2-2015-specific nodes
|
|
631
|
-
if (root.find((child) => Array.isArray(child) && child[0] ===
|
|
632
|
-
return
|
|
639
|
+
if (root.find((child) => Array.isArray(child) && child[0] === 'CS')) {
|
|
640
|
+
return '2015'; // `CS` is valid in both, but default to 2015 unless `USAGE` is present
|
|
633
641
|
}
|
|
634
642
|
|
|
635
|
-
if (root[0] ===
|
|
636
|
-
return
|
|
643
|
+
if (root[0] === 'BOUNDCRS' || root[0] === 'PROJCRS' || root[0] === 'GEOGCRS') {
|
|
644
|
+
return '2015'; // These are valid in both, but default to 2015
|
|
637
645
|
}
|
|
638
646
|
|
|
639
647
|
// Default to WKT2-2015 if no specific indicators are found
|
|
640
|
-
return
|
|
648
|
+
return '2015';
|
|
641
649
|
}
|
|
642
650
|
|
|
643
651
|
/**
|
|
@@ -647,7 +655,7 @@
|
|
|
647
655
|
*/
|
|
648
656
|
function buildPROJJSON(root) {
|
|
649
657
|
const version = detectWKT2Version(root);
|
|
650
|
-
const builder = version ===
|
|
658
|
+
const builder = version === '2019' ? PROJJSONBuilder2019 : PROJJSONBuilder2015;
|
|
651
659
|
return builder.convert(root);
|
|
652
660
|
}
|
|
653
661
|
|
|
@@ -662,30 +670,30 @@
|
|
|
662
670
|
|
|
663
671
|
// Check for WKT2-specific keywords
|
|
664
672
|
if (
|
|
665
|
-
normalizedWKT.includes(
|
|
666
|
-
normalizedWKT.includes(
|
|
667
|
-
normalizedWKT.includes(
|
|
668
|
-
normalizedWKT.includes(
|
|
669
|
-
normalizedWKT.includes(
|
|
670
|
-
normalizedWKT.includes(
|
|
671
|
-
normalizedWKT.includes(
|
|
673
|
+
normalizedWKT.includes('PROJCRS') ||
|
|
674
|
+
normalizedWKT.includes('GEOGCRS') ||
|
|
675
|
+
normalizedWKT.includes('BOUNDCRS') ||
|
|
676
|
+
normalizedWKT.includes('VERTCRS') ||
|
|
677
|
+
normalizedWKT.includes('LENGTHUNIT') ||
|
|
678
|
+
normalizedWKT.includes('ANGLEUNIT') ||
|
|
679
|
+
normalizedWKT.includes('SCALEUNIT')
|
|
672
680
|
) {
|
|
673
|
-
return
|
|
681
|
+
return 'WKT2';
|
|
674
682
|
}
|
|
675
683
|
|
|
676
684
|
// Check for WKT1-specific keywords
|
|
677
685
|
if (
|
|
678
|
-
normalizedWKT.includes(
|
|
679
|
-
normalizedWKT.includes(
|
|
680
|
-
normalizedWKT.includes(
|
|
681
|
-
normalizedWKT.includes(
|
|
682
|
-
normalizedWKT.includes(
|
|
686
|
+
normalizedWKT.includes('PROJCS') ||
|
|
687
|
+
normalizedWKT.includes('GEOGCS') ||
|
|
688
|
+
normalizedWKT.includes('LOCAL_CS') ||
|
|
689
|
+
normalizedWKT.includes('VERT_CS') ||
|
|
690
|
+
normalizedWKT.includes('UNIT')
|
|
683
691
|
) {
|
|
684
|
-
return
|
|
692
|
+
return 'WKT1';
|
|
685
693
|
}
|
|
686
694
|
|
|
687
695
|
// Default to WKT1 if no specific indicators are found
|
|
688
|
-
return
|
|
696
|
+
return 'WKT1';
|
|
689
697
|
}
|
|
690
698
|
|
|
691
699
|
var NEUTRAL = 1;
|
|
@@ -1010,7 +1018,7 @@
|
|
|
1010
1018
|
if (result.units === 'meter') {
|
|
1011
1019
|
result.to_meter = 1; // Only set to_meter if units are 'meter'
|
|
1012
1020
|
}
|
|
1013
|
-
} else if (unit
|
|
1021
|
+
} else if (unit && unit.name) {
|
|
1014
1022
|
result.units = unit.name.toLowerCase();
|
|
1015
1023
|
if (result.units === 'metre') {
|
|
1016
1024
|
result.units = 'meter'; // Normalize 'metre' to 'meter'
|
|
@@ -1051,7 +1059,7 @@
|
|
|
1051
1059
|
transformPROJJSON(projjson.source_crs, result);
|
|
1052
1060
|
|
|
1053
1061
|
if (projjson.transformation) {
|
|
1054
|
-
if (projjson.transformation.method
|
|
1062
|
+
if (projjson.transformation.method && projjson.transformation.method.name === 'NTv2') {
|
|
1055
1063
|
// Set nadgrids to the filename from the parameterfile
|
|
1056
1064
|
result.nadgrids = projjson.transformation.parameters[0].value;
|
|
1057
1065
|
} else {
|
|
@@ -1081,8 +1089,8 @@
|
|
|
1081
1089
|
case 'type':
|
|
1082
1090
|
if (value === 'GeographicCRS') {
|
|
1083
1091
|
result.projName = 'longlat';
|
|
1084
|
-
} else if (value === 'ProjectedCRS') {
|
|
1085
|
-
result.projName = projjson.conversion
|
|
1092
|
+
} else if (value === 'ProjectedCRS' && projjson.conversion && projjson.conversion.method) {
|
|
1093
|
+
result.projName = projjson.conversion.method.name; // Retain original capitalization
|
|
1086
1094
|
}
|
|
1087
1095
|
break;
|
|
1088
1096
|
|
|
@@ -1124,7 +1132,7 @@
|
|
|
1124
1132
|
const { units, to_meter } = processUnit(value.unit);
|
|
1125
1133
|
result.units = units;
|
|
1126
1134
|
result.to_meter = to_meter;
|
|
1127
|
-
} else if (value.axis[0]
|
|
1135
|
+
} else if (value.axis[0] && value.axis[0].unit) {
|
|
1128
1136
|
const { units, to_meter } = processUnit(value.axis[0].unit);
|
|
1129
1137
|
result.units = units;
|
|
1130
1138
|
result.to_meter = to_meter;
|
|
@@ -1590,6 +1598,9 @@
|
|
|
1590
1598
|
}
|
|
1591
1599
|
var codes = ['3857', '900913', '3785', '102113'];
|
|
1592
1600
|
function checkMercator(item) {
|
|
1601
|
+
if (item.title) {
|
|
1602
|
+
return item.title.toLowerCase().indexOf('epsg:') === 0 && codes.indexOf(item.title.substr(5)) > -1;
|
|
1603
|
+
}
|
|
1593
1604
|
var auth = match(item, 'authority');
|
|
1594
1605
|
if (!auth) {
|
|
1595
1606
|
return;
|
|
@@ -8910,8 +8921,8 @@
|
|
|
8910
8921
|
|
|
8911
8922
|
/* Place parameters in static storage for common use
|
|
8912
8923
|
------------------------------------------------- */
|
|
8913
|
-
this.sin_p14 = Math.sin(this.lat0);
|
|
8914
|
-
this.cos_p14 = Math.cos(this.lat0);
|
|
8924
|
+
this.sin_p14 = Math.sin(this.lat0 || 0);
|
|
8925
|
+
this.cos_p14 = Math.cos(this.lat0 || 0);
|
|
8915
8926
|
}
|
|
8916
8927
|
|
|
8917
8928
|
/* Orthographic forward equations--mapping lat,long to x,y
|
|
@@ -8926,7 +8937,7 @@
|
|
|
8926
8937
|
var lat = p.y;
|
|
8927
8938
|
/* Forward equations
|
|
8928
8939
|
----------------- */
|
|
8929
|
-
dlon = adjust_lon(lon - this.long0, this.over);
|
|
8940
|
+
dlon = adjust_lon(lon - (this.long0 || 0), this.over);
|
|
8930
8941
|
|
|
8931
8942
|
sinphi = Math.sin(lat);
|
|
8932
8943
|
cosphi = Math.cos(lat);
|
|
@@ -8936,7 +8947,7 @@
|
|
|
8936
8947
|
ksp = 1;
|
|
8937
8948
|
if ((g > 0) || (Math.abs(g) <= EPSLN)) {
|
|
8938
8949
|
x = this.a * ksp * cosphi * Math.sin(dlon);
|
|
8939
|
-
y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
|
|
8950
|
+
y = (this.y0 || 0) + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
|
|
8940
8951
|
}
|
|
8941
8952
|
p.x = x;
|
|
8942
8953
|
p.y = y;
|
|
@@ -8949,36 +8960,39 @@
|
|
|
8949
8960
|
var sinz, cosz; /* sin of z and cos of z */
|
|
8950
8961
|
var con;
|
|
8951
8962
|
var lon, lat;
|
|
8963
|
+
var long0, lat0;
|
|
8952
8964
|
/* Inverse equations
|
|
8953
8965
|
----------------- */
|
|
8954
|
-
p.x -= this.x0;
|
|
8955
|
-
p.y -= this.y0;
|
|
8966
|
+
p.x -= this.x0 || 0;
|
|
8967
|
+
p.y -= this.y0 || 0;
|
|
8956
8968
|
rh = Math.sqrt(p.x * p.x + p.y * p.y);
|
|
8957
8969
|
z = asinz(rh / this.a);
|
|
8958
8970
|
|
|
8959
8971
|
sinz = Math.sin(z);
|
|
8960
8972
|
cosz = Math.cos(z);
|
|
8961
8973
|
|
|
8962
|
-
|
|
8974
|
+
long0 = this.long0 || 0;
|
|
8975
|
+
lat0 = this.lat0 || 0;
|
|
8976
|
+
lon = long0;
|
|
8963
8977
|
if (Math.abs(rh) <= EPSLN) {
|
|
8964
|
-
lat =
|
|
8978
|
+
lat = lat0;
|
|
8965
8979
|
p.x = lon;
|
|
8966
8980
|
p.y = lat;
|
|
8967
8981
|
return p;
|
|
8968
8982
|
}
|
|
8969
8983
|
lat = asinz(cosz * this.sin_p14 + (p.y * sinz * this.cos_p14) / rh);
|
|
8970
|
-
con = Math.abs(
|
|
8984
|
+
con = Math.abs(lat0) - HALF_PI;
|
|
8971
8985
|
if (Math.abs(con) <= EPSLN) {
|
|
8972
|
-
if (
|
|
8973
|
-
lon = adjust_lon(
|
|
8986
|
+
if (lat0 >= 0) {
|
|
8987
|
+
lon = adjust_lon(long0 + Math.atan2(p.x, -p.y), this.over);
|
|
8974
8988
|
} else {
|
|
8975
|
-
lon = adjust_lon(
|
|
8989
|
+
lon = adjust_lon(long0 - Math.atan2(-p.x, p.y), this.over);
|
|
8976
8990
|
}
|
|
8977
8991
|
p.x = lon;
|
|
8978
8992
|
p.y = lat;
|
|
8979
8993
|
return p;
|
|
8980
8994
|
}
|
|
8981
|
-
lon = adjust_lon(
|
|
8995
|
+
lon = adjust_lon(long0 + Math.atan2((p.x * sinz), rh * this.cos_p14 * cosz - p.y * this.sin_p14 * sinz), this.over);
|
|
8982
8996
|
p.x = lon;
|
|
8983
8997
|
p.y = lat;
|
|
8984
8998
|
return p;
|
|
@@ -10552,7 +10566,7 @@
|
|
|
10552
10566
|
nadgrid,
|
|
10553
10567
|
transform,
|
|
10554
10568
|
mgrs,
|
|
10555
|
-
version: '2.20.
|
|
10569
|
+
version: '2.20.3'
|
|
10556
10570
|
});
|
|
10557
10571
|
includedProjections(proj4);
|
|
10558
10572
|
|