@wemap/routers 11.5.0 → 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.mjs CHANGED
@@ -237,6 +237,8 @@ class Leg {
237
237
  stepsGenerationRules
238
238
  });
239
239
  }
240
+ // TODO: Remove when possible...
241
+ // Livemap specific
240
242
  multiplyLevel(levelFactor) {
241
243
  this.from.coords.level = Level.multiplyBy(this.from.coords.level, levelFactor);
242
244
  this.to.coords.level = Level.multiplyBy(this.to.coords.level, levelFactor);
@@ -277,6 +279,7 @@ class Leg {
277
279
  firstStep: stepId === 0,
278
280
  lastStep: stepId === stepsInfo.length - 1,
279
281
  distance,
282
+ // stepInfo.distance is overwritten
280
283
  duration: stepInfo.duration || getDurationFromLength(distance),
281
284
  levelChange: stepInfo.levelChange || null,
282
285
  extras: stepInfo.extras || null
@@ -376,6 +379,9 @@ class Itinerary {
376
379
  legs
377
380
  });
378
381
  }
382
+ /**
383
+ * Convert lat/lng/level? points to Itinerary
384
+ */
379
385
  static fromOrderedPointsArray(points, start, end) {
380
386
  const pointToCoordinates = (point) => new Coordinates(point[0], point[1], null, point[2]);
381
387
  return this.fromOrderedCoordinates(
@@ -384,6 +390,9 @@ class Itinerary {
384
390
  pointToCoordinates(end)
385
391
  );
386
392
  }
393
+ /**
394
+ * Convert ordered Coordinates to Itinerary
395
+ */
387
396
  static fromOrderedCoordinates(coords, from, to, mode = "WALK") {
388
397
  const leg = new Leg({
389
398
  from: { coords: from },
@@ -438,11 +447,15 @@ class Itinerary {
438
447
  legs: [leg]
439
448
  });
440
449
  }
450
+ // TODO: Remove when possible...
451
+ // Livemap specific
441
452
  multiplyLevel(levelFactor) {
442
453
  this.from.level = Level.multiplyBy(this.from.level, levelFactor);
443
454
  this.to.level = Level.multiplyBy(this.to.level, levelFactor);
444
455
  this.legs.forEach((leg) => leg.multiplyLevel(levelFactor));
445
456
  }
457
+ // TODO: Remove when possible...
458
+ // Livemap specific
446
459
  forceUnknownLevelTo0() {
447
460
  this.from.level = this.from.level || 0;
448
461
  this.to.level = this.to.level || 0;
@@ -474,6 +487,14 @@ class Itinerary {
474
487
  }
475
488
  };
476
489
  }
490
+ /**
491
+ * Update steps info thanks to the coordinates of the whole itinerary.
492
+ * This method will update:
493
+ * - all steps number
494
+ * - first/last steps
495
+ * - previousBearing/nextBearing/angle of first and last step of each leg
496
+ * - distance/duration of first and last step of each leg
497
+ */
477
498
  updateStepsFromLegs() {
478
499
  const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
479
500
  const steps = this.legs.map((leg) => leg.steps).flat();
@@ -558,6 +579,8 @@ class RouterResponse {
558
579
  error: json.error
559
580
  });
560
581
  }
582
+ // TODO: Remove when possible...
583
+ // Livemap specific
561
584
  multiplyLevel(levelFactor) {
562
585
  this.from.level = Level.multiplyBy(this.from.level, levelFactor);
563
586
  this.to.level = Level.multiplyBy(this.to.level, levelFactor);
@@ -571,7 +594,7 @@ const DEFAULT_WAY_SELECTOR = (way) => {
571
594
  const isElevatorArea = way.tags.highway === "elevator" && way.isArea;
572
595
  return HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) && !isElevatorArea && !["no", "private"].includes(way.tags.access) || way.tags.footway === "sidewalk" || way.tags.public_transport === "platform" || way.tags.railway === "platform";
573
596
  };
574
- const _OsmGraph = class extends GeoGraph {
597
+ const _OsmGraph = class _OsmGraph extends GeoGraph {
575
598
  getVertexByCoords(coords) {
576
599
  return GeoGraph.getVertexByCoords(this.vertices, coords);
577
600
  }
@@ -733,9 +756,9 @@ const _OsmGraph = class extends GeoGraph {
733
756
  }
734
757
  }
735
758
  };
759
+ __publicField(_OsmGraph, "HIGHWAYS_PEDESTRIANS", HIGHWAYS_PEDESTRIANS);
760
+ __publicField(_OsmGraph, "DEFAULT_WAY_SELECTOR", DEFAULT_WAY_SELECTOR);
736
761
  let OsmGraph = _OsmGraph;
737
- __publicField(OsmGraph, "HIGHWAYS_PEDESTRIANS", HIGHWAYS_PEDESTRIANS);
738
- __publicField(OsmGraph, "DEFAULT_WAY_SELECTOR", DEFAULT_WAY_SELECTOR);
739
762
  const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previousStep) => {
740
763
  var _a, _b, _c, _d, _e;
741
764
  const edges = graphItinerary.edges;
@@ -800,7 +823,7 @@ const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previous
800
823
  ...forceEndOfLevelChange && { forceEndOfLevelChange }
801
824
  };
802
825
  };
803
- const _WemapOsmRouter = class extends GeoGraphRouter {
826
+ const _WemapOsmRouter = class _WemapOsmRouter extends GeoGraphRouter {
804
827
  constructor(graph) {
805
828
  super(graph);
806
829
  }
@@ -911,10 +934,10 @@ const _WemapOsmRouter = class extends GeoGraphRouter {
911
934
  );
912
935
  }
913
936
  };
937
+ __publicField(_WemapOsmRouter, "DEFAULT_OPTIONS", _WemapOsmRouter.buildOptions());
938
+ __publicField(_WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", _WemapOsmRouter.buildOptions({ useStairs: false }));
939
+ __publicField(_WemapOsmRouter, "DEFAULT_TRIP_OPTIONS", _WemapOsmRouter.buildTripOptions());
914
940
  let WemapOsmRouter = _WemapOsmRouter;
915
- __publicField(WemapOsmRouter, "DEFAULT_OPTIONS", _WemapOsmRouter.buildOptions());
916
- __publicField(WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", _WemapOsmRouter.buildOptions({ useStairs: false }));
917
- __publicField(WemapOsmRouter, "DEFAULT_TRIP_OPTIONS", _WemapOsmRouter.buildTripOptions());
918
941
  class RemoteRouter {
919
942
  }
920
943
  class RemoteRouterServerUnreachable extends Error {
@@ -1014,9 +1037,17 @@ function parseWKTGeometry(wktGeometry) {
1014
1037
  });
1015
1038
  }
1016
1039
  class CitywayRemoteRouter extends RemoteRouter {
1040
+ /**
1041
+ * @override
1042
+ */
1017
1043
  get rname() {
1018
1044
  return "cityway";
1019
1045
  }
1046
+ /**
1047
+ * @override
1048
+ * @throws {RoutingModeCorrespondanceNotFound}
1049
+ * @throws {RemoteRouterServerUnreachable}
1050
+ */
1020
1051
  async getItineraries(endpointUrl, mode, waypoints) {
1021
1052
  const url = this.getURL(endpointUrl, mode, waypoints);
1022
1053
  const res = await fetch(url).catch(() => {
@@ -1027,6 +1058,9 @@ class CitywayRemoteRouter extends RemoteRouter {
1027
1058
  });
1028
1059
  return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);
1029
1060
  }
1061
+ /**
1062
+ * @throws {RoutingModeCorrespondanceNotFound}
1063
+ */
1030
1064
  getURL(endpointUrl, mode, waypoints) {
1031
1065
  const citywayMode = inputModeCorrespondance$2.get(mode);
1032
1066
  if (!citywayMode) {
@@ -1043,6 +1077,11 @@ class CitywayRemoteRouter extends RemoteRouter {
1043
1077
  search = (search ? `${search}&` : "?") + `${fromPlace}&${toPlace}&${queryMode}`;
1044
1078
  return `${url.origin}${url.pathname}${search}`;
1045
1079
  }
1080
+ /**
1081
+ * Generate multi itineraries from Cityway JSON
1082
+ * @returns {!RouterResponse}
1083
+ * @example https://preprod.api.lia2.cityway.fr/journeyplanner/api/opt/PlanTrips/json?DepartureLatitude=49.51509388236216&DepartureLongitude=0.09341749619366316&ArrivalLatitude=49.5067090188444&ArrivalLongitude=0.1694842115417831&DepartureType=COORDINATES&ArrivalType=COORDINATES
1084
+ */
1046
1085
  createRouterResponseFromJson(json, from, to) {
1047
1086
  const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
1048
1087
  if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {
@@ -1164,6 +1203,10 @@ class CitywayRemoteRouter extends RemoteRouter {
1164
1203
  }
1165
1204
  return routerResponse;
1166
1205
  }
1206
+ /**
1207
+ * @param {string} iso8601Duration
1208
+ * @see https://stackoverflow.com/a/29153059/2239938
1209
+ */
1167
1210
  parseDuration(iso8601Duration) {
1168
1211
  const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
1169
1212
  const matches = iso8601Duration.match(iso8601DurationRegex);
@@ -1179,9 +1222,16 @@ class CitywayRemoteRouter extends RemoteRouter {
1179
1222
  }
1180
1223
  const CitywayRemoteRouter$1 = new CitywayRemoteRouter();
1181
1224
  class DeutscheBahnRemoteRouter extends RemoteRouter {
1225
+ /**
1226
+ * @override
1227
+ */
1182
1228
  get rname() {
1183
1229
  return "deutsche-bahn";
1184
1230
  }
1231
+ /**
1232
+ * @override
1233
+ * @throws {RemoteRouterServerUnreachable}
1234
+ */
1185
1235
  async getItineraries(endpointUrl, mode, waypoints) {
1186
1236
  const url = this.getURL(endpointUrl, mode, waypoints);
1187
1237
  const res = await fetch(url).catch(() => {
@@ -1237,7 +1287,7 @@ routingModeCorrespondance.set("Funicular", "FUNICULAR");
1237
1287
  routingModeCorrespondance.set("LocalTrain", "TRAIN");
1238
1288
  routingModeCorrespondance.set("LongDistanceTrain", "TRAIN");
1239
1289
  routingModeCorrespondance.set("Metro", "METRO");
1240
- routingModeCorrespondance.set("M\xE9tro", "METRO");
1290
+ routingModeCorrespondance.set("Métro", "METRO");
1241
1291
  routingModeCorrespondance.set("RailShuttle", "TRAIN");
1242
1292
  routingModeCorrespondance.set("RapidTransit", "BUS");
1243
1293
  routingModeCorrespondance.set("Shuttle", "BUS");
@@ -1292,9 +1342,16 @@ function dateStringToTimestamp(stringDate, timeZone) {
1292
1342
  ).getTime();
1293
1343
  }
1294
1344
  class IdfmRemoteRouter extends RemoteRouter {
1345
+ /**
1346
+ * @override
1347
+ */
1295
1348
  get rname() {
1296
1349
  return "idfm";
1297
1350
  }
1351
+ /**
1352
+ * @throws {IdfmRemoteRouterTokenError}
1353
+ * @throws {RemoteRouterServerUnreachable}
1354
+ */
1298
1355
  async getItineraries(endpointUrl, mode, waypoints, options = {}) {
1299
1356
  const url = this.getURL(endpointUrl, mode, waypoints, options);
1300
1357
  const res = await fetch(url, {
@@ -1383,6 +1440,11 @@ class IdfmRemoteRouter extends RemoteRouter {
1383
1440
  to
1384
1441
  };
1385
1442
  }
1443
+ /**
1444
+ * Since the IDFM API does not provide coords for each step, we need to compute them
1445
+ * We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step
1446
+ * @param {Leg} leg
1447
+ */
1386
1448
  findStepsCoord(legCoords, steps) {
1387
1449
  const coords = legCoords;
1388
1450
  const duplicatedCoords = [...coords];
@@ -1508,9 +1570,16 @@ inputModeCorrespondance$1.set("BIKE", "bike");
1508
1570
  inputModeCorrespondance$1.set("BUS", "bus");
1509
1571
  inputModeCorrespondance$1.set("MULTI", "walking");
1510
1572
  class OsrmRemoteRouter extends RemoteRouter {
1573
+ /**
1574
+ * @override
1575
+ */
1511
1576
  get rname() {
1512
1577
  return "osrm";
1513
1578
  }
1579
+ /**
1580
+ * @throws {RemoteRouterServerUnreachable}
1581
+ * @throws {RoutingModeCorrespondanceNotFound}
1582
+ */
1514
1583
  async getItineraries(endpointUrl, mode, waypoints, options = {}) {
1515
1584
  const url = this.getURL(endpointUrl, mode, waypoints, options);
1516
1585
  const res = await fetch(url).catch(() => {
@@ -1524,6 +1593,9 @@ class OsrmRemoteRouter extends RemoteRouter {
1524
1593
  const osrmMode = inputModeCorrespondance$1.get(mode);
1525
1594
  return this.createRouterResponseFromJson(jsonResponse, from, to, osrmMode);
1526
1595
  }
1596
+ /**
1597
+ * @throws {RoutingModeCorrespondanceNotFound}
1598
+ */
1527
1599
  getURL(endpointUrl, mode, waypoints, options = {}) {
1528
1600
  let osrmMode = inputModeCorrespondance$1.get(mode);
1529
1601
  if (!osrmMode) {
@@ -1546,6 +1618,10 @@ class OsrmRemoteRouter extends RemoteRouter {
1546
1618
  }
1547
1619
  return [lng, lat, level];
1548
1620
  }
1621
+ /**
1622
+ * @param {object} json
1623
+ * @returns {Coordinates}
1624
+ */
1549
1625
  jsonToCoordinates(json) {
1550
1626
  const coords = new Coordinates(json[1], json[0]);
1551
1627
  if (json.length > 2) {
@@ -1584,6 +1660,9 @@ class OsrmRemoteRouter extends RemoteRouter {
1584
1660
  message
1585
1661
  };
1586
1662
  }
1663
+ /**
1664
+ * @deprecated
1665
+ */
1587
1666
  itineraryToOsrmJson(itinerary) {
1588
1667
  const lastLegId = itinerary.legs.length - 1;
1589
1668
  const itinerarySteps = itinerary.steps;
@@ -1707,6 +1786,10 @@ class OtpRemoteRouter extends RemoteRouter {
1707
1786
  get rname() {
1708
1787
  return "otp";
1709
1788
  }
1789
+ /**
1790
+ * @throws {RemoteRouterServerUnreachable}
1791
+ * @throws {RoutingModeCorrespondanceNotFound}
1792
+ */
1710
1793
  async getItineraries(endpointUrl, mode, waypoints) {
1711
1794
  const url = this.getURL(endpointUrl, mode, waypoints);
1712
1795
  const res = await fetch(url).catch(() => {
@@ -1717,6 +1800,9 @@ class OtpRemoteRouter extends RemoteRouter {
1717
1800
  });
1718
1801
  return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);
1719
1802
  }
1803
+ /**
1804
+ * @throws {RoutingModeCorrespondanceNotFound}
1805
+ */
1720
1806
  getURL(endpointUrl, mode, waypoints) {
1721
1807
  const otpMode = inputModeCorrespondance.get(mode);
1722
1808
  if (!otpMode) {
@@ -1733,6 +1819,9 @@ class OtpRemoteRouter extends RemoteRouter {
1733
1819
  search = (search ? `${search}&` : "?") + `${fromPlace}&${toPlace}&${queryMode}`;
1734
1820
  return `${url.origin}${url.pathname}${search}`;
1735
1821
  }
1822
+ /**
1823
+ * Generate multi itineraries from OTP JSON
1824
+ */
1736
1825
  createRouterResponseFromJson(json, from, to) {
1737
1826
  const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
1738
1827
  const { plan: jsonPlan } = json;
@@ -1864,6 +1953,11 @@ class RemoteRouterManager {
1864
1953
  getRouterByName(name) {
1865
1954
  return remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
1866
1955
  }
1956
+ /**
1957
+ * @throws {RemoteRouterServerUnreachable}
1958
+ * @throws {RoutingModeCorrespondanceNotFound}
1959
+ * @throws {IdfmRemoteRouterTokenError}
1960
+ */
1867
1961
  async getItineraries(name, endpointUrl, mode, waypoints, options) {
1868
1962
  const router = this.getRouterByName(name);
1869
1963
  if (!router) {
@@ -1871,6 +1965,11 @@ class RemoteRouterManager {
1871
1965
  }
1872
1966
  return router.getItineraries(endpointUrl, mode, waypoints, options);
1873
1967
  }
1968
+ /**
1969
+ * @throws {RemoteRouterServerUnreachable}
1970
+ * @throws {RoutingModeCorrespondanceNotFound}
1971
+ * @throws {IdfmRemoteRouterTokenError}
1972
+ */
1874
1973
  async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
1875
1974
  let routerResponse;
1876
1975
  for (const { name, endpointUrl } of remoteRouters2) {
@@ -2176,6 +2275,12 @@ class CustomNetworkMap {
2176
2275
  isPointInside(coordinates) {
2177
2276
  return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);
2178
2277
  }
2278
+ /**
2279
+ * Get the list of entry points sorted by the lowest distance between:
2280
+ * start -> entry point -> end
2281
+ * (as the crow flies)
2282
+ *
2283
+ */
2179
2284
  getOrderedEntryPointsSortedByDistance(start, end) {
2180
2285
  const entryPointsCopy = [...this.entryPoints];
2181
2286
  const levelDiffFactor = 50;
@@ -2189,6 +2294,17 @@ class CustomNetworkMap {
2189
2294
  return distance2D + levelDiff * levelDiffFactor;
2190
2295
  });
2191
2296
  }
2297
+ /**
2298
+ * Get the best itinerary from any entry point to an end coordinates.
2299
+ *
2300
+ * The algorithm works as following:
2301
+ * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
2302
+ * 2 - Try to calculate an itinerary from the first entry point to the end coordinates.
2303
+ * 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.
2304
+ *
2305
+ * /!\ start is only used to sort the entry points (step 1).
2306
+ *
2307
+ */
2192
2308
  getBestItineraryFromEntryPointsToEnd(start, end, options) {
2193
2309
  const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
2194
2310
  for (const entryPoint of sortedEntryPoints) {
@@ -2203,6 +2319,17 @@ class CustomNetworkMap {
2203
2319
  `No route found from entry points to ${end.toString()} in map: ${this.name}`
2204
2320
  );
2205
2321
  }
2322
+ /**
2323
+ * Get the best itinerary from start coordinates to any entry point.
2324
+ *
2325
+ * The algorithm works as following:
2326
+ * 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
2327
+ * 2 - Try to calculate an itinerary from the start coordinates to the first entry point.
2328
+ * 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.
2329
+ *
2330
+ * /!\ end is only used to sort the entry points (step 1).
2331
+ *
2332
+ */
2206
2333
  getBestItineraryFromStartToEntryPoints(start, end, options) {
2207
2334
  const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
2208
2335
  for (const entryPoint of sortedEntryPoints) {