@wemap/geo 11.3.3 → 11.7.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/index.js CHANGED
@@ -5,12 +5,10 @@ var __publicField = (obj, key, value) => {
5
5
  __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
6
  return value;
7
7
  };
8
- Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
8
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
9
  const maths = require("@wemap/maths");
10
10
  const utils = require("@wemap/utils");
11
11
  const Logger = require("@wemap/logger");
12
- const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
13
- const Logger__default = /* @__PURE__ */ _interopDefaultLegacy(Logger);
14
12
  const R_MAJOR = 6378137;
15
13
  const R_MINOR = 63567523142e-4;
16
14
  const EARTH_GRAVITY = 9.80665;
@@ -26,21 +24,21 @@ const R_MINOR_4 = R_MINOR_2 * R_MINOR_2;
26
24
  const CIRCUMFERENCE = R_MAJOR * 2 * Math.PI;
27
25
  const Constants = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
28
26
  __proto__: null,
29
- R_MAJOR,
30
- R_MINOR,
27
+ CIRCUMFERENCE,
31
28
  EARTH_GRAVITY,
32
- EPS_DEG_MM,
33
- EPS_MM,
34
- ELLIPSOID_FLATNESS,
35
29
  ECCENTRICITY,
36
30
  ECCENTRICITY_2,
31
+ ELLIPSOID_FLATNESS,
32
+ EPS_DEG_MM,
33
+ EPS_MM,
34
+ R_MAJOR,
37
35
  R_MAJOR_2,
38
36
  R_MAJOR_4,
37
+ R_MINOR,
39
38
  R_MINOR_2,
40
- R_MINOR_4,
41
- CIRCUMFERENCE
39
+ R_MINOR_4
42
40
  }, Symbol.toStringTag, { value: "Module" }));
43
- const _Level = class {
41
+ const _Level = class _Level {
44
42
  static checkType(level) {
45
43
  if (level === null) {
46
44
  return;
@@ -59,6 +57,9 @@ const _Level = class {
59
57
  }
60
58
  throw Error(`Unknown level format: ${level}`);
61
59
  }
60
+ /**
61
+ * Return true if the level is a range, false otherwise
62
+ */
62
63
  static isRange(level) {
63
64
  if (_Level.VERIFY_TYPING) {
64
65
  this.checkType(level);
@@ -77,6 +78,9 @@ const _Level = class {
77
78
  }
78
79
  return [level[0], level[1]];
79
80
  }
81
+ /**
82
+ * Create a level from a string (eg. 1, -2, 1;2, -2;3, 2;-1, 0.5;1 ...)
83
+ */
80
84
  static fromString(str) {
81
85
  if (str === null) {
82
86
  return null;
@@ -105,6 +109,11 @@ const _Level = class {
105
109
  }
106
110
  throw Error(`Cannot parse following level: ${str}`);
107
111
  }
112
+ /**
113
+ * Returns if a level is contained in another
114
+ * @param {null|number|[number, number]} container The container level
115
+ * @param {null|number|[number, number]} targeted The targeted level
116
+ */
108
117
  static contains(container, targeted) {
109
118
  if (_Level.VERIFY_TYPING) {
110
119
  this.checkType(container);
@@ -127,6 +136,9 @@ const _Level = class {
127
136
  }
128
137
  return container <= targeted[0] && container >= targeted[1];
129
138
  }
139
+ /**
140
+ * Retrieve the intersection of two levels
141
+ */
130
142
  static intersection(first, second) {
131
143
  if (_Level.VERIFY_TYPING) {
132
144
  this.checkType(first);
@@ -160,6 +172,12 @@ const _Level = class {
160
172
  }
161
173
  return up < low ? null : [low, up];
162
174
  }
175
+ /**
176
+ * Retrieve the intersection of two levels
177
+ * @param {null|number|[number, number]} first The first level
178
+ * @param {null|number|[number, number]} second The second level
179
+ * @returns {boolean}
180
+ */
163
181
  static intersect(first, second) {
164
182
  if (_Level.VERIFY_TYPING) {
165
183
  this.checkType(first);
@@ -170,6 +188,9 @@ const _Level = class {
170
188
  }
171
189
  return this.intersection(first, second) !== null;
172
190
  }
191
+ /**
192
+ * Retrieve the union of two levels
193
+ */
173
194
  static union(first, second) {
174
195
  if (_Level.VERIFY_TYPING) {
175
196
  this.checkType(first);
@@ -203,6 +224,12 @@ const _Level = class {
203
224
  }
204
225
  return [low, up];
205
226
  }
227
+ /**
228
+ * Multiply a level by a factor
229
+ * @param {null|number|[number, number]} level the level to multiply
230
+ * @param {number} factor
231
+ * @returns {null|number|[number, number]}
232
+ */
206
233
  static multiplyBy(level, factor) {
207
234
  if (_Level.VERIFY_TYPING) {
208
235
  this.checkType(level);
@@ -269,8 +296,8 @@ const _Level = class {
269
296
  return null;
270
297
  }
271
298
  };
299
+ __publicField(_Level, "VERIFY_TYPING", false);
272
300
  let Level = _Level;
273
- __publicField(Level, "VERIFY_TYPING", false);
274
301
  class Coordinates {
275
302
  constructor(lat, lng, alt = null, level = null) {
276
303
  __publicField(this, "_lat");
@@ -318,6 +345,10 @@ class Coordinates {
318
345
  set longitude(_) {
319
346
  throw new Error("Please use Coordinates#lng setter instead of Coordinate#longitude");
320
347
  }
348
+ /**
349
+ * alt does not denote the altitude of a point but its height from
350
+ * the "level" field (if defined) or from the ground
351
+ */
321
352
  get alt() {
322
353
  return this._alt;
323
354
  }
@@ -332,6 +363,9 @@ class Coordinates {
332
363
  Level.checkType(level);
333
364
  this._level = level;
334
365
  }
366
+ /**
367
+ * Deep clone coordinates
368
+ */
335
369
  clone() {
336
370
  const output = new Coordinates(this.lat, this.lng, this.alt);
337
371
  if (this.level !== null) {
@@ -356,11 +390,18 @@ class Coordinates {
356
390
  equals(other) {
357
391
  return Coordinates.equals(this, other);
358
392
  }
393
+ /**
394
+ * @throws {Error} if elevation is defined and point altitude is not defined
395
+ */
359
396
  destinationPoint(distance, bearing, elevation = null) {
360
397
  const newPoint = this.clone();
361
398
  newPoint.move(distance, bearing, elevation);
362
399
  return newPoint;
363
400
  }
401
+ /**
402
+ * Source: http://www.movable-type.co.uk/scripts/latlong.html#destPoint
403
+ * @throws {Error} if elevation is defined and point altitude is not defined
404
+ */
364
405
  move(distance, bearing, elevation = null) {
365
406
  const dR = distance / R_MAJOR;
366
407
  const cosDr = Math.cos(dR);
@@ -384,6 +425,9 @@ class Coordinates {
384
425
  }
385
426
  return this;
386
427
  }
428
+ /**
429
+ * Returns a distance between two points in meters
430
+ */
387
431
  distanceTo(location2) {
388
432
  const lat1 = this.lat;
389
433
  const lng1 = this.lng;
@@ -418,6 +462,11 @@ class Coordinates {
418
462
  static bearingTo(point1, point2) {
419
463
  return point1.bearingTo(point2);
420
464
  }
465
+ /**
466
+ * ECEF Transformations
467
+ * Here we used a light version of ECEF considering earth
468
+ * as a sphere instead of an ellipse
469
+ */
421
470
  get enuToEcefRotation() {
422
471
  const rot1 = maths.Quaternion.fromAxisAngle([0, 0, 1], Math.PI / 2 + maths.deg2rad(this.lng));
423
472
  const rot2 = maths.Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2 - maths.deg2rad(this.lat));
@@ -428,6 +477,10 @@ class Coordinates {
428
477
  const rot2 = maths.Quaternion.fromAxisAngle([0, 0, 1], -maths.deg2rad(this.lng) - Math.PI / 2);
429
478
  return maths.Quaternion.multiply(rot1, rot2);
430
479
  }
480
+ /**
481
+ * https://gist.github.com/klucar/1536194
482
+ * Adapted for spherical formula
483
+ */
431
484
  get ecef() {
432
485
  if (!this._ecef) {
433
486
  const lat = maths.deg2rad(this.lat);
@@ -453,6 +506,10 @@ class Coordinates {
453
506
  newPoint._ecef = ecef;
454
507
  return newPoint;
455
508
  }
509
+ /**
510
+ * https://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere
511
+ * Adapted to ECEF
512
+ */
456
513
  getSegmentProjection(p1, p2) {
457
514
  const a = maths.Vector3.normalize(p1.ecef);
458
515
  const b = maths.Vector3.normalize(p2.ecef);
@@ -480,6 +537,9 @@ class Coordinates {
480
537
  }
481
538
  return projection;
482
539
  }
540
+ /**
541
+ * Input / Output
542
+ */
483
543
  toString() {
484
544
  let str = "[" + this._lat.toFixed(7) + ", " + this._lng.toFixed(7);
485
545
  if (this._alt !== null) {
@@ -571,6 +631,8 @@ class UserPosition extends Coordinates {
571
631
  newPoint.move(distance, bearing, elevation);
572
632
  return newPoint;
573
633
  }
634
+ // Create a UserPosition with lat, lng, alt from Coordinates coordinates and
635
+ // other fields from another UserPosition
574
636
  static fromCoordinates(coordinates) {
575
637
  return new UserPosition(
576
638
  coordinates.lat,
@@ -742,11 +804,11 @@ function calcDistance(coords) {
742
804
  }
743
805
  const Utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
744
806
  __proto__: null,
807
+ calcDistance,
808
+ geolocationPositionToUserPosition,
745
809
  sampleRoute,
746
- trimRoute,
747
810
  simplifyRoute,
748
- geolocationPositionToUserPosition,
749
- calcDistance
811
+ trimRoute
750
812
  }, Symbol.toStringTag, { value: "Module" }));
751
813
  class BoundingBox {
752
814
  constructor(northEast, southWest) {
@@ -758,14 +820,23 @@ class BoundingBox {
758
820
  throw new Error("Incorrect bounding box");
759
821
  }
760
822
  }
823
+ /**
824
+ * Returns the geographical coordinate equidistant from the bounding box's corners.
825
+ */
761
826
  get center() {
762
827
  const latCenter = (this.southWest.lat + this.northEast.lat) / 2;
763
828
  const lngCenter = (this.northEast.lng + this.southWest.lng) / 2;
764
829
  return new Coordinates(latCenter, lngCenter);
765
830
  }
831
+ /**
832
+ * Check if a point is contained in the bounding box.
833
+ */
766
834
  contains(point) {
767
835
  return point.lat <= this.northEast.lat && point.lat >= this.southWest.lat && point.lng <= this.northEast.lng && point.lng >= this.southWest.lng;
768
836
  }
837
+ /**
838
+ * Extend the bounds to include a given LngLat or LngLatBounds.
839
+ */
769
840
  extend(obj) {
770
841
  const sw = this.southWest, ne = this.northEast;
771
842
  let sw2, ne2;
@@ -788,6 +859,10 @@ class BoundingBox {
788
859
  );
789
860
  return this;
790
861
  }
862
+ /**
863
+ * This method extends the bounding box with a value in meters
864
+ * /*\ This method is not precise as distance differs in function of latitude
865
+ */
791
866
  extendsWithMeasure(measure) {
792
867
  if (typeof measure !== "number") {
793
868
  throw new Error("measure is not a number");
@@ -796,6 +871,11 @@ class BoundingBox {
796
871
  this.southWest = this.southWest.clone().destinationPoint(measure, -Math.PI / 2).destinationPoint(measure, Math.PI);
797
872
  return this;
798
873
  }
874
+ /**
875
+ * Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
876
+ * For example, a ratio of 0.5 extends the bounds by 50% in each direction.
877
+ * Negative values will retract the bounds.
878
+ */
799
879
  pad(bufferRatio) {
800
880
  const sw = this.southWest;
801
881
  const ne = this.northEast;
@@ -805,27 +885,51 @@ class BoundingBox {
805
885
  this.northEast = new Coordinates(ne.lat + heightBuffer, ne.lng + widthBuffer);
806
886
  return this;
807
887
  }
888
+ /**
889
+ * Returns the southwest corner of the bounding box.
890
+ */
808
891
  getSouthWest() {
809
892
  return this.southWest;
810
893
  }
894
+ /**
895
+ * Returns the northeast corner of the bounding box.
896
+ */
811
897
  getNorthEast() {
812
898
  return this.northEast;
813
899
  }
900
+ /**
901
+ * Returns the northwest corner of the bounding box.
902
+ */
814
903
  getNorthWest() {
815
904
  return new Coordinates(this.getNorth(), this.getWest());
816
905
  }
906
+ /**
907
+ * Returns the southeast corner of the bounding box.
908
+ */
817
909
  getSouthEast() {
818
910
  return new Coordinates(this.getSouth(), this.getEast());
819
911
  }
912
+ /**
913
+ * Returns the west edge of the bounding box.
914
+ */
820
915
  getWest() {
821
916
  return this.southWest.lng;
822
917
  }
918
+ /**
919
+ * Returns the south edge of the bounding box.
920
+ */
823
921
  getSouth() {
824
922
  return this.southWest.lat;
825
923
  }
924
+ /**
925
+ * Returns the east edge of the bounding box.
926
+ */
826
927
  getEast() {
827
928
  return this.northEast.lng;
828
929
  }
930
+ /**
931
+ * Returns the north edge of the bounding box.
932
+ */
829
933
  getNorth() {
830
934
  return this.northEast.lat;
831
935
  }
@@ -835,6 +939,9 @@ class BoundingBox {
835
939
  equals(other) {
836
940
  return BoundingBox.equals(this, other);
837
941
  }
942
+ /**
943
+ * Create a BoundingBox from a WSEN array
944
+ */
838
945
  static fromArray(bounds) {
839
946
  return new BoundingBox(
840
947
  new Coordinates(bounds[3], bounds[2]),
@@ -850,6 +957,9 @@ class BoundingBox {
850
957
  new BoundingBox(coords[0], coords[0])
851
958
  );
852
959
  }
960
+ /**
961
+ * Returns the WSEN array
962
+ */
853
963
  toArray() {
854
964
  return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()];
855
965
  }
@@ -887,6 +997,12 @@ class RelativePosition {
887
997
  clone() {
888
998
  return new RelativePosition(this.x, this.y, this.z, this.time, this.accuracy, this.bearing);
889
999
  }
1000
+ /**
1001
+ * Compares two RelativePosition
1002
+ * @param {RelativePosition} pos1 position 1
1003
+ * @param {RelativePosition} pos2 position 2
1004
+ * @param {Number} eps x, y, z epsilon in meters (default: 1e-3 [= 1mm])
1005
+ */
890
1006
  static equals(pos1, pos2, eps = EPS_MM) {
891
1007
  if (pos1 === null && pos1 === pos2) {
892
1008
  return true;
@@ -922,6 +1038,9 @@ class GeoRef {
922
1038
  __publicField(this, "heading", 0);
923
1039
  this.origin = origin;
924
1040
  }
1041
+ /**
1042
+ * LocalPosition in ENU frame
1043
+ */
925
1044
  localToWorld(localPosition) {
926
1045
  const enuTranslationScaled = maths.Vector3.multiplyScalar(localPosition, this.scale);
927
1046
  const rotationOffset = maths.Quaternion.fromAxisAngle([0, 0, 1], this.heading);
@@ -930,6 +1049,9 @@ class GeoRef {
930
1049
  const ecef = maths.Vector3.sum(this.origin.ecef, ecefTranslation);
931
1050
  return Coordinates.fromECEF(ecef);
932
1051
  }
1052
+ /**
1053
+ * LocalPosition in ENU frame
1054
+ */
933
1055
  worldToLocal(coords) {
934
1056
  const rotationOffset = maths.Quaternion.fromAxisAngle([0, 0, 1], -this.heading);
935
1057
  const ecefToEnuRotationOrigin = maths.Quaternion.multiply(this.origin.ecefToEnuRotation, rotationOffset);
@@ -1047,6 +1169,9 @@ class Attitude {
1047
1169
  clone() {
1048
1170
  return new Attitude(this.quaternion.slice(0), this.time, this.accuracy);
1049
1171
  }
1172
+ /**
1173
+ * Calculate the relative attitude between two given attitudes
1174
+ */
1050
1175
  static diff(attitudeStart, attitudeEnd) {
1051
1176
  const quaternionDiff = maths.Quaternion.multiply(
1052
1177
  maths.Quaternion.inverse(attitudeStart.quaternion),
@@ -1088,6 +1213,11 @@ class AbsoluteHeading {
1088
1213
  this.accuracy
1089
1214
  );
1090
1215
  }
1216
+ /**
1217
+ * Compares two AbsoluteHeading
1218
+ * @param {AbsoluteHeading} heading1 heading 1
1219
+ * @param {AbsoluteHeading} heading2 heading 2
1220
+ */
1091
1221
  static equals(heading1, heading2) {
1092
1222
  if (heading1 === null && heading1 === heading2) {
1093
1223
  return true;
@@ -1145,12 +1275,18 @@ class GeoGraphEdge extends utils.GraphEdge {
1145
1275
  Level.checkType(level);
1146
1276
  this._level = level;
1147
1277
  }
1278
+ /**
1279
+ * Get edge bearing from vertex1 to vertex2
1280
+ */
1148
1281
  get bearing() {
1149
1282
  if (!this._computedSizeAndBearing) {
1150
1283
  this._computeSizeAndBearing();
1151
1284
  }
1152
1285
  return this._bearing;
1153
1286
  }
1287
+ /**
1288
+ * get edge length
1289
+ */
1154
1290
  get length() {
1155
1291
  if (!this._computedSizeAndBearing) {
1156
1292
  this._computeSizeAndBearing();
@@ -1179,6 +1315,9 @@ class GeoGraphVertex extends utils.GraphVertex {
1179
1315
  bearingTo(other) {
1180
1316
  return this.coords.bearingTo(other.coords);
1181
1317
  }
1318
+ /**
1319
+ * Does not include "edges" property
1320
+ */
1182
1321
  toJson() {
1183
1322
  return this.coords.toCompressedJson();
1184
1323
  }
@@ -1202,6 +1341,9 @@ class GeoGraphVertex extends utils.GraphVertex {
1202
1341
  }
1203
1342
  this.coords.level = tmpLevel;
1204
1343
  }
1344
+ /**
1345
+ * We suppose inferVertexLevelFromEdges() was called before
1346
+ */
1205
1347
  inferVertexLevelByNeighboors() {
1206
1348
  const { level } = this.coords;
1207
1349
  if (level === null || !Level.isRange(level)) {
@@ -1218,6 +1360,9 @@ class GeoGraphVertex extends utils.GraphVertex {
1218
1360
  }
1219
1361
  return true;
1220
1362
  }
1363
+ /**
1364
+ * We suppose inferVertexLevelFromEdges() and inferVertexLevelByNeighboors() were called before
1365
+ */
1221
1366
  inferVertexLevelByRecursion() {
1222
1367
  const { level } = this.coords;
1223
1368
  if (level === null || !Level.isRange(level)) {
@@ -1282,13 +1427,21 @@ class GeoGraph extends utils.Graph {
1282
1427
  return boundingBox;
1283
1428
  }
1284
1429
  toCompressedJson() {
1430
+ const createEdgeExtras = (edge) => {
1431
+ const extras = {};
1432
+ if (edge.isOneway) {
1433
+ extras.oneway = true;
1434
+ }
1435
+ return extras;
1436
+ };
1285
1437
  return {
1286
1438
  vertices: this.vertices.map((vertex) => vertex.toJson()),
1287
1439
  edges: this.edges.map((edge) => {
1288
1440
  const vertex1Idx = this.vertices.indexOf(edge.vertex1);
1289
1441
  const vertex2Idx = this.vertices.indexOf(edge.vertex2);
1290
- if (edge.isOneway) {
1291
- return [vertex1Idx, vertex2Idx, edge.level, true];
1442
+ const edgeExtras = createEdgeExtras(edge);
1443
+ if (Object.keys(edgeExtras).length > 0) {
1444
+ return [vertex1Idx, vertex2Idx, edge.level, edgeExtras];
1292
1445
  }
1293
1446
  if (edge.level !== null) {
1294
1447
  return [vertex1Idx, vertex2Idx, edge.level];
@@ -1306,8 +1459,9 @@ class GeoGraph extends utils.Graph {
1306
1459
  geograph.vertices[jsonEdge[1]],
1307
1460
  { level: jsonEdge.length > 2 ? jsonEdge[2] : null }
1308
1461
  );
1309
- if (jsonEdge.length > 3 && jsonEdge[3]) {
1310
- edge.isOneway = true;
1462
+ const extras = jsonEdge.length > 3 ? jsonEdge[3] : {};
1463
+ if (typeof extras.oneway !== "undefined") {
1464
+ edge.isOneway = extras.oneway;
1311
1465
  }
1312
1466
  return edge;
1313
1467
  });
@@ -1342,6 +1496,10 @@ class GeoGraph extends utils.Graph {
1342
1496
  }
1343
1497
  return geograph;
1344
1498
  }
1499
+ /**
1500
+ * Create edges From MultiLevel Itinerary for a given level
1501
+ * @param useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)
1502
+ */
1345
1503
  getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
1346
1504
  return this.edges.filter(
1347
1505
  ({ level }) => useMultiLevelEdges ? Level.intersect(targetLevel, level) : Level.contains(targetLevel, level)
@@ -1369,7 +1527,7 @@ class GeoGraphProjection {
1369
1527
  this.nearestElement = nearestElement;
1370
1528
  }
1371
1529
  }
1372
- const _GeoGraphProjectionHandler = class {
1530
+ const _GeoGraphProjectionHandler = class _GeoGraphProjectionHandler {
1373
1531
  constructor(graph = null) {
1374
1532
  __publicField(this, "graph", null);
1375
1533
  __publicField(this, "_maxDistance", Number.MAX_VALUE);
@@ -1388,19 +1546,25 @@ const _GeoGraphProjectionHandler = class {
1388
1546
  get maxDistance() {
1389
1547
  return this._maxDistance;
1390
1548
  }
1391
- _shouldProjectOnEdgeAndNodes(edge, location, useBearing, useMultiLevelSegments, acceptEdgeFn) {
1549
+ /**
1550
+ * Check if the specified edge and its vertices can be used for projection
1551
+ * @returns an array of two elements.
1552
+ * First is true if projection will be used on the specified edge, false otherwise.
1553
+ * Second is true if projection will be used on the vertices of the specified edge, false otherwise.
1554
+ */
1555
+ _shouldProjectOnEdgeAndVertices(edge, location, useBearing, useMultiLevelSegments, acceptEdgeFn) {
1392
1556
  if (!acceptEdgeFn(edge)) {
1393
1557
  return [false, false, false];
1394
1558
  }
1395
1559
  let checkEdge = Level.intersect(location.level, edge.level);
1396
- let checkNode1 = Level.intersect(location.level, edge.vertex1.coords.level);
1397
- let checkNode2 = Level.intersect(location.level, edge.vertex2.coords.level);
1398
- checkNode1 = checkNode1 || edge.vertex1.io && location.level === null;
1399
- checkNode2 = checkNode2 || edge.vertex2.io && location.level === null;
1560
+ let checkVertex1 = Level.intersect(location.level, edge.vertex1.coords.level);
1561
+ let checkVertex2 = Level.intersect(location.level, edge.vertex2.coords.level);
1562
+ checkVertex1 = checkVertex1 || edge.vertex1.io && location.level === null;
1563
+ checkVertex2 = checkVertex2 || edge.vertex2.io && location.level === null;
1400
1564
  if (!useMultiLevelSegments) {
1401
1565
  checkEdge = checkEdge && !Level.isRange(edge.level);
1402
- checkNode1 = checkNode1 && !Level.isRange(edge.vertex1.coords.level);
1403
- checkNode2 = checkNode2 && !Level.isRange(edge.vertex2.coords.level);
1566
+ checkVertex1 = checkVertex1 && !Level.isRange(edge.vertex1.coords.level);
1567
+ checkVertex2 = checkVertex2 && !Level.isRange(edge.vertex2.coords.level);
1404
1568
  }
1405
1569
  if (useBearing) {
1406
1570
  if (checkEdge) {
@@ -1409,21 +1573,31 @@ const _GeoGraphProjectionHandler = class {
1409
1573
  checkEdge = false;
1410
1574
  }
1411
1575
  }
1412
- checkNode1 = false;
1413
- checkNode2 = false;
1576
+ checkVertex1 = false;
1577
+ checkVertex2 = false;
1414
1578
  }
1415
- return [checkEdge, checkNode1, checkNode2];
1579
+ return [checkEdge, checkVertex1, checkVertex2];
1416
1580
  }
1417
1581
  static _assignLatLngLevel(fromCoordinates, toCoordinates) {
1418
1582
  toCoordinates.lat = fromCoordinates.lat;
1419
1583
  toCoordinates.lng = fromCoordinates.lng;
1420
1584
  toCoordinates.level = Level.clone(fromCoordinates.level);
1421
1585
  }
1422
- static _handleLevelsWithIONodes(projection, location, projectionNode) {
1423
- if (location.level === null && projectionNode.io) {
1586
+ /**
1587
+ * IO Vertices are typical because they have a non-null level but projection car works on them.
1588
+ * This function handles the case where the projection is on an IO vertex and a location with
1589
+ * a null level is required.
1590
+ */
1591
+ static _handleLevelsWithIOVertices(projection, location, projectionVertex) {
1592
+ if (location.level === null && projectionVertex.io) {
1424
1593
  projection.level = null;
1425
1594
  }
1426
1595
  }
1596
+ /**
1597
+ * Main function for map-matching, the networks have to be set before calling this function
1598
+ * The function will returns a GraphProjection object given a coordinates object and a set
1599
+ * of options (useDistance, useBearing, useMultiLevelSegments, acceptEdgeFn).
1600
+ */
1427
1601
  getProjection(location, useDistance = false, useBearing = false, useMultiLevelSegments = true, acceptEdgeFn = () => true) {
1428
1602
  if (this.graph === null) {
1429
1603
  throw new Error("Graph has not been set yet");
@@ -1438,33 +1612,33 @@ const _GeoGraphProjectionHandler = class {
1438
1612
  return distanceOfNewProjection < distanceFromNearestElement && (!useDistance || distanceOfNewProjection <= this._maxDistance);
1439
1613
  };
1440
1614
  for (const edge of this.graph.edges) {
1441
- const [checkEdge, checkNode1, checkNode2] = this._shouldProjectOnEdgeAndNodes(
1615
+ const [checkEdge, checkVertex1, checkVertex2] = this._shouldProjectOnEdgeAndVertices(
1442
1616
  edge,
1443
1617
  location,
1444
1618
  useBearing,
1445
1619
  useMultiLevelSegments,
1446
1620
  acceptEdgeFn
1447
1621
  );
1448
- if (checkNode1) {
1449
- const distNode1 = location.distanceTo(edge.vertex1.coords);
1450
- if (isProjectionBetter(distNode1) || distNode1 <= EPS_MM) {
1451
- distanceFromNearestElement = distNode1;
1622
+ if (checkVertex1) {
1623
+ const distVertex1 = location.distanceTo(edge.vertex1.coords);
1624
+ if (isProjectionBetter(distVertex1) || distVertex1 <= EPS_MM) {
1625
+ distanceFromNearestElement = distVertex1;
1452
1626
  nearestElement = edge.vertex1;
1453
1627
  _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex1.coords, projection);
1454
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex1);
1455
- if (distNode1 <= EPS_MM) {
1628
+ _GeoGraphProjectionHandler._handleLevelsWithIOVertices(projection, location, edge.vertex1);
1629
+ if (distVertex1 <= EPS_MM) {
1456
1630
  break;
1457
1631
  }
1458
1632
  }
1459
1633
  }
1460
- if (checkNode2) {
1461
- const distNode2 = location.distanceTo(edge.vertex2.coords);
1462
- if (isProjectionBetter(distNode2) || distNode2 <= EPS_MM) {
1463
- distanceFromNearestElement = distNode2;
1634
+ if (checkVertex2) {
1635
+ const distVertex2 = location.distanceTo(edge.vertex2.coords);
1636
+ if (isProjectionBetter(distVertex2) || distVertex2 <= EPS_MM) {
1637
+ distanceFromNearestElement = distVertex2;
1464
1638
  nearestElement = edge.vertex2;
1465
1639
  _GeoGraphProjectionHandler._assignLatLngLevel(edge.vertex2.coords, projection);
1466
- _GeoGraphProjectionHandler._handleLevelsWithIONodes(projection, location, edge.vertex2);
1467
- if (distNode2 <= EPS_MM) {
1640
+ _GeoGraphProjectionHandler._handleLevelsWithIOVertices(projection, location, edge.vertex2);
1641
+ if (distVertex2 <= EPS_MM) {
1468
1642
  break;
1469
1643
  }
1470
1644
  }
@@ -1496,10 +1670,10 @@ const _GeoGraphProjectionHandler = class {
1496
1670
  );
1497
1671
  }
1498
1672
  };
1499
- let GeoGraphProjectionHandler = _GeoGraphProjectionHandler;
1500
- __publicField(GeoGraphProjectionHandler, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
1673
+ __publicField(_GeoGraphProjectionHandler, "_updateProjectionLevelFromEdge", (_edge, _projection) => {
1501
1674
  _projection.level = Level.clone(_edge.level);
1502
1675
  });
1676
+ let GeoGraphProjectionHandler = _GeoGraphProjectionHandler;
1503
1677
  class GeoGraphItinerary extends GeoGraph {
1504
1678
  constructor(start, end, vertices, edges, edgesWeights) {
1505
1679
  super(vertices, edges);
@@ -1522,7 +1696,7 @@ class GeoGraphItinerary extends GeoGraph {
1522
1696
  const prevVertex = arr[idx - 1];
1523
1697
  const edge = GeoGraphEdge.getEdgeByVertices(prevVertex.edges, prevVertex, vertex);
1524
1698
  if (!edge) {
1525
- Logger__default.default.error("Cannot retrieve edge to create itinerary");
1699
+ Logger.error("Cannot retrieve edge to create itinerary");
1526
1700
  return;
1527
1701
  }
1528
1702
  edges.push(new GeoGraphEdge(
@@ -1543,13 +1717,13 @@ class NoRouteFoundError extends Error {
1543
1717
  }
1544
1718
  get startStr() {
1545
1719
  if (this.start instanceof GeoGraphVertex) {
1546
- return `GraphNode ${this.start.coords.toString()}`;
1720
+ return `GeoGraphVertex ${this.start.coords.toString()}`;
1547
1721
  }
1548
1722
  return this.start.toString();
1549
1723
  }
1550
1724
  get endStr() {
1551
1725
  if (this.end instanceof GeoGraphVertex) {
1552
- return `GraphNode ${this.end.coords.toString()}`;
1726
+ return `GeoGraphVertex ${this.end.coords.toString()}`;
1553
1727
  }
1554
1728
  return this.end.toString();
1555
1729
  }
@@ -1561,7 +1735,7 @@ class NoRouteFoundError extends Error {
1561
1735
  return message;
1562
1736
  }
1563
1737
  }
1564
- const _GeoGraphRouter = class {
1738
+ const _GeoGraphRouter = class _GeoGraphRouter {
1565
1739
  constructor(graph) {
1566
1740
  __publicField(this, "_mapMatching");
1567
1741
  __publicField(this, "_graph");
@@ -1720,11 +1894,11 @@ const _GeoGraphRouter = class {
1720
1894
  return GeoGraphItinerary.fromGraphVertices(start.coords, end.coords, path, edgesWeights);
1721
1895
  }
1722
1896
  };
1723
- let GeoGraphRouter = _GeoGraphRouter;
1724
- __publicField(GeoGraphRouter, "DEFAULT_OPTIONS", {
1897
+ __publicField(_GeoGraphRouter, "DEFAULT_OPTIONS", {
1725
1898
  projectionMaxDistance: 50,
1726
1899
  weightEdgeFn: (edge) => edge.length
1727
1900
  });
1901
+ let GeoGraphRouter = _GeoGraphRouter;
1728
1902
  exports.AbsoluteHeading = AbsoluteHeading;
1729
1903
  exports.Attitude = Attitude;
1730
1904
  exports.BoundingBox = BoundingBox;