@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.js +148 -27
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => {
|
|
|
5
5
|
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
6
|
return value;
|
|
7
7
|
};
|
|
8
|
-
Object.
|
|
8
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
9
9
|
const geo = require("@wemap/geo");
|
|
10
10
|
const maths = require("@wemap/maths");
|
|
11
11
|
const salesman = require("@wemap/salesman.js");
|
|
@@ -14,12 +14,6 @@ const Logger = require("@wemap/logger");
|
|
|
14
14
|
const Polyline = require("@mapbox/polyline");
|
|
15
15
|
const pointInPolygon = require("@turf/boolean-point-in-polygon");
|
|
16
16
|
const convexHullFn = require("@turf/convex");
|
|
17
|
-
const _interopDefaultLegacy = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
|
|
18
|
-
const salesman__default = /* @__PURE__ */ _interopDefaultLegacy(salesman);
|
|
19
|
-
const Logger__default = /* @__PURE__ */ _interopDefaultLegacy(Logger);
|
|
20
|
-
const Polyline__default = /* @__PURE__ */ _interopDefaultLegacy(Polyline);
|
|
21
|
-
const pointInPolygon__default = /* @__PURE__ */ _interopDefaultLegacy(pointInPolygon);
|
|
22
|
-
const convexHullFn__default = /* @__PURE__ */ _interopDefaultLegacy(convexHullFn);
|
|
23
17
|
function getDurationFromLength(length, speed = 5) {
|
|
24
18
|
return length / (speed * 1e3 / 3600);
|
|
25
19
|
}
|
|
@@ -245,6 +239,8 @@ class Leg {
|
|
|
245
239
|
stepsGenerationRules
|
|
246
240
|
});
|
|
247
241
|
}
|
|
242
|
+
// TODO: Remove when possible...
|
|
243
|
+
// Livemap specific
|
|
248
244
|
multiplyLevel(levelFactor) {
|
|
249
245
|
this.from.coords.level = geo.Level.multiplyBy(this.from.coords.level, levelFactor);
|
|
250
246
|
this.to.coords.level = geo.Level.multiplyBy(this.to.coords.level, levelFactor);
|
|
@@ -285,6 +281,7 @@ class Leg {
|
|
|
285
281
|
firstStep: stepId === 0,
|
|
286
282
|
lastStep: stepId === stepsInfo.length - 1,
|
|
287
283
|
distance,
|
|
284
|
+
// stepInfo.distance is overwritten
|
|
288
285
|
duration: stepInfo.duration || getDurationFromLength(distance),
|
|
289
286
|
levelChange: stepInfo.levelChange || null,
|
|
290
287
|
extras: stepInfo.extras || null
|
|
@@ -384,6 +381,9 @@ class Itinerary {
|
|
|
384
381
|
legs
|
|
385
382
|
});
|
|
386
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Convert lat/lng/level? points to Itinerary
|
|
386
|
+
*/
|
|
387
387
|
static fromOrderedPointsArray(points, start, end) {
|
|
388
388
|
const pointToCoordinates = (point) => new geo.Coordinates(point[0], point[1], null, point[2]);
|
|
389
389
|
return this.fromOrderedCoordinates(
|
|
@@ -392,6 +392,9 @@ class Itinerary {
|
|
|
392
392
|
pointToCoordinates(end)
|
|
393
393
|
);
|
|
394
394
|
}
|
|
395
|
+
/**
|
|
396
|
+
* Convert ordered Coordinates to Itinerary
|
|
397
|
+
*/
|
|
395
398
|
static fromOrderedCoordinates(coords, from, to, mode = "WALK") {
|
|
396
399
|
const leg = new Leg({
|
|
397
400
|
from: { coords: from },
|
|
@@ -446,11 +449,15 @@ class Itinerary {
|
|
|
446
449
|
legs: [leg]
|
|
447
450
|
});
|
|
448
451
|
}
|
|
452
|
+
// TODO: Remove when possible...
|
|
453
|
+
// Livemap specific
|
|
449
454
|
multiplyLevel(levelFactor) {
|
|
450
455
|
this.from.level = geo.Level.multiplyBy(this.from.level, levelFactor);
|
|
451
456
|
this.to.level = geo.Level.multiplyBy(this.to.level, levelFactor);
|
|
452
457
|
this.legs.forEach((leg) => leg.multiplyLevel(levelFactor));
|
|
453
458
|
}
|
|
459
|
+
// TODO: Remove when possible...
|
|
460
|
+
// Livemap specific
|
|
454
461
|
forceUnknownLevelTo0() {
|
|
455
462
|
this.from.level = this.from.level || 0;
|
|
456
463
|
this.to.level = this.to.level || 0;
|
|
@@ -482,6 +489,14 @@ class Itinerary {
|
|
|
482
489
|
}
|
|
483
490
|
};
|
|
484
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* Update steps info thanks to the coordinates of the whole itinerary.
|
|
494
|
+
* This method will update:
|
|
495
|
+
* - all steps number
|
|
496
|
+
* - first/last steps
|
|
497
|
+
* - previousBearing/nextBearing/angle of first and last step of each leg
|
|
498
|
+
* - distance/duration of first and last step of each leg
|
|
499
|
+
*/
|
|
485
500
|
updateStepsFromLegs() {
|
|
486
501
|
const itineraryCoords = this.coords.filter((coords, idx, arr) => idx === 0 || !arr[idx - 1].equals(coords));
|
|
487
502
|
const steps = this.legs.map((leg) => leg.steps).flat();
|
|
@@ -566,6 +581,8 @@ class RouterResponse {
|
|
|
566
581
|
error: json.error
|
|
567
582
|
});
|
|
568
583
|
}
|
|
584
|
+
// TODO: Remove when possible...
|
|
585
|
+
// Livemap specific
|
|
569
586
|
multiplyLevel(levelFactor) {
|
|
570
587
|
this.from.level = geo.Level.multiplyBy(this.from.level, levelFactor);
|
|
571
588
|
this.to.level = geo.Level.multiplyBy(this.to.level, levelFactor);
|
|
@@ -579,7 +596,7 @@ const DEFAULT_WAY_SELECTOR = (way) => {
|
|
|
579
596
|
const isElevatorArea = way.tags.highway === "elevator" && way.isArea;
|
|
580
597
|
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";
|
|
581
598
|
};
|
|
582
|
-
const _OsmGraph = class extends geo.GeoGraph {
|
|
599
|
+
const _OsmGraph = class _OsmGraph extends geo.GeoGraph {
|
|
583
600
|
getVertexByCoords(coords) {
|
|
584
601
|
return geo.GeoGraph.getVertexByCoords(this.vertices, coords);
|
|
585
602
|
}
|
|
@@ -741,9 +758,9 @@ const _OsmGraph = class extends geo.GeoGraph {
|
|
|
741
758
|
}
|
|
742
759
|
}
|
|
743
760
|
};
|
|
761
|
+
__publicField(_OsmGraph, "HIGHWAYS_PEDESTRIANS", HIGHWAYS_PEDESTRIANS);
|
|
762
|
+
__publicField(_OsmGraph, "DEFAULT_WAY_SELECTOR", DEFAULT_WAY_SELECTOR);
|
|
744
763
|
let OsmGraph = _OsmGraph;
|
|
745
|
-
__publicField(OsmGraph, "HIGHWAYS_PEDESTRIANS", HIGHWAYS_PEDESTRIANS);
|
|
746
|
-
__publicField(OsmGraph, "DEFAULT_WAY_SELECTOR", DEFAULT_WAY_SELECTOR);
|
|
747
764
|
const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previousStep) => {
|
|
748
765
|
var _a, _b, _c, _d, _e;
|
|
749
766
|
const edges = graphItinerary.edges;
|
|
@@ -808,7 +825,7 @@ const buildStepsRules = (graphItinerary) => (currentCoords, nextCoords, previous
|
|
|
808
825
|
...forceEndOfLevelChange && { forceEndOfLevelChange }
|
|
809
826
|
};
|
|
810
827
|
};
|
|
811
|
-
const _WemapOsmRouter = class extends geo.GeoGraphRouter {
|
|
828
|
+
const _WemapOsmRouter = class _WemapOsmRouter extends geo.GeoGraphRouter {
|
|
812
829
|
constructor(graph) {
|
|
813
830
|
super(graph);
|
|
814
831
|
}
|
|
@@ -840,12 +857,12 @@ const _WemapOsmRouter = class extends geo.GeoGraphRouter {
|
|
|
840
857
|
}
|
|
841
858
|
getShortestTrip(waypoints, options = _WemapOsmRouter.DEFAULT_TRIP_OPTIONS) {
|
|
842
859
|
const points = waypoints.map((waypoint) => {
|
|
843
|
-
const point = new
|
|
860
|
+
const point = new salesman.Point(0, 0);
|
|
844
861
|
point.coords = waypoint;
|
|
845
862
|
return point;
|
|
846
863
|
});
|
|
847
864
|
const cache = [];
|
|
848
|
-
const solution =
|
|
865
|
+
const solution = salesman.solve(points, options.tspTempCoeff, void 0, (p, q) => {
|
|
849
866
|
const osmItinerary = this.getShortestPath(
|
|
850
867
|
p.coords,
|
|
851
868
|
q.coords,
|
|
@@ -919,10 +936,10 @@ const _WemapOsmRouter = class extends geo.GeoGraphRouter {
|
|
|
919
936
|
);
|
|
920
937
|
}
|
|
921
938
|
};
|
|
939
|
+
__publicField(_WemapOsmRouter, "DEFAULT_OPTIONS", _WemapOsmRouter.buildOptions());
|
|
940
|
+
__publicField(_WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", _WemapOsmRouter.buildOptions({ useStairs: false }));
|
|
941
|
+
__publicField(_WemapOsmRouter, "DEFAULT_TRIP_OPTIONS", _WemapOsmRouter.buildTripOptions());
|
|
922
942
|
let WemapOsmRouter = _WemapOsmRouter;
|
|
923
|
-
__publicField(WemapOsmRouter, "DEFAULT_OPTIONS", _WemapOsmRouter.buildOptions());
|
|
924
|
-
__publicField(WemapOsmRouter, "WITHOUT_STAIRS_OPTIONS", _WemapOsmRouter.buildOptions({ useStairs: false }));
|
|
925
|
-
__publicField(WemapOsmRouter, "DEFAULT_TRIP_OPTIONS", _WemapOsmRouter.buildTripOptions());
|
|
926
943
|
class RemoteRouter {
|
|
927
944
|
}
|
|
928
945
|
class RemoteRouterServerUnreachable extends Error {
|
|
@@ -1022,9 +1039,17 @@ function parseWKTGeometry(wktGeometry) {
|
|
|
1022
1039
|
});
|
|
1023
1040
|
}
|
|
1024
1041
|
class CitywayRemoteRouter extends RemoteRouter {
|
|
1042
|
+
/**
|
|
1043
|
+
* @override
|
|
1044
|
+
*/
|
|
1025
1045
|
get rname() {
|
|
1026
1046
|
return "cityway";
|
|
1027
1047
|
}
|
|
1048
|
+
/**
|
|
1049
|
+
* @override
|
|
1050
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1051
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1052
|
+
*/
|
|
1028
1053
|
async getItineraries(endpointUrl, mode, waypoints) {
|
|
1029
1054
|
const url = this.getURL(endpointUrl, mode, waypoints);
|
|
1030
1055
|
const res = await fetch(url).catch(() => {
|
|
@@ -1035,13 +1060,16 @@ class CitywayRemoteRouter extends RemoteRouter {
|
|
|
1035
1060
|
});
|
|
1036
1061
|
return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);
|
|
1037
1062
|
}
|
|
1063
|
+
/**
|
|
1064
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1065
|
+
*/
|
|
1038
1066
|
getURL(endpointUrl, mode, waypoints) {
|
|
1039
1067
|
const citywayMode = inputModeCorrespondance$2.get(mode);
|
|
1040
1068
|
if (!citywayMode) {
|
|
1041
1069
|
throw new RoutingModeCorrespondanceNotFound(this.rname, mode);
|
|
1042
1070
|
}
|
|
1043
1071
|
if (waypoints.length > 2) {
|
|
1044
|
-
|
|
1072
|
+
Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
|
|
1045
1073
|
}
|
|
1046
1074
|
const fromPlace = `DepartureLatitude=${waypoints[0].latitude}&DepartureLongitude=${waypoints[0].longitude}`;
|
|
1047
1075
|
const toPlace = `ArrivalLatitude=${waypoints[1].latitude}&ArrivalLongitude=${waypoints[1].longitude}`;
|
|
@@ -1051,6 +1079,11 @@ class CitywayRemoteRouter extends RemoteRouter {
|
|
|
1051
1079
|
search = (search ? `${search}&` : "?") + `${fromPlace}&${toPlace}&${queryMode}`;
|
|
1052
1080
|
return `${url.origin}${url.pathname}${search}`;
|
|
1053
1081
|
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Generate multi itineraries from Cityway JSON
|
|
1084
|
+
* @returns {!RouterResponse}
|
|
1085
|
+
* @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
|
|
1086
|
+
*/
|
|
1054
1087
|
createRouterResponseFromJson(json, from, to) {
|
|
1055
1088
|
const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
|
|
1056
1089
|
if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {
|
|
@@ -1144,7 +1177,7 @@ class CitywayRemoteRouter extends RemoteRouter {
|
|
|
1144
1177
|
distance: jsonLeg.Distance
|
|
1145
1178
|
}];
|
|
1146
1179
|
} else {
|
|
1147
|
-
|
|
1180
|
+
Logger.warn(`[CitywayParser] Unknown leg mode: ${jsonLeg.TransportMode}`);
|
|
1148
1181
|
continue;
|
|
1149
1182
|
}
|
|
1150
1183
|
const leg = new Leg({
|
|
@@ -1172,6 +1205,10 @@ class CitywayRemoteRouter extends RemoteRouter {
|
|
|
1172
1205
|
}
|
|
1173
1206
|
return routerResponse;
|
|
1174
1207
|
}
|
|
1208
|
+
/**
|
|
1209
|
+
* @param {string} iso8601Duration
|
|
1210
|
+
* @see https://stackoverflow.com/a/29153059/2239938
|
|
1211
|
+
*/
|
|
1175
1212
|
parseDuration(iso8601Duration) {
|
|
1176
1213
|
const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
1177
1214
|
const matches = iso8601Duration.match(iso8601DurationRegex);
|
|
@@ -1187,9 +1224,16 @@ class CitywayRemoteRouter extends RemoteRouter {
|
|
|
1187
1224
|
}
|
|
1188
1225
|
const CitywayRemoteRouter$1 = new CitywayRemoteRouter();
|
|
1189
1226
|
class DeutscheBahnRemoteRouter extends RemoteRouter {
|
|
1227
|
+
/**
|
|
1228
|
+
* @override
|
|
1229
|
+
*/
|
|
1190
1230
|
get rname() {
|
|
1191
1231
|
return "deutsche-bahn";
|
|
1192
1232
|
}
|
|
1233
|
+
/**
|
|
1234
|
+
* @override
|
|
1235
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1236
|
+
*/
|
|
1193
1237
|
async getItineraries(endpointUrl, mode, waypoints) {
|
|
1194
1238
|
const url = this.getURL(endpointUrl, mode, waypoints);
|
|
1195
1239
|
const res = await fetch(url).catch(() => {
|
|
@@ -1245,7 +1289,7 @@ routingModeCorrespondance.set("Funicular", "FUNICULAR");
|
|
|
1245
1289
|
routingModeCorrespondance.set("LocalTrain", "TRAIN");
|
|
1246
1290
|
routingModeCorrespondance.set("LongDistanceTrain", "TRAIN");
|
|
1247
1291
|
routingModeCorrespondance.set("Metro", "METRO");
|
|
1248
|
-
routingModeCorrespondance.set("
|
|
1292
|
+
routingModeCorrespondance.set("Métro", "METRO");
|
|
1249
1293
|
routingModeCorrespondance.set("RailShuttle", "TRAIN");
|
|
1250
1294
|
routingModeCorrespondance.set("RapidTransit", "BUS");
|
|
1251
1295
|
routingModeCorrespondance.set("Shuttle", "BUS");
|
|
@@ -1300,9 +1344,16 @@ function dateStringToTimestamp(stringDate, timeZone) {
|
|
|
1300
1344
|
).getTime();
|
|
1301
1345
|
}
|
|
1302
1346
|
class IdfmRemoteRouter extends RemoteRouter {
|
|
1347
|
+
/**
|
|
1348
|
+
* @override
|
|
1349
|
+
*/
|
|
1303
1350
|
get rname() {
|
|
1304
1351
|
return "idfm";
|
|
1305
1352
|
}
|
|
1353
|
+
/**
|
|
1354
|
+
* @throws {IdfmRemoteRouterTokenError}
|
|
1355
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1356
|
+
*/
|
|
1306
1357
|
async getItineraries(endpointUrl, mode, waypoints, options = {}) {
|
|
1307
1358
|
const url = this.getURL(endpointUrl, mode, waypoints, options);
|
|
1308
1359
|
const res = await fetch(url, {
|
|
@@ -1326,7 +1377,7 @@ class IdfmRemoteRouter extends RemoteRouter {
|
|
|
1326
1377
|
}
|
|
1327
1378
|
getURL(endpointUrl, mode, waypoints, options) {
|
|
1328
1379
|
if (waypoints.length > 2) {
|
|
1329
|
-
|
|
1380
|
+
Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
|
|
1330
1381
|
}
|
|
1331
1382
|
const url = new URL(endpointUrl);
|
|
1332
1383
|
const coreParams = new URLSearchParams();
|
|
@@ -1391,6 +1442,11 @@ class IdfmRemoteRouter extends RemoteRouter {
|
|
|
1391
1442
|
to
|
|
1392
1443
|
};
|
|
1393
1444
|
}
|
|
1445
|
+
/**
|
|
1446
|
+
* Since the IDFM API does not provide coords for each step, we need to compute them
|
|
1447
|
+
* We trim the coordinates of the leg with the distance of each step and keep the last result as the coords of the step
|
|
1448
|
+
* @param {Leg} leg
|
|
1449
|
+
*/
|
|
1394
1450
|
findStepsCoord(legCoords, steps) {
|
|
1395
1451
|
const coords = legCoords;
|
|
1396
1452
|
const duplicatedCoords = [...coords];
|
|
@@ -1516,9 +1572,16 @@ inputModeCorrespondance$1.set("BIKE", "bike");
|
|
|
1516
1572
|
inputModeCorrespondance$1.set("BUS", "bus");
|
|
1517
1573
|
inputModeCorrespondance$1.set("MULTI", "walking");
|
|
1518
1574
|
class OsrmRemoteRouter extends RemoteRouter {
|
|
1575
|
+
/**
|
|
1576
|
+
* @override
|
|
1577
|
+
*/
|
|
1519
1578
|
get rname() {
|
|
1520
1579
|
return "osrm";
|
|
1521
1580
|
}
|
|
1581
|
+
/**
|
|
1582
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1583
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1584
|
+
*/
|
|
1522
1585
|
async getItineraries(endpointUrl, mode, waypoints, options = {}) {
|
|
1523
1586
|
const url = this.getURL(endpointUrl, mode, waypoints, options);
|
|
1524
1587
|
const res = await fetch(url).catch(() => {
|
|
@@ -1532,6 +1595,9 @@ class OsrmRemoteRouter extends RemoteRouter {
|
|
|
1532
1595
|
const osrmMode = inputModeCorrespondance$1.get(mode);
|
|
1533
1596
|
return this.createRouterResponseFromJson(jsonResponse, from, to, osrmMode);
|
|
1534
1597
|
}
|
|
1598
|
+
/**
|
|
1599
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1600
|
+
*/
|
|
1535
1601
|
getURL(endpointUrl, mode, waypoints, options = {}) {
|
|
1536
1602
|
let osrmMode = inputModeCorrespondance$1.get(mode);
|
|
1537
1603
|
if (!osrmMode) {
|
|
@@ -1554,6 +1620,10 @@ class OsrmRemoteRouter extends RemoteRouter {
|
|
|
1554
1620
|
}
|
|
1555
1621
|
return [lng, lat, level];
|
|
1556
1622
|
}
|
|
1623
|
+
/**
|
|
1624
|
+
* @param {object} json
|
|
1625
|
+
* @returns {Coordinates}
|
|
1626
|
+
*/
|
|
1557
1627
|
jsonToCoordinates(json) {
|
|
1558
1628
|
const coords = new geo.Coordinates(json[1], json[0]);
|
|
1559
1629
|
if (json.length > 2) {
|
|
@@ -1592,6 +1662,9 @@ class OsrmRemoteRouter extends RemoteRouter {
|
|
|
1592
1662
|
message
|
|
1593
1663
|
};
|
|
1594
1664
|
}
|
|
1665
|
+
/**
|
|
1666
|
+
* @deprecated
|
|
1667
|
+
*/
|
|
1595
1668
|
itineraryToOsrmJson(itinerary) {
|
|
1596
1669
|
const lastLegId = itinerary.legs.length - 1;
|
|
1597
1670
|
const itinerarySteps = itinerary.steps;
|
|
@@ -1715,6 +1788,10 @@ class OtpRemoteRouter extends RemoteRouter {
|
|
|
1715
1788
|
get rname() {
|
|
1716
1789
|
return "otp";
|
|
1717
1790
|
}
|
|
1791
|
+
/**
|
|
1792
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1793
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1794
|
+
*/
|
|
1718
1795
|
async getItineraries(endpointUrl, mode, waypoints) {
|
|
1719
1796
|
const url = this.getURL(endpointUrl, mode, waypoints);
|
|
1720
1797
|
const res = await fetch(url).catch(() => {
|
|
@@ -1725,13 +1802,16 @@ class OtpRemoteRouter extends RemoteRouter {
|
|
|
1725
1802
|
});
|
|
1726
1803
|
return this.createRouterResponseFromJson(jsonResponse, waypoints[0], waypoints[1]);
|
|
1727
1804
|
}
|
|
1805
|
+
/**
|
|
1806
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1807
|
+
*/
|
|
1728
1808
|
getURL(endpointUrl, mode, waypoints) {
|
|
1729
1809
|
const otpMode = inputModeCorrespondance.get(mode);
|
|
1730
1810
|
if (!otpMode) {
|
|
1731
1811
|
throw new RoutingModeCorrespondanceNotFound(this.rname, mode);
|
|
1732
1812
|
}
|
|
1733
1813
|
if (waypoints.length > 2) {
|
|
1734
|
-
|
|
1814
|
+
Logger.warn(`${this.rname} router uses only the first 2 waypoints (asked ${waypoints.length})`);
|
|
1735
1815
|
}
|
|
1736
1816
|
const fromPlace = `fromPlace=${waypoints[0].latitude},${waypoints[0].longitude}`;
|
|
1737
1817
|
const toPlace = `toPlace=${waypoints[1].latitude},${waypoints[1].longitude}`;
|
|
@@ -1741,6 +1821,9 @@ class OtpRemoteRouter extends RemoteRouter {
|
|
|
1741
1821
|
search = (search ? `${search}&` : "?") + `${fromPlace}&${toPlace}&${queryMode}`;
|
|
1742
1822
|
return `${url.origin}${url.pathname}${search}`;
|
|
1743
1823
|
}
|
|
1824
|
+
/**
|
|
1825
|
+
* Generate multi itineraries from OTP JSON
|
|
1826
|
+
*/
|
|
1744
1827
|
createRouterResponseFromJson(json, from, to) {
|
|
1745
1828
|
const routerResponse = new RouterResponse({ routerName: this.rname, from, to });
|
|
1746
1829
|
const { plan: jsonPlan } = json;
|
|
@@ -1752,7 +1835,7 @@ class OtpRemoteRouter extends RemoteRouter {
|
|
|
1752
1835
|
for (const jsonItinerary of jsonPlan.itineraries) {
|
|
1753
1836
|
const legs = [];
|
|
1754
1837
|
for (const jsonLeg of jsonItinerary.legs) {
|
|
1755
|
-
const legCoords =
|
|
1838
|
+
const legCoords = Polyline.decode(jsonLeg.legGeometry.points).map(([lat, lon]) => new geo.Coordinates(lat, lon));
|
|
1756
1839
|
let transportInfo;
|
|
1757
1840
|
let minStepsInfo;
|
|
1758
1841
|
if (isLegPT(jsonLeg)) {
|
|
@@ -1872,6 +1955,11 @@ class RemoteRouterManager {
|
|
|
1872
1955
|
getRouterByName(name) {
|
|
1873
1956
|
return remoteRouters.find((remoteRouter) => remoteRouter.rname === name);
|
|
1874
1957
|
}
|
|
1958
|
+
/**
|
|
1959
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1960
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1961
|
+
* @throws {IdfmRemoteRouterTokenError}
|
|
1962
|
+
*/
|
|
1875
1963
|
async getItineraries(name, endpointUrl, mode, waypoints, options) {
|
|
1876
1964
|
const router = this.getRouterByName(name);
|
|
1877
1965
|
if (!router) {
|
|
@@ -1879,6 +1967,11 @@ class RemoteRouterManager {
|
|
|
1879
1967
|
}
|
|
1880
1968
|
return router.getItineraries(endpointUrl, mode, waypoints, options);
|
|
1881
1969
|
}
|
|
1970
|
+
/**
|
|
1971
|
+
* @throws {RemoteRouterServerUnreachable}
|
|
1972
|
+
* @throws {RoutingModeCorrespondanceNotFound}
|
|
1973
|
+
* @throws {IdfmRemoteRouterTokenError}
|
|
1974
|
+
*/
|
|
1882
1975
|
async getItinerariesWithFallback(remoteRouters2, mode, waypoints, options) {
|
|
1883
1976
|
let routerResponse;
|
|
1884
1977
|
for (const { name, endpointUrl } of remoteRouters2) {
|
|
@@ -1920,7 +2013,7 @@ class WemapMultiRouter {
|
|
|
1920
2013
|
if (ioMapsToTest.length !== targetMaps.length) {
|
|
1921
2014
|
ioMapsToTest.forEach((map) => {
|
|
1922
2015
|
if (map.name && !targetMaps.includes(map.name)) {
|
|
1923
|
-
|
|
2016
|
+
Logger.warn(`CustomNetworkMap "${map.name}" not found in WemapMultiRouter`);
|
|
1924
2017
|
}
|
|
1925
2018
|
});
|
|
1926
2019
|
}
|
|
@@ -1964,7 +2057,7 @@ class WemapMultiRouter {
|
|
|
1964
2057
|
async getItineraries(mode, waypoints, options = null) {
|
|
1965
2058
|
var _a;
|
|
1966
2059
|
if (waypoints.length > 2) {
|
|
1967
|
-
|
|
2060
|
+
Logger.warn(`WemapMultiRouter uses only the first 2 waypoints (asked ${waypoints.length})`);
|
|
1968
2061
|
}
|
|
1969
2062
|
const start = waypoints[0];
|
|
1970
2063
|
const end = waypoints[1];
|
|
@@ -2143,7 +2236,7 @@ class CustomNetworkMap {
|
|
|
2143
2236
|
this.bounds = bounds;
|
|
2144
2237
|
} else {
|
|
2145
2238
|
const polygon = [graph.vertices.map((vertex) => [vertex.coords.lng, vertex.coords.lat])];
|
|
2146
|
-
const convexHull =
|
|
2239
|
+
const convexHull = convexHullFn({ type: "polygon", coordinates: polygon });
|
|
2147
2240
|
if (!convexHull) {
|
|
2148
2241
|
throw new Error(`Cannot calculate convexHull of network "${name}"`);
|
|
2149
2242
|
}
|
|
@@ -2182,8 +2275,14 @@ class CustomNetworkMap {
|
|
|
2182
2275
|
return new CustomNetworkMap(graph, entryPoints, bounds, name);
|
|
2183
2276
|
}
|
|
2184
2277
|
isPointInside(coordinates) {
|
|
2185
|
-
return
|
|
2186
|
-
}
|
|
2278
|
+
return pointInPolygon([coordinates.lng, coordinates.lat], this.bounds);
|
|
2279
|
+
}
|
|
2280
|
+
/**
|
|
2281
|
+
* Get the list of entry points sorted by the lowest distance between:
|
|
2282
|
+
* start -> entry point -> end
|
|
2283
|
+
* (as the crow flies)
|
|
2284
|
+
*
|
|
2285
|
+
*/
|
|
2187
2286
|
getOrderedEntryPointsSortedByDistance(start, end) {
|
|
2188
2287
|
const entryPointsCopy = [...this.entryPoints];
|
|
2189
2288
|
const levelDiffFactor = 50;
|
|
@@ -2197,6 +2296,17 @@ class CustomNetworkMap {
|
|
|
2197
2296
|
return distance2D + levelDiff * levelDiffFactor;
|
|
2198
2297
|
});
|
|
2199
2298
|
}
|
|
2299
|
+
/**
|
|
2300
|
+
* Get the best itinerary from any entry point to an end coordinates.
|
|
2301
|
+
*
|
|
2302
|
+
* The algorithm works as following:
|
|
2303
|
+
* 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
|
|
2304
|
+
* 2 - Try to calculate an itinerary from the first entry point to the end coordinates.
|
|
2305
|
+
* 3 - If an itinerary is found, it is returned. Otherwise it tries from the next entry point.
|
|
2306
|
+
*
|
|
2307
|
+
* /!\ start is only used to sort the entry points (step 1).
|
|
2308
|
+
*
|
|
2309
|
+
*/
|
|
2200
2310
|
getBestItineraryFromEntryPointsToEnd(start, end, options) {
|
|
2201
2311
|
const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
|
|
2202
2312
|
for (const entryPoint of sortedEntryPoints) {
|
|
@@ -2211,6 +2321,17 @@ class CustomNetworkMap {
|
|
|
2211
2321
|
`No route found from entry points to ${end.toString()} in map: ${this.name}`
|
|
2212
2322
|
);
|
|
2213
2323
|
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Get the best itinerary from start coordinates to any entry point.
|
|
2326
|
+
*
|
|
2327
|
+
* The algorithm works as following:
|
|
2328
|
+
* 1 - Entry points are sorted using distance (as the crow flies) between start - entry point - end
|
|
2329
|
+
* 2 - Try to calculate an itinerary from the start coordinates to the first entry point.
|
|
2330
|
+
* 3 - If an itinerary is found, it is returned. Otherwise it tries to the next entry point.
|
|
2331
|
+
*
|
|
2332
|
+
* /!\ end is only used to sort the entry points (step 1).
|
|
2333
|
+
*
|
|
2334
|
+
*/
|
|
2214
2335
|
getBestItineraryFromStartToEntryPoints(start, end, options) {
|
|
2215
2336
|
const sortedEntryPoints = this.getOrderedEntryPointsSortedByDistance(start, end);
|
|
2216
2337
|
for (const entryPoint of sortedEntryPoints) {
|