@wemap/geo 7.4.0 → 8.0.0-alpha.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/dist/wemap-geo.es.js +183 -16
- package/dist/wemap-geo.es.js.map +1 -1
- package/package.json +3 -3
- package/src/coordinates/GeoRef.js +5 -5
package/dist/wemap-geo.es.js
CHANGED
|
@@ -349,9 +349,30 @@ class Level {
|
|
|
349
349
|
*/
|
|
350
350
|
class Coordinates {
|
|
351
351
|
|
|
352
|
+
/** @type {Number} */
|
|
353
|
+
_lat;
|
|
354
|
+
|
|
355
|
+
/** @type {Number} */
|
|
356
|
+
_lng;
|
|
357
|
+
|
|
358
|
+
/** @type {Number|null} */
|
|
359
|
+
_alt = null;
|
|
360
|
+
|
|
361
|
+
/** @type {Level|null} */
|
|
362
|
+
_level = null;
|
|
363
|
+
|
|
364
|
+
/** @type {[Number, Number, Number]|null} */
|
|
365
|
+
_ecef;
|
|
366
|
+
|
|
352
367
|
autoWrap = true;
|
|
353
368
|
|
|
354
|
-
|
|
369
|
+
/**
|
|
370
|
+
* @param {Number} lat
|
|
371
|
+
* @param {Number} lng
|
|
372
|
+
* @param {?(Number|null)} alt
|
|
373
|
+
* @param {?(Level|null)} level
|
|
374
|
+
*/
|
|
375
|
+
constructor(lat, lng, alt = null, level = null) {
|
|
355
376
|
this.lat = lat;
|
|
356
377
|
this.lng = lng;
|
|
357
378
|
this.alt = alt;
|
|
@@ -359,23 +380,28 @@ class Coordinates {
|
|
|
359
380
|
this._ecef = null;
|
|
360
381
|
}
|
|
361
382
|
|
|
383
|
+
/** @type {Number} */
|
|
362
384
|
get lat() {
|
|
363
385
|
return this._lat;
|
|
364
386
|
}
|
|
365
387
|
|
|
388
|
+
/** @type {Number} */
|
|
366
389
|
get latitude() {
|
|
367
390
|
return this._lat;
|
|
368
391
|
}
|
|
369
392
|
|
|
393
|
+
/** @type {Number} */
|
|
370
394
|
get lng() {
|
|
371
395
|
return this._lng;
|
|
372
396
|
}
|
|
373
397
|
|
|
398
|
+
/** @type {Number} */
|
|
374
399
|
get longitude() {
|
|
375
400
|
return this._lng;
|
|
376
401
|
}
|
|
377
402
|
|
|
378
403
|
/**
|
|
404
|
+
* @type {Number|null}
|
|
379
405
|
* alt does not denote the altitude of a point but its height from
|
|
380
406
|
* the "level" field (if defined) or from the ground
|
|
381
407
|
*/
|
|
@@ -383,10 +409,12 @@ class Coordinates {
|
|
|
383
409
|
return this._alt;
|
|
384
410
|
}
|
|
385
411
|
|
|
412
|
+
/** @type {Level|null} */
|
|
386
413
|
get level() {
|
|
387
414
|
return this._level;
|
|
388
415
|
}
|
|
389
416
|
|
|
417
|
+
/** @type {Number} */
|
|
390
418
|
set lat(lat) {
|
|
391
419
|
if (typeof lat === 'number' && Math.abs(lat) <= 90) {
|
|
392
420
|
this._lat = lat;
|
|
@@ -396,10 +424,12 @@ class Coordinates {
|
|
|
396
424
|
this._ecef = null;
|
|
397
425
|
}
|
|
398
426
|
|
|
399
|
-
|
|
427
|
+
/** @type {Number} */
|
|
428
|
+
set latitude(_) {
|
|
400
429
|
throw new Error('Please use Coordinate#lat setter instead of Coordinate#latitude');
|
|
401
430
|
}
|
|
402
431
|
|
|
432
|
+
/** @type {Number} */
|
|
403
433
|
set lng(lng) {
|
|
404
434
|
if (typeof lng === 'number') {
|
|
405
435
|
this._lng = lng;
|
|
@@ -412,10 +442,12 @@ class Coordinates {
|
|
|
412
442
|
this._ecef = null;
|
|
413
443
|
}
|
|
414
444
|
|
|
415
|
-
|
|
445
|
+
/** @type {Number} */
|
|
446
|
+
set longitude(_) {
|
|
416
447
|
throw new Error('Please use Coordinate#lng setter instead of Coordinate#longitude');
|
|
417
448
|
}
|
|
418
449
|
|
|
450
|
+
/** @type {Number|null} */
|
|
419
451
|
set alt(alt) {
|
|
420
452
|
if (typeof alt === 'number') {
|
|
421
453
|
this._alt = alt;
|
|
@@ -428,6 +460,7 @@ class Coordinates {
|
|
|
428
460
|
this._ecef = null;
|
|
429
461
|
}
|
|
430
462
|
|
|
463
|
+
/** @type {Level|null} */
|
|
431
464
|
set level(level) {
|
|
432
465
|
if (level instanceof Level) {
|
|
433
466
|
this._level = level;
|
|
@@ -439,6 +472,10 @@ class Coordinates {
|
|
|
439
472
|
}
|
|
440
473
|
}
|
|
441
474
|
|
|
475
|
+
/**
|
|
476
|
+
* Deep clone coordinates
|
|
477
|
+
* @returns {!Coordinates}
|
|
478
|
+
*/
|
|
442
479
|
clone() {
|
|
443
480
|
const output = new Coordinates(this.lat, this.lng, this.alt);
|
|
444
481
|
if (this.level) {
|
|
@@ -479,17 +516,35 @@ class Coordinates {
|
|
|
479
516
|
&& Level.equalsTo(pos1.level, pos2.level);
|
|
480
517
|
}
|
|
481
518
|
|
|
519
|
+
/**
|
|
520
|
+
* @param {Coordinates} other
|
|
521
|
+
* @returns {!Boolean}
|
|
522
|
+
*/
|
|
482
523
|
equalsTo(other) {
|
|
483
524
|
return Coordinates.equalsTo(this, other);
|
|
484
525
|
}
|
|
485
526
|
|
|
527
|
+
/**
|
|
528
|
+
* @param {!Number} distance
|
|
529
|
+
* @param {!Number} bearing
|
|
530
|
+
* @param {?Number} elevation
|
|
531
|
+
* @returns {!Coordinates}
|
|
532
|
+
* @throws {Error} if elevation is defined and point altitude is not defined
|
|
533
|
+
*/
|
|
486
534
|
destinationPoint(distance, bearing, elevation) {
|
|
487
535
|
const newPoint = this.clone();
|
|
488
536
|
newPoint.move(distance, bearing, elevation);
|
|
489
537
|
return newPoint;
|
|
490
538
|
}
|
|
491
539
|
|
|
492
|
-
|
|
540
|
+
/**
|
|
541
|
+
* Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint
|
|
542
|
+
* @param {!Number} distance
|
|
543
|
+
* @param {!Number} bearing
|
|
544
|
+
* @param {?Number} elevation
|
|
545
|
+
* @returns {!Coordinates}
|
|
546
|
+
* @throws {Error} if elevation is defined and point altitude is not defined
|
|
547
|
+
*/
|
|
493
548
|
move(distance, bearing, elevation) {
|
|
494
549
|
|
|
495
550
|
const dR = distance / Constants.R_MAJOR;
|
|
@@ -518,7 +573,6 @@ class Coordinates {
|
|
|
518
573
|
this.alt += elevation;
|
|
519
574
|
}
|
|
520
575
|
|
|
521
|
-
|
|
522
576
|
return this;
|
|
523
577
|
}
|
|
524
578
|
|
|
@@ -553,10 +607,19 @@ class Coordinates {
|
|
|
553
607
|
return Constants.R_MAJOR * cosn;
|
|
554
608
|
}
|
|
555
609
|
|
|
610
|
+
/**
|
|
611
|
+
* @param {!Coordinates} point1
|
|
612
|
+
* @param {!Coordinates} point2
|
|
613
|
+
* @returns {!Number}
|
|
614
|
+
*/
|
|
556
615
|
static distanceBetween(point1, point2) {
|
|
557
616
|
return point1.distanceTo(point2);
|
|
558
617
|
}
|
|
559
618
|
|
|
619
|
+
/**
|
|
620
|
+
* @param {!Coordinates} location2
|
|
621
|
+
* @returns {!Number}
|
|
622
|
+
*/
|
|
560
623
|
bearingTo(location2) {
|
|
561
624
|
const lat1 = deg2rad(this.lat);
|
|
562
625
|
const lat2 = deg2rad(location2.lat);
|
|
@@ -566,6 +629,11 @@ class Coordinates {
|
|
|
566
629
|
Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(diffLng));
|
|
567
630
|
}
|
|
568
631
|
|
|
632
|
+
/**
|
|
633
|
+
* @param {!Coordinates} point1
|
|
634
|
+
* @param {!Coordinates} point2
|
|
635
|
+
* @returns {!Number}
|
|
636
|
+
*/
|
|
569
637
|
static bearingTo(point1, point2) {
|
|
570
638
|
return point1.bearingTo(point2);
|
|
571
639
|
}
|
|
@@ -577,20 +645,25 @@ class Coordinates {
|
|
|
577
645
|
* as a sphere instead of an ellipse
|
|
578
646
|
*/
|
|
579
647
|
|
|
648
|
+
/** @type {![Number, Number, Number, Number]} */
|
|
580
649
|
get enuToEcefRotation() {
|
|
581
650
|
const rot1 = Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + deg2rad(this.lng));
|
|
582
651
|
const rot2 = Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - deg2rad(this.lat));
|
|
583
652
|
return Quaternion.multiply(rot1, rot2);
|
|
584
653
|
}
|
|
585
654
|
|
|
655
|
+
/** @type {![Number, Number, Number, Number]} */
|
|
586
656
|
get ecefToEnuRotation() {
|
|
587
657
|
const rot1 = Quaternion.fromAxisAngle([1, 0, 0], deg2rad(this.lat) - Math.PI / 2);
|
|
588
658
|
const rot2 = Quaternion.fromAxisAngle([0, 0, 1], -deg2rad(this.lng) - Math.PI / 2);
|
|
589
659
|
return Quaternion.multiply(rot1, rot2);
|
|
590
660
|
}
|
|
591
661
|
|
|
592
|
-
|
|
593
|
-
|
|
662
|
+
/**
|
|
663
|
+
* https://gist.github.com/klucar/1536194
|
|
664
|
+
* Adapted for spherical formula
|
|
665
|
+
* @type {![Number, Number, Number]}
|
|
666
|
+
*/
|
|
594
667
|
get ecef() {
|
|
595
668
|
|
|
596
669
|
if (!this._ecef) {
|
|
@@ -608,6 +681,10 @@ class Coordinates {
|
|
|
608
681
|
return this._ecef;
|
|
609
682
|
}
|
|
610
683
|
|
|
684
|
+
/**
|
|
685
|
+
* @param {![Number, Number, Number]} ecef
|
|
686
|
+
* @returns {!Coordinates}
|
|
687
|
+
*/
|
|
611
688
|
static fromECEF(ecef) {
|
|
612
689
|
|
|
613
690
|
const x = ecef[0];
|
|
@@ -628,8 +705,13 @@ class Coordinates {
|
|
|
628
705
|
}
|
|
629
706
|
|
|
630
707
|
|
|
631
|
-
|
|
632
|
-
|
|
708
|
+
/**
|
|
709
|
+
* https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere
|
|
710
|
+
* Adapted to ECEF
|
|
711
|
+
* @param {!Coordinates} p1
|
|
712
|
+
* @param {!Coordinates} p2
|
|
713
|
+
* @returns {Coordinates|null}
|
|
714
|
+
*/
|
|
633
715
|
getSegmentProjection(p1, p2) {
|
|
634
716
|
|
|
635
717
|
const a = Vector3.normalize(p1.ecef);
|
|
@@ -669,6 +751,9 @@ class Coordinates {
|
|
|
669
751
|
* Input / Output
|
|
670
752
|
*/
|
|
671
753
|
|
|
754
|
+
/**
|
|
755
|
+
* @returns {!String}
|
|
756
|
+
*/
|
|
672
757
|
toString() {
|
|
673
758
|
let str = '[' + this._lat.toFixed(7) + ', ' + this._lng.toFixed(7);
|
|
674
759
|
if (this._alt !== null) {
|
|
@@ -681,6 +766,9 @@ class Coordinates {
|
|
|
681
766
|
return str;
|
|
682
767
|
}
|
|
683
768
|
|
|
769
|
+
/**
|
|
770
|
+
* @returns {!Object}
|
|
771
|
+
*/
|
|
684
772
|
toJson() {
|
|
685
773
|
const output = {
|
|
686
774
|
lat: this.lat,
|
|
@@ -695,10 +783,17 @@ class Coordinates {
|
|
|
695
783
|
return output;
|
|
696
784
|
}
|
|
697
785
|
|
|
786
|
+
/**
|
|
787
|
+
* @param {!Object} json
|
|
788
|
+
* @returns {!Coordinates}
|
|
789
|
+
*/
|
|
698
790
|
static fromJson(json) {
|
|
699
791
|
return new Coordinates(json.lat, json.lng, json.alt, Level.fromString(json.level));
|
|
700
792
|
}
|
|
701
793
|
|
|
794
|
+
/**
|
|
795
|
+
* @returns {!Object}
|
|
796
|
+
*/
|
|
702
797
|
toCompressedJson() {
|
|
703
798
|
const output = [this.lat, this.lng];
|
|
704
799
|
if (this.alt !== null || this.level !== null) {
|
|
@@ -710,6 +805,10 @@ class Coordinates {
|
|
|
710
805
|
return output;
|
|
711
806
|
}
|
|
712
807
|
|
|
808
|
+
/**
|
|
809
|
+
* @param {!Object} json
|
|
810
|
+
* @returns {!Coordinates}
|
|
811
|
+
*/
|
|
713
812
|
static fromCompressedJson(json) {
|
|
714
813
|
const coords = new Coordinates(json[0], json[1]);
|
|
715
814
|
if (json.length > 2) {
|
|
@@ -1433,6 +1532,67 @@ class RelativePosition {
|
|
|
1433
1532
|
*/
|
|
1434
1533
|
class GeoRelativePosition extends RelativePosition { }
|
|
1435
1534
|
|
|
1535
|
+
class GeoRef {
|
|
1536
|
+
|
|
1537
|
+
/** @type {!Coordinates} */
|
|
1538
|
+
origin;
|
|
1539
|
+
|
|
1540
|
+
/** @type {number} */
|
|
1541
|
+
scale = 1;
|
|
1542
|
+
|
|
1543
|
+
/** @type {number} */
|
|
1544
|
+
heading = 0;
|
|
1545
|
+
|
|
1546
|
+
|
|
1547
|
+
/**
|
|
1548
|
+
* @param {number[]} localPosition in ENU frame
|
|
1549
|
+
* @returns {Coordinates}
|
|
1550
|
+
*/
|
|
1551
|
+
localToWorld(localPosition) {
|
|
1552
|
+
const localPositionScaled = Vector3.multiplyScalar(localPosition, this.scale);
|
|
1553
|
+
const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);
|
|
1554
|
+
const ecefToEnuRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.ecefToEnuRotation);
|
|
1555
|
+
const ecefTranslation = Quaternion.rotate(ecefToEnuRotationOrigin, localPositionScaled);
|
|
1556
|
+
const ecef = Vector3.add(this.origin.ecef, ecefTranslation);
|
|
1557
|
+
return Coordinates.fromECEF(ecef);
|
|
1558
|
+
}
|
|
1559
|
+
|
|
1560
|
+
/**
|
|
1561
|
+
* @param {Coordinates} coords
|
|
1562
|
+
* @returns {number[]} localPosition in ENU frame
|
|
1563
|
+
*/
|
|
1564
|
+
worldToLocal(coords) {
|
|
1565
|
+
const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], -this.heading);
|
|
1566
|
+
const enuToEcefRotationOrigin = Quaternion.multiply(this.origin.enuToEcefRotation, rotationOffset);
|
|
1567
|
+
const ecefTranslation = Vector3.subtract(coords.ecef, this.origin.ecef);
|
|
1568
|
+
const ecefTranslationScaled = Vector3.multiplyScalar(ecefTranslation, 1 / this.scale);
|
|
1569
|
+
return Quaternion.rotate(enuToEcefRotationOrigin, ecefTranslationScaled);
|
|
1570
|
+
}
|
|
1571
|
+
|
|
1572
|
+
/**
|
|
1573
|
+
* @returns {Object}
|
|
1574
|
+
*/
|
|
1575
|
+
toJson() {
|
|
1576
|
+
return {
|
|
1577
|
+
origin: this.origin.toJson(),
|
|
1578
|
+
scale: this.scale,
|
|
1579
|
+
heading: this.heading
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* @param {Object} json
|
|
1585
|
+
* @returns {GeoRef}
|
|
1586
|
+
*/
|
|
1587
|
+
static fromJson(json) {
|
|
1588
|
+
const geoRef = new GeoRef();
|
|
1589
|
+
geoRef.origin = Coordinates.fromJson(json.origin);
|
|
1590
|
+
geoRef.scale = json.scale;
|
|
1591
|
+
geoRef.heading = json.heading;
|
|
1592
|
+
return geoRef;
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1436
1596
|
class Attitude {
|
|
1437
1597
|
|
|
1438
1598
|
_quaternion = [1, 0, 0, 0];
|
|
@@ -2468,11 +2628,11 @@ class MapMatching {
|
|
|
2468
2628
|
checkEdge = false;
|
|
2469
2629
|
}
|
|
2470
2630
|
|
|
2471
|
-
if (!Level.equalsTo(location.level, edge.node1.coords.level) && !edge.node1.io) {
|
|
2631
|
+
if (!Level.equalsTo(location.level, edge.node1.coords.level) && !(edge.node1.io && !location.level)) {
|
|
2472
2632
|
checkNode1 = false;
|
|
2473
2633
|
}
|
|
2474
2634
|
|
|
2475
|
-
if (!Level.equalsTo(location.level, edge.node2.coords.level) && !edge.node2.io) {
|
|
2635
|
+
if (!Level.equalsTo(location.level, edge.node2.coords.level) && !(edge.node2.io && !location.level)) {
|
|
2476
2636
|
checkNode2 = false;
|
|
2477
2637
|
}
|
|
2478
2638
|
|
|
@@ -2776,6 +2936,10 @@ class GraphRouter {
|
|
|
2776
2936
|
|
|
2777
2937
|
const createdNodes = [];
|
|
2778
2938
|
|
|
2939
|
+
/**
|
|
2940
|
+
* @param {GraphNode|Coordinates} point
|
|
2941
|
+
* @returns {GraphNode}
|
|
2942
|
+
*/
|
|
2779
2943
|
const retrieveOrCreateNearestNode = point => {
|
|
2780
2944
|
if (point instanceof GraphNode) {
|
|
2781
2945
|
return point;
|
|
@@ -2788,10 +2952,13 @@ class GraphRouter {
|
|
|
2788
2952
|
|
|
2789
2953
|
const proj = this._mapMatching.getProjection(point, true, false, false, acceptEdgeFn);
|
|
2790
2954
|
if (!proj) {
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2955
|
+
let message = `Point ${point.toString()} is too far from the network `
|
|
2956
|
+
+ `> ${this._mapMatching.maxDistance.toFixed(0)} meters.`;
|
|
2957
|
+
if (point.level) {
|
|
2958
|
+
message += ' If it is a multi-level map, please verify if you have'
|
|
2959
|
+
+ ` a network at level ${point.level.toString()}.`;
|
|
2960
|
+
}
|
|
2961
|
+
throw new NoRouteFoundError(start, end, message);
|
|
2795
2962
|
}
|
|
2796
2963
|
if (proj.nearestElement instanceof GraphNode) {
|
|
2797
2964
|
return proj.nearestElement;
|
|
@@ -2999,5 +3166,5 @@ class GraphRouter {
|
|
|
2999
3166
|
}
|
|
3000
3167
|
}
|
|
3001
3168
|
|
|
3002
|
-
export { AbsoluteHeading, Attitude, BoundingBox, Constants, Coordinates, GeoRelativePosition, GraphEdge, GraphItinerary, GraphNode, GraphProjection, GraphRouter, GraphRouterOptions, GraphUtils, Level, MapMatching, Network, NoRouteFoundError, RelativePosition, UserPosition, Utils };
|
|
3169
|
+
export { AbsoluteHeading, Attitude, BoundingBox, Constants, Coordinates, GeoRef, GeoRelativePosition, GraphEdge, GraphItinerary, GraphNode, GraphProjection, GraphRouter, GraphRouterOptions, GraphUtils, Level, MapMatching, Network, NoRouteFoundError, RelativePosition, UserPosition, Utils };
|
|
3003
3170
|
//# sourceMappingURL=wemap-geo.es.js.map
|