@wemap/routers 6.0.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.
Files changed (49) hide show
  1. package/assets/bureaux-wemap-montpellier-network.osm +162 -0
  2. package/assets/gare-de-lyon-extract.osm +174 -0
  3. package/assets/itinerary-deutsche-bahn-1.json +368 -0
  4. package/assets/itinerary-grenoble-otp-1.json +1536 -0
  5. package/assets/itinerary-grenoble-otp-2.json +1092 -0
  6. package/assets/itinerary-lehavre-cityway-1.json +6799 -0
  7. package/assets/itinerary-lehavre-cityway-2.json +2133 -0
  8. package/assets/itinerary-lehavre-cityway-3.json +12577 -0
  9. package/assets/itinerary-lehavre-cityway-4.json +1451 -0
  10. package/assets/itinerary-lehavre-cityway-5.json +5925 -0
  11. package/assets/itinerary-montpellier-osrm-3.json +1 -0
  12. package/assets/itinerary-montpellier-outdoor-without-steps.json +110 -0
  13. package/assets/itinerary-montpellier-outdoor.json +513 -0
  14. package/assets/itinerary-with-duplicate-nodes.json +110 -0
  15. package/assets/network-conveying-backward.osm +74 -0
  16. package/assets/network-elevator.osm +48 -0
  17. package/assets/network-simple.osm +27 -0
  18. package/assets/network-with-modifiers.osm +39 -0
  19. package/assets/one-way.osm +46 -0
  20. package/dist/wemap-osm.es.js +2012 -0
  21. package/dist/wemap-osm.es.js.map +1 -0
  22. package/index.js +24 -0
  23. package/package.json +35 -0
  24. package/src/ItineraryInfoManager.js +148 -0
  25. package/src/ItineraryInfoManager.spec.js +54 -0
  26. package/src/Utils.js +64 -0
  27. package/src/cityway/CitywayUtils.js +240 -0
  28. package/src/cityway/CitywayUtils.spec.js +109 -0
  29. package/src/deutsche-bahn/DeutscheBahnRouterUtils.js +91 -0
  30. package/src/deutsche-bahn/DeutscheBahnRouterUtils.spec.js +54 -0
  31. package/src/model/Itinerary.js +197 -0
  32. package/src/model/Itinerary.type.spec.js +105 -0
  33. package/src/model/ItineraryInfo.js +34 -0
  34. package/src/model/Leg.js +113 -0
  35. package/src/model/LevelChange.js +65 -0
  36. package/src/model/RouterResponse.js +19 -0
  37. package/src/model/RouterResponse.type.spec.js +24 -0
  38. package/src/model/Step.js +118 -0
  39. package/src/osrm/OsrmUtils.js +269 -0
  40. package/src/osrm/OsrmUtils.spec.js +457 -0
  41. package/src/otp/OtpUtils.js +150 -0
  42. package/src/otp/OtpUtils.spec.js +97 -0
  43. package/src/wemap/WemapNetworkUtils.js +195 -0
  44. package/src/wemap/WemapNetworkUtils.spec.js +109 -0
  45. package/src/wemap/WemapRouter.js +27 -0
  46. package/src/wemap/WemapRouter.spec.js +221 -0
  47. package/src/wemap/WemapRouterOptions.js +32 -0
  48. package/src/wemap/WemapRouterUtils.js +46 -0
  49. package/src/wemap/WemapStepsGeneration.js +104 -0
@@ -0,0 +1,105 @@
1
+ import chai from 'chai';
2
+
3
+ import { Coordinates } from '@wemap/geo';
4
+
5
+ import LevelChange from './LevelChange.js';
6
+ import Leg from './Leg.js';
7
+ import Itinerary from './Itinerary.js';
8
+ import Step from './Step.js';
9
+
10
+ const { expect } = chai;
11
+
12
+
13
+ const isNullOrNumber = val => val === null || typeof val === 'number';
14
+ const isNullOrString = val => val === null || typeof val === 'string';
15
+ const isNullOrObject = val => val === null || typeof val === 'object';
16
+ const isNullOrArray = val => val === null || Array.isArray(val);
17
+ const isNullOrLevelChange = val => val === null || val instanceof LevelChange;
18
+
19
+ const isUndefinedOrBoolean = val => typeof val === 'undefined' || typeof val === 'boolean';
20
+ const isUndefinedOrString = val => typeof val === 'undefined' || typeof val === 'string';
21
+
22
+ const stepExtraProperties = ['subwayEntrance', 'subwayEntranceRef'];
23
+
24
+ /**
25
+ * @param {Step} step
26
+ */
27
+ export function verifyStepData(step) {
28
+
29
+ expect(step).instanceOf(Step);
30
+ expect(step.firstStep).be.a('boolean');
31
+ expect(step.lastStep).be.a('boolean');
32
+ expect(step.number).be.a('number');
33
+ expect(step.coords).instanceOf(Coordinates);
34
+ expect(step.angle).be.a('number');
35
+ expect(step.previousBearing).be.a('number');
36
+ expect(step.nextBearing).be.a('number');
37
+ expect(step.distance).be.a('number');
38
+ expect(step.duration).satisfies(isNullOrNumber);
39
+ expect(step.name).satisfies(isNullOrString);
40
+ expect(step.levelChange).satisfies(isNullOrLevelChange);
41
+ expect(step._idCoordsInLeg).be.a('number');
42
+
43
+ expect(step.extras).satisfies(isNullOrObject);
44
+ if (step.extras !== null) {
45
+ for (const key of Object.keys(step.extras)) {
46
+ expect(stepExtraProperties).includes(key);
47
+ }
48
+ expect(step.extras.subwayEntrance).satisfies(isUndefinedOrBoolean);
49
+ expect(step.extras.subwayEntranceRef).satisfies(isUndefinedOrString);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @param {Leg} routerResponse
55
+ */
56
+ export function verifyLegData(leg) {
57
+
58
+ expect(leg).instanceOf(Leg);
59
+ expect(leg.mode).be.a('string');
60
+ expect(leg.distance).be.a('number');
61
+ expect(leg.duration).be.a('number');
62
+ expect(leg.startTime).satisfies(isNullOrNumber);
63
+ expect(leg.endTime).satisfies(isNullOrNumber);
64
+ expect(leg.from).be.an('object');
65
+ expect(leg.from.name).satisfies(isNullOrString);
66
+ expect(leg.from.coords).instanceOf(Coordinates);
67
+ expect(leg.to).be.an('object');
68
+ expect(leg.to.name).satisfies(isNullOrString);
69
+ expect(leg.to.coords).instanceOf(Coordinates);
70
+ expect(leg.coords).be.an('array');
71
+ leg.coords.forEach(coords => expect(coords).instanceOf(Coordinates));
72
+
73
+ expect(leg.transportInfo).satisfies(isNullOrObject);
74
+ if (leg.transportInfo !== null) {
75
+ expect(leg.transportInfo.name).be.a('string');
76
+ expect(leg.transportInfo.routeColor).satisfies(isNullOrString);
77
+ expect(leg.transportInfo.routeTextColor).satisfies(isNullOrString);
78
+ expect(leg.transportInfo.directionName).satisfies(isNullOrString);
79
+ }
80
+ expect(leg.steps).satisfies(isNullOrArray);
81
+ if (leg.steps !== null) {
82
+ leg.steps.forEach(verifyStepData);
83
+ }
84
+ }
85
+
86
+
87
+ /**
88
+ * @param {Itinerary} itinerary
89
+ */
90
+ export function verifyItineraryData(itinerary) {
91
+
92
+ expect(itinerary).instanceOf(Itinerary);
93
+ expect(itinerary.from).instanceOf(Coordinates);
94
+ expect(itinerary.to).instanceOf(Coordinates);
95
+ expect(itinerary.coords).be.an('array');
96
+ for (const coords of itinerary.coords) {
97
+ expect(coords).instanceOf(Coordinates);
98
+ }
99
+ expect(itinerary.distance).be.a('number');
100
+ expect(itinerary.duration).be.a('number');
101
+ expect(itinerary.startTime).satisfies(isNullOrNumber);
102
+ expect(itinerary.endTime).satisfies(isNullOrNumber);
103
+ expect(itinerary.legs).be.an('array');
104
+ itinerary.legs.forEach(verifyLegData);
105
+ }
@@ -0,0 +1,34 @@
1
+ import { GraphProjection } from '@wemap/geo';
2
+
3
+ import Leg from './Leg.js';
4
+ import Step from './Step.js';
5
+
6
+ class ItineraryInfo {
7
+
8
+ /** @type {Step} */
9
+ nextStep;
10
+
11
+ /** @type {Step} */
12
+ previousStep;
13
+
14
+ /** @type {GraphProjection} */
15
+ projection;
16
+
17
+ /** @type {Leg} */
18
+ leg;
19
+
20
+ /** @type {number} */
21
+ traveledDistance;
22
+
23
+ /** @type {number} */
24
+ traveledPercentage;
25
+
26
+ /** @type {number} */
27
+ remainingDistance;
28
+
29
+ /** @type {number} */
30
+ remainingPercentage;
31
+
32
+ }
33
+
34
+ export default ItineraryInfo;
@@ -0,0 +1,113 @@
1
+ import { Coordinates, Network } from '@wemap/geo';
2
+
3
+ import Step from './Step.js';
4
+
5
+ class Leg {
6
+
7
+ /** @type {!string} can be WALK, BIKE, BUS, TRAM, CAR, FUNICULAR */
8
+ mode;
9
+
10
+ /** @type {!number} */
11
+ distance;
12
+
13
+ /** @type {!number} */
14
+ duration;
15
+
16
+ /** @type {?number} */
17
+ startTime = null;
18
+
19
+ /** @type {?number} */
20
+ endTime = null;
21
+
22
+ /** @type {!{name: ?string, coords: !Coordinates}} */
23
+ from;
24
+
25
+ /** @type {!{name: ?string, coords: !Coordinates}} */
26
+ to;
27
+
28
+ /** @type {!Coordinates[]} */
29
+ coords;
30
+
31
+ /** @type {?{name: !string, routeColor: ?string, routeTextColor: ?string, directionName: ?string}} */
32
+ transportInfo = null;
33
+
34
+ /** @type {?(Step[])} */
35
+ steps = null;
36
+
37
+ /**
38
+ * @returns {Network}
39
+ */
40
+ toNetwork() {
41
+ return Network.fromCoordinates([this.coords]);
42
+ }
43
+
44
+ /**
45
+ * @returns {object}
46
+ */
47
+ toJson() {
48
+ const output = {
49
+ mode: this.mode,
50
+ from: { coords: this.from.coords.toCompressedJson() },
51
+ to: { coords: this.to.coords.toCompressedJson() },
52
+ distance: this.distance,
53
+ duration: this.duration,
54
+ coords: this.coords.map(coords => coords.toCompressedJson())
55
+ };
56
+ if (this.from.name) {
57
+ output.from.name = this.from.name;
58
+ }
59
+ if (this.to.name) {
60
+ output.to.name = this.to.name;
61
+ }
62
+ if (this.startTime !== null) {
63
+ output.startTime = this.startTime;
64
+ }
65
+ if (this.endTime !== null) {
66
+ output.endTime = this.endTime;
67
+ }
68
+ if (this.transportInfo !== null) {
69
+ output.transportInfo = this.transportInfo;
70
+ }
71
+ if (this.steps !== null && this.steps.length > 0) {
72
+ output.steps = this.steps.map(step => step.toJson());
73
+ }
74
+ return output;
75
+ }
76
+
77
+
78
+ /**
79
+ * @param {object} json
80
+ * @returns {Leg}
81
+ */
82
+ static fromJson(json) {
83
+ const leg = new Leg();
84
+ leg.mode = json.mode;
85
+ leg.from = { coords: Coordinates.fromCompressedJson(json.from.coords) };
86
+ leg.to = { coords: Coordinates.fromCompressedJson(json.to.coords) };
87
+ leg.distance = json.distance;
88
+ leg.duration = json.duration;
89
+ leg.coords = json.coords.map(Coordinates.fromCompressedJson);
90
+ if (json.from.name) {
91
+ leg.from.name = json.from.name;
92
+ }
93
+ if (json.to.name) {
94
+ leg.to.name = json.to.name;
95
+ }
96
+ if (json.startTime) {
97
+ leg.startTime = json.startTime;
98
+ }
99
+ if (json.endTime) {
100
+ leg.endTime = json.endTime;
101
+ }
102
+ if (json.transportInfo) {
103
+ leg.transportInfo = json.transportInfo;
104
+ }
105
+ if (json.steps) {
106
+ leg.steps = json.steps.map(Step.fromJson);
107
+ }
108
+ return leg;
109
+ }
110
+
111
+ }
112
+
113
+ export default Leg;
@@ -0,0 +1,65 @@
1
+ import { Level, GraphNode, GraphUtils } from '@wemap/geo';
2
+
3
+ import { OsmElement } from '@wemap/osm';
4
+
5
+ class LevelChange {
6
+
7
+ /** @type {!string} [up|down] */
8
+ direction;
9
+
10
+ /** @type {!number} [-2, -1, 1, ...] */
11
+ difference;
12
+
13
+ /** @type {?string} [elevator|conveyor|stairs] */
14
+ type = null;
15
+
16
+ /**
17
+ * @param {GraphNode<OsmElement>} firstNode
18
+ * @param {GraphNode<OsmElement>} secondNode
19
+ * @returns {LevelChange}
20
+ */
21
+ static fromTwoNodes(firstNode, secondNode) {
22
+
23
+ const levelChange = new LevelChange();
24
+
25
+ const edge = GraphUtils.getEdgeByNodes(firstNode.edges, firstNode, secondNode);
26
+
27
+ if (edge.builtFrom.isElevator) {
28
+ levelChange.type = 'elevator';
29
+ } else if (edge.builtFrom.isConveying) {
30
+ levelChange.type = 'conveyor';
31
+ } else if (edge.builtFrom.areStairs) {
32
+ levelChange.type = 'stairs';
33
+ }
34
+
35
+ levelChange.difference = Level.diff(firstNode.coords.level, secondNode.coords.level);
36
+ levelChange.direction = levelChange.difference > 0 ? 'up' : 'down';
37
+
38
+ return levelChange;
39
+ }
40
+
41
+ /**
42
+ * @returns {object}
43
+ */
44
+ toJson() {
45
+ return {
46
+ direction: this.direction,
47
+ difference: this.difference,
48
+ type: this.type
49
+ };
50
+ }
51
+
52
+ /**
53
+ * @param {object} json
54
+ * @returns {LevelChange}
55
+ */
56
+ static fromJson(json) {
57
+ const levelChange = new LevelChange();
58
+ levelChange.direction = json.direction;
59
+ levelChange.difference = json.difference;
60
+ levelChange.type = json.type;
61
+ return levelChange;
62
+ }
63
+ }
64
+
65
+ export default LevelChange;
@@ -0,0 +1,19 @@
1
+ import { Coordinates } from '@wemap/geo';
2
+
3
+ import Itinerary from './Itinerary.js';
4
+ class RouterResponse {
5
+
6
+ /** @type {!string} */
7
+ routerName;
8
+
9
+ /** @type {!Coordinates} */
10
+ from;
11
+
12
+ /** @type {!Coordinates} */
13
+ to;
14
+
15
+ /** @type {!(Itinerary[])} */
16
+ itineraries = [];
17
+ }
18
+
19
+ export default RouterResponse;
@@ -0,0 +1,24 @@
1
+ import chai from 'chai';
2
+
3
+ import { Coordinates } from '@wemap/geo';
4
+
5
+ import RouterResponse from './RouterResponse.js';
6
+
7
+ import { verifyItineraryData } from './Itinerary.type.spec.js';
8
+
9
+ const { expect } = chai;
10
+
11
+ /**
12
+ * @param {RouterResponse} routerResponse
13
+ */
14
+ export function verifyRouterResponseData(routerResponse) {
15
+
16
+ expect(routerResponse).instanceOf(RouterResponse);
17
+ expect(routerResponse.routerName).be.a('string');
18
+ expect(routerResponse.from).instanceOf(Coordinates);
19
+ expect(routerResponse.to).instanceOf(Coordinates);
20
+ expect(routerResponse.itineraries).be.an('array');
21
+ routerResponse.itineraries.forEach(verifyItineraryData);
22
+
23
+ }
24
+
@@ -0,0 +1,118 @@
1
+ import { Coordinates } from '@wemap/geo';
2
+
3
+ import LevelChange from './LevelChange.js';
4
+
5
+ class Step {
6
+
7
+ /** @type {!boolean} */
8
+ firstStep = false;
9
+
10
+ /** @type {!boolean} */
11
+ lastStep = false;
12
+
13
+ /** @type {!number} */
14
+ number;
15
+
16
+ /** @type {!Coordinates} */
17
+ coords = [];
18
+
19
+
20
+ /** @type {!number} */
21
+ angle;
22
+
23
+ /** @type {!number} */
24
+ previousBearing;
25
+
26
+ /** @type {!number} */
27
+ nextBearing;
28
+
29
+
30
+ /** @type {!number} */
31
+ distance;
32
+
33
+ /** @type {?number} */
34
+ duration = null;
35
+
36
+ /** @type {?string} */
37
+ name = null;
38
+
39
+
40
+ /** @type {?LevelChange} */
41
+ levelChange = null;
42
+
43
+ /** @type {?{?subwayEntrance: boolean, ?subwayEntranceRef: string}} */
44
+ extras = {};
45
+
46
+ /** @type {!number} */
47
+ _idCoordsInLeg = null;
48
+
49
+ /**
50
+ * @returns {object}
51
+ */
52
+ toJson() {
53
+ const output = {
54
+ number: this.number,
55
+ coords: this.coords.toCompressedJson(),
56
+ angle: this.angle,
57
+ previousBearing: this.previousBearing,
58
+ nextBearing: this.nextBearing,
59
+ distance: this.distance,
60
+ _idCoordsInLeg: this._idCoordsInLeg
61
+ };
62
+ if (this.firstStep) {
63
+ output.firstStep = true;
64
+ }
65
+ if (this.lastStep) {
66
+ output.lastStep = true;
67
+ }
68
+ if (this.duration !== null) {
69
+ output.duration = this.duration;
70
+ }
71
+ if (this.name !== null) {
72
+ output.name = this.name;
73
+ }
74
+ if (this.levelChange !== null) {
75
+ output.levelChange = this.levelChange.toJson();
76
+ }
77
+ if (this.extras && Object.keys(this.extras).length !== 0) {
78
+ output.extras = this.extras;
79
+ }
80
+ return output;
81
+ }
82
+
83
+ /**
84
+ * @param {object} json
85
+ * @returns {Step}
86
+ */
87
+ static fromJson(json) {
88
+ const step = new Step();
89
+ step.number = json.number;
90
+ step.coords = Coordinates.fromCompressedJson(json.coords);
91
+ step.angle = json.angle;
92
+ step.previousBearing = json.previousBearing;
93
+ step.nextBearing = json.nextBearing;
94
+ step.distance = json.distance;
95
+ step._idCoordsInLeg = json._idCoordsInLeg;
96
+ if (json.firstStep) {
97
+ step.firstStep = json.firstStep;
98
+ }
99
+ if (json.lastStep) {
100
+ step.lastStep = json.lastStep;
101
+ }
102
+ if (json.duration) {
103
+ step.duration = json.duration;
104
+ }
105
+ if (json.name) {
106
+ step.name = json.name;
107
+ }
108
+ if (json.levelChange) {
109
+ step.levelChange = LevelChange.fromJson(json.levelChange);
110
+ }
111
+ if (json.extras) {
112
+ step.extras = json.extras;
113
+ }
114
+ return step;
115
+ }
116
+ }
117
+
118
+ export default Step;