@wemap/routers 6.2.2 → 7.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 (57) hide show
  1. package/assets/biocbon-bergere-rdc-network.osm +163 -0
  2. package/assets/gare-de-lest-network-pp-bounds.osm +1615 -0
  3. package/dist/wemap-routers.es.js +1811 -695
  4. package/dist/wemap-routers.es.js.map +1 -1
  5. package/index.js +13 -5
  6. package/package.json +9 -6
  7. package/src/Constants.js +4 -2
  8. package/src/ItineraryInfoManager.spec.js +2 -2
  9. package/src/Utils.js +0 -77
  10. package/src/model/Itinerary.js +41 -5
  11. package/src/model/Itinerary.spec.js +91 -0
  12. package/src/model/Itinerary.type.spec.js +3 -78
  13. package/src/model/Leg.js +89 -19
  14. package/src/model/Leg.spec.js +110 -0
  15. package/src/model/Leg.type.spec.js +48 -0
  16. package/src/model/LevelChange.js +14 -24
  17. package/src/model/LevelChange.spec.js +78 -0
  18. package/src/model/LevelChange.type.spec.js +26 -0
  19. package/src/model/RouterResponse.js +70 -1
  20. package/src/model/RouterResponse.spec.js +85 -0
  21. package/src/model/RouterResponse.type.spec.js +7 -4
  22. package/src/model/Step.js +45 -6
  23. package/src/model/Step.spec.js +100 -0
  24. package/src/model/Step.type.spec.js +52 -0
  25. package/src/remote/RemoteRouter.js +31 -0
  26. package/src/remote/RemoteRouterManager.js +84 -0
  27. package/src/remote/RemoteRouterOptions.js +25 -0
  28. package/src/remote/RemoteRouterServerUnreachable.js +10 -0
  29. package/src/remote/RemoteRouterUtils.js +78 -0
  30. package/src/remote/RoutingModeCorrespondanceNotFound.js +18 -0
  31. package/src/remote/cityway/CitywayRemoteRouter.js +386 -0
  32. package/src/{cityway/CitywayUtils.spec.js → remote/cityway/CitywayRemoteRouter.spec.js} +19 -18
  33. package/src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.js +143 -0
  34. package/src/{deutsche-bahn/DeutscheBahnRouterUtils.spec.js → remote/deutsche-bahn/DeutscheBahnRemoteRouter.spec.js} +7 -6
  35. package/src/remote/idfm/IdfmRemoteRouter.js +432 -0
  36. package/src/{idfm/IdfmUtils.spec.js → remote/idfm/IdfmRemoteRouter.spec.js} +7 -6
  37. package/src/remote/idfm/IdfmRemoteRouterTokenError.js +6 -0
  38. package/src/remote/osrm/OsrmRemoteRouter.js +331 -0
  39. package/src/{osrm/OsrmUtils.spec.js → remote/osrm/OsrmRemoteRouter.spec.js} +9 -15
  40. package/src/remote/otp/OtpRemoteRouter.js +222 -0
  41. package/src/{otp/OtpUtils.spec.js → remote/otp/OtpRemoteRouter.spec.js} +10 -9
  42. package/src/remote/wemap-meta/WemapMetaRemoteRouter.js +57 -0
  43. package/src/remote/wemap-meta/WemapMetaRemoteRouter.spec.js +22 -0
  44. package/src/remote/wemap-meta/WemapMetaRemoteRouterOptions.js +36 -0
  45. package/src/remote/wemap-meta/WemapMetaRemoteRouterPayload.js +44 -0
  46. package/src/wemap/WemapRouter.js +6 -0
  47. package/src/wemap/WemapRouterUtils.js +10 -4
  48. package/src/wemap/WemapStepsGeneration.js +36 -9
  49. package/src/wemap-meta/IOMap.js +191 -0
  50. package/src/wemap-meta/WemapMetaRouter.js +314 -0
  51. package/src/wemap-meta/WemapMetaRouter.spec.js +119 -0
  52. package/src/wemap-meta/WemapMetaRouterOptions.js +20 -0
  53. package/src/cityway/CitywayUtils.js +0 -252
  54. package/src/deutsche-bahn/DeutscheBahnRouterUtils.js +0 -91
  55. package/src/idfm/IdfmUtils.js +0 -247
  56. package/src/osrm/OsrmUtils.js +0 -269
  57. package/src/otp/OtpUtils.js +0 -150
package/index.js CHANGED
@@ -13,14 +13,22 @@ export { default as WemapRouter } from './src/wemap/WemapRouter.js';
13
13
  export { default as WemapRouterOptions } from './src/wemap/WemapRouterOptions.js';
14
14
  export * as WemapRouterUtils from './src/wemap/WemapRouterUtils.js';
15
15
  export * as WemapNetworkUtils from './src/wemap/WemapNetworkUtils.js';
16
+ export { default as WemapMetaRouter } from './src/wemap-meta/WemapMetaRouter.js';
17
+ export { default as WemapMetaRouterOptions } from './src/wemap-meta/WemapMetaRouterOptions.js';
18
+ export { default as WemapMetaRouterIOMap } from './src/wemap-meta/IOMap.js';
16
19
 
17
20
  /* Other Routers */
18
- export * as OsrmUtils from './src/osrm/OsrmUtils.js';
19
- export * as OtpUtils from './src/otp/OtpUtils.js';
20
- export * as CitywayUtils from './src/cityway/CitywayUtils.js';
21
- export * as DeutscheBahnRouterUtils from './src/deutsche-bahn/DeutscheBahnRouterUtils.js';
22
- export * as IdfmUtils from './src/idfm/IdfmUtils.js';
21
+ export { default as OsrmRemoteRouter } from './src/remote/osrm/OsrmRemoteRouter.js';
22
+ export { default as OtpRemoteRouter } from './src/remote/otp/OtpRemoteRouter.js';
23
+ export { default as CitywayRemoteRouter } from './src/remote/cityway/CitywayRemoteRouter.js';
24
+ export { default as DeutscheBahnRemoteRouter } from './src/remote/deutsche-bahn/DeutscheBahnRemoteRouter.js';
25
+ export { default as IdfmRemoteRouter } from './src/remote/idfm/IdfmRemoteRouter.js';
26
+ export { default as WemapMetaRemoteRouter } from './src/remote/wemap-meta/WemapMetaRemoteRouter.js';
27
+ export { default as WemapMetaRemoteRouterOptions } from './src/remote/wemap-meta/WemapMetaRemoteRouterOptions.js';
28
+ export { default as WemapMetaRemoteRouterPayload } from './src/remote/wemap-meta/WemapMetaRemoteRouterPayload.js';
29
+
23
30
 
24
31
  /* Others */
25
32
  export { default as ItineraryInfoManager } from './src/ItineraryInfoManager.js';
26
33
  export * from './src/Utils.js';
34
+ export { default as Constants } from './src/Constants.js';
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/routers"
12
12
  },
13
13
  "name": "@wemap/routers",
14
- "version": "6.2.2",
14
+ "version": "7.0.0",
15
15
  "bugs": {
16
16
  "url": "https://github.com/wemap/wemap-modules-js/issues"
17
17
  },
@@ -26,10 +26,13 @@
26
26
  "license": "ISC",
27
27
  "dependencies": {
28
28
  "@mapbox/polyline": "^1.1.1",
29
- "@wemap/geo": "^6.2.2",
30
- "@wemap/logger": "^6.0.0",
31
- "@wemap/maths": "^6.0.0",
32
- "@wemap/osm": "^6.2.2"
29
+ "@turf/boolean-point-in-polygon": "^6.5.0",
30
+ "@turf/convex": "^6.5.0",
31
+ "@turf/helpers": "^6.5.0",
32
+ "@wemap/geo": "^7.0.0",
33
+ "@wemap/logger": "^7.0.0",
34
+ "@wemap/maths": "^7.0.0",
35
+ "@wemap/osm": "^7.0.0"
33
36
  },
34
- "gitHead": "ee717a21b2f01820472df0112da9373044f267f9"
37
+ "gitHead": "cfd70d1f998599c53689c1b1996a517247f04dce"
35
38
  }
package/src/Constants.js CHANGED
@@ -9,10 +9,13 @@ Constants.ROUTING_MODE = {
9
9
  FERRY: 'FERRY',
10
10
  FUNICULAR: 'FUNICULAR',
11
11
  METRO: 'METRO',
12
+ MOTO: 'MOTO',
12
13
  TRAIN: 'TRAIN',
13
14
  TAXI: 'TAXI',
14
15
  TRAM: 'TRAM',
15
- WALK: 'WALK'
16
+ WALK: 'WALK',
17
+ MULTI: 'MULTI',
18
+ UNKNOWN: 'UNKNOWN'
16
19
  };
17
20
 
18
21
  Constants.PUBLIC_TRANSPORT = [
@@ -23,7 +26,6 @@ Constants.PUBLIC_TRANSPORT = [
23
26
  Constants.ROUTING_MODE.FUNICULAR,
24
27
  Constants.ROUTING_MODE.METRO,
25
28
  Constants.ROUTING_MODE.TRAIN,
26
- Constants.ROUTING_MODE.TAXI,
27
29
  Constants.ROUTING_MODE.TRAM
28
30
  ];
29
31
 
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'url';
6
6
 
7
7
  import { Coordinates, GraphEdge, GraphNode } from '@wemap/geo';
8
8
 
9
- import { createRouterResponseFromJson } from './otp/OtpUtils.js';
9
+ import OtpRemoteRouter from './remote/otp/OtpRemoteRouter.js';
10
10
  import ItineraryInfoManager from './ItineraryInfoManager.js';
11
11
 
12
12
 
@@ -19,7 +19,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
19
  const filePath = path.resolve(__dirname, '../assets/itinerary-grenoble-otp-1.json');
20
20
  const fileString = fs.readFileSync(filePath, 'utf8');
21
21
  const json = JSON.parse(fileString);
22
- const routerResponse = createRouterResponseFromJson(json);
22
+ const routerResponse = OtpRemoteRouter.createRouterResponseFromJson(json);
23
23
 
24
24
  let position, itineraryInfo;
25
25
 
package/src/Utils.js CHANGED
@@ -1,7 +1,3 @@
1
- import { diffAngle } from '@wemap/maths';
2
-
3
- import Itinerary from './model/Itinerary.js';
4
-
5
1
  /**
6
2
  * Get route duration
7
3
  * @param {Number} speed in km/h
@@ -10,76 +6,3 @@ import Itinerary from './model/Itinerary.js';
10
6
  export function getDurationFromLength(length, speed = 5) {
11
7
  return length / (speed * 1000 / 3600);
12
8
  }
13
-
14
- /**
15
- * Create and return a date with a given timezone
16
- * @param {number} year
17
- * @param {number} month
18
- * @param {number} day
19
- * @param {number} hours
20
- * @param {number} minutes
21
- * @param {number} seconds
22
- * @param {string} timeZone - timezone name (e.g. 'Europe/Paris')
23
- */
24
- export function dateWithTimeZone(year, month, day, hour, minute, second, timeZone = 'Europe/Paris') {
25
- const date = new Date(Date.UTC(year, month, day, hour, minute, second));
26
-
27
- const utcDate = new Date(date.toLocaleString('en-US', { timeZone: 'UTC' }));
28
- const tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
29
- const offset = utcDate.getTime() - tzDate.getTime();
30
-
31
- date.setTime(date.getTime() + offset);
32
-
33
- return date;
34
- }
35
-
36
- /**
37
- * @param {Itinerary} itinerary
38
- */
39
- export function generateStepsMetadata(itinerary) {
40
-
41
- let counter = 1;
42
-
43
- itinerary.legs.forEach((leg, legId) => {
44
- leg.steps.forEach((step, stepId) => {
45
-
46
- if (counter === 1) {
47
- step.firstStep = true;
48
- }
49
- if (legId === itinerary.legs.length - 1
50
- && stepId === leg.steps.length - 1) {
51
- step.lastStep = true;
52
- }
53
-
54
- step.number = counter++;
55
-
56
-
57
- /*
58
- * Generate previousBearing, nextBearing and angle
59
- */
60
-
61
- let coordsBeforeStep;
62
- if (step._idCoordsInLeg > 0) {
63
- coordsBeforeStep = leg.coords[step._idCoordsInLeg - 1];
64
- } else if (legId === 0) {
65
- coordsBeforeStep = itinerary.from;
66
- } else {
67
- coordsBeforeStep = itinerary.legs[legId - 1].to.coords;
68
- }
69
-
70
- let coordsAfterStep;
71
- if (step._idCoordsInLeg !== leg.coords.length - 1) {
72
- coordsAfterStep = leg.coords[step._idCoordsInLeg + 1];
73
- } else if (legId === itinerary.legs.length - 1) {
74
- coordsAfterStep = itinerary.to;
75
- } else {
76
- coordsAfterStep = itinerary.legs[legId + 1].from.coords;
77
- }
78
-
79
- step.previousBearing = coordsBeforeStep.bearingTo(step.coords);
80
- step.nextBearing = step.coords.bearingTo(coordsAfterStep);
81
- step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);
82
-
83
- });
84
- });
85
- }
@@ -74,9 +74,9 @@ class Itinerary {
74
74
 
75
75
  get mode() {
76
76
  if (!this._mode) {
77
- let isPublicTransport;
78
- let isBicycle;
79
- let isDriving;
77
+ let isPublicTransport = false;
78
+ let isBicycle = false;
79
+ let isDriving = false;
80
80
 
81
81
  this.legs.forEach((leg) => {
82
82
  isPublicTransport = isPublicTransport || Constants.PUBLIC_TRANSPORT.includes(leg.mode);
@@ -189,6 +189,42 @@ class Itinerary {
189
189
  return itinerary;
190
190
  }
191
191
 
192
+
193
+ /**
194
+ * @param {Itinerary} obj1
195
+ * @param {Itinerary} obj2
196
+ * @returns {Boolean}
197
+ */
198
+ static equalsTo(obj1, obj2) {
199
+ const intermediate = obj1.from.equalsTo(obj2.from)
200
+ && obj1.to.equalsTo(obj2.to)
201
+ && obj1.distance === obj2.distance
202
+ && obj1.duration === obj2.duration
203
+ && obj1.startTime === obj2.startTime
204
+ && obj1.endTime === obj2.endTime
205
+ && obj1.legs.length === obj2.legs.length;
206
+
207
+ if (!intermediate) {
208
+ return false;
209
+ }
210
+
211
+ for (let i = 0; i < obj1.legs.length; i++) {
212
+ if (!obj1.legs[i].equalsTo(obj2.legs[i])) {
213
+ return false;
214
+ }
215
+ }
216
+
217
+ return true;
218
+ }
219
+
220
+ /**
221
+ * @param {Itinerary} obj
222
+ * @returns {Boolean}
223
+ */
224
+ equalsTo(obj) {
225
+ return Itinerary.equalsTo(this, obj);
226
+ }
227
+
192
228
  /**
193
229
  * @returns {object}
194
230
  */
@@ -221,10 +257,10 @@ class Itinerary {
221
257
  itinerary.distance = json.distance;
222
258
  itinerary.duration = json.duration;
223
259
  itinerary.legs = json.legs.map(Leg.fromJson);
224
- if (json.startTime) {
260
+ if (typeof json.startTime === 'number') {
225
261
  itinerary.startTime = json.startTime;
226
262
  }
227
- if (json.endTime) {
263
+ if (typeof json.endTime === 'number') {
228
264
  itinerary.endTime = json.endTime;
229
265
  }
230
266
  return itinerary;
@@ -0,0 +1,91 @@
1
+ /* eslint-disable max-statements */
2
+ import chai from 'chai';
3
+
4
+ import { Coordinates } from '@wemap/geo';
5
+
6
+ import Itinerary from './Itinerary.js';
7
+ import checkItineraryType from './Itinerary.type.spec.js';
8
+ import { leg1, leg2, leg3, leg4 } from './Leg.spec.js';
9
+
10
+ const { expect } = chai;
11
+
12
+ const itinerary1 = new Itinerary();
13
+ itinerary1.from = new Coordinates(0, 0);
14
+ itinerary1.to = new Coordinates(1, 0);
15
+ itinerary1.distance = 10;
16
+ itinerary1.duration = 20;
17
+ itinerary1.legs = [leg1];
18
+
19
+ const itinerary2 = new Itinerary();
20
+ itinerary2.from = new Coordinates(0, 0);
21
+ itinerary2.to = new Coordinates(1, 0);
22
+ itinerary2.distance = 100;
23
+ itinerary2.duration = 200;
24
+ itinerary2.startTime = 0;
25
+ itinerary2.endTime = 10;
26
+ itinerary2.legs = [leg1, leg2];
27
+
28
+ const itinerary3 = new Itinerary();
29
+ itinerary3.from = new Coordinates(0, 0);
30
+ itinerary3.to = new Coordinates(2, 0);
31
+ itinerary3.distance = 1000;
32
+ itinerary3.duration = 2000;
33
+ itinerary3.legs = [leg1, leg2, leg3, leg4];
34
+
35
+ const itinerary4 = new Itinerary();
36
+ itinerary4.from = new Coordinates(1, 0);
37
+ itinerary4.to = new Coordinates(4, 0);
38
+ itinerary4.distance = 10000;
39
+ itinerary4.duration = 20000;
40
+ itinerary4.legs = [leg1];
41
+
42
+ const itinerary5 = new Itinerary();
43
+ Object.assign(itinerary5, itinerary4);
44
+
45
+ describe('Itinerary', () => {
46
+
47
+ it('checkTypes', () => {
48
+ checkItineraryType(itinerary1);
49
+ checkItineraryType(itinerary2);
50
+ checkItineraryType(itinerary3);
51
+ checkItineraryType(itinerary4);
52
+ });
53
+
54
+ it('equals', () => {
55
+ expect(itinerary1.equalsTo(itinerary1)).is.true;
56
+ expect(itinerary2.equalsTo(itinerary2)).is.true;
57
+ expect(itinerary3.equalsTo(itinerary3)).is.true;
58
+ expect(itinerary4.equalsTo(itinerary4)).is.true;
59
+ expect(itinerary4.equalsTo(itinerary5)).is.true;
60
+ expect(itinerary1.equalsTo(itinerary2)).is.false;
61
+ expect(itinerary1.equalsTo(itinerary3)).is.false;
62
+ expect(itinerary1.equalsTo(itinerary4)).is.false;
63
+ });
64
+
65
+ it('from / to JSON', () => {
66
+
67
+ const itinerary1Json = itinerary1.toJson();
68
+ expect(itinerary1Json).be.an('object');
69
+ const itinerary1Bis = Itinerary.fromJson(itinerary1Json);
70
+ expect(itinerary1.equalsTo(itinerary1Bis)).is.true;
71
+
72
+ const itinerary2Json = itinerary2.toJson();
73
+ expect(itinerary2Json).be.an('object');
74
+ const itinerary2Bis = Itinerary.fromJson(itinerary2Json);
75
+ expect(itinerary2.equalsTo(itinerary2Bis)).is.true;
76
+
77
+ const itinerary3Json = itinerary3.toJson();
78
+ expect(itinerary3Json).be.an('object');
79
+ const itinerary3Bis = Itinerary.fromJson(itinerary3Json);
80
+ expect(itinerary3.equalsTo(itinerary3Bis)).is.true;
81
+
82
+ const itinerary4Json = itinerary4.toJson();
83
+ expect(itinerary4Json).be.an('object');
84
+ const itinerary4Bis = Itinerary.fromJson(itinerary4Json);
85
+ expect(itinerary4.equalsTo(itinerary4Bis)).is.true;
86
+
87
+ });
88
+
89
+ });
90
+
91
+ export { itinerary1, itinerary2, itinerary3, itinerary4 };
@@ -2,92 +2,17 @@ import chai from 'chai';
2
2
 
3
3
  import { Coordinates } from '@wemap/geo';
4
4
 
5
- import LevelChange from './LevelChange.js';
6
- import Leg from './Leg.js';
5
+ import checkLegType from './Leg.type.spec.js';
7
6
  import Itinerary from './Itinerary.js';
8
- import Step from './Step.js';
9
7
 
10
8
  const { expect } = chai;
11
9
 
12
-
13
10
  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
11
 
87
12
  /**
88
13
  * @param {Itinerary} itinerary
89
14
  */
90
- export function verifyItineraryData(itinerary) {
15
+ export default function checkItineraryType(itinerary) {
91
16
 
92
17
  expect(itinerary).instanceOf(Itinerary);
93
18
  expect(itinerary.mode).be.a('string');
@@ -102,5 +27,5 @@ export function verifyItineraryData(itinerary) {
102
27
  expect(itinerary.startTime).satisfies(isNullOrNumber);
103
28
  expect(itinerary.endTime).satisfies(isNullOrNumber);
104
29
  expect(itinerary.legs).be.an('array');
105
- itinerary.legs.forEach(verifyLegData);
30
+ itinerary.legs.forEach(checkLegType);
106
31
  }
package/src/model/Leg.js CHANGED
@@ -46,6 +46,72 @@ class Leg {
46
46
  return Network.fromCoordinates([this.coords]);
47
47
  }
48
48
 
49
+
50
+ /**
51
+ * @param {Leg} obj1
52
+ * @param {Leg} obj2
53
+ * @returns {Boolean}
54
+ */
55
+ // eslint-disable-next-line complexity
56
+ static equalsTo(obj1, obj2) {
57
+ const intermediate = obj1.mode === obj2.mode
58
+ && obj1.distance === obj2.distance
59
+ && obj1.duration === obj2.duration
60
+ && obj1.startTime === obj2.startTime
61
+ && obj1.endTime === obj2.endTime
62
+ && obj1.from.name === obj2.from.name
63
+ && obj1.from.coords.equalsTo(obj2.from.coords)
64
+ && obj1.to.name === obj2.to.name
65
+ && obj1.to.coords.equalsTo(obj2.to.coords)
66
+ && obj1.coords.length === obj2.coords.length
67
+ && (
68
+ obj1.steps === obj2.steps
69
+ || obj1.steps.length === obj2.steps.length
70
+ );
71
+
72
+ if (!intermediate) {
73
+ return false;
74
+ }
75
+
76
+ let i;
77
+ for (i = 0; i < obj1.coords.length; i++) {
78
+ if (!obj1.coords[i].equalsTo(obj2.coords[i])) {
79
+ return false;
80
+ }
81
+ }
82
+ if (obj1.steps) {
83
+ for (i = 0; i < obj1.steps.length; i++) {
84
+ if (!obj1.steps[i].equalsTo(obj2.steps[i])) {
85
+ return false;
86
+ }
87
+ }
88
+ }
89
+
90
+ if (obj1.transportInfo !== obj2.transportInfo) {
91
+ if (obj1.transportInfo === null) {
92
+ return false;
93
+ }
94
+ if (
95
+ obj1.transportInfo.name !== obj2.transportInfo.name
96
+ || obj1.transportInfo.routeColor !== obj2.transportInfo.routeColor
97
+ || obj1.transportInfo.routeTextColor !== obj2.transportInfo.routeTextColor
98
+ || obj1.transportInfo.directionName !== obj2.transportInfo.directionName
99
+ ) {
100
+ return false;
101
+ }
102
+ }
103
+
104
+ return true;
105
+ }
106
+
107
+ /**
108
+ * @param {Leg} obj
109
+ * @returns {Boolean}
110
+ */
111
+ equalsTo(obj) {
112
+ return Leg.equalsTo(this, obj);
113
+ }
114
+
49
115
  /**
50
116
  * @returns {object}
51
117
  */
@@ -58,18 +124,18 @@ class Leg {
58
124
  duration: this.duration,
59
125
  coords: this.coords.map(coords => coords.toCompressedJson())
60
126
  };
61
- if (this.from.name) {
62
- output.from.name = this.from.name;
63
- }
64
- if (this.to.name) {
65
- output.to.name = this.to.name;
66
- }
67
127
  if (this.startTime !== null) {
68
128
  output.startTime = this.startTime;
69
129
  }
70
130
  if (this.endTime !== null) {
71
131
  output.endTime = this.endTime;
72
132
  }
133
+ if (this.from.name !== null) {
134
+ output.from.name = this.from.name;
135
+ }
136
+ if (this.to.name !== null) {
137
+ output.to.name = this.to.name;
138
+ }
73
139
  if (this.transportInfo !== null) {
74
140
  output.transportInfo = this.transportInfo;
75
141
  }
@@ -87,27 +153,31 @@ class Leg {
87
153
  static fromJson(json) {
88
154
  const leg = new Leg();
89
155
  leg.mode = json.mode;
90
- leg.from = { coords: Coordinates.fromCompressedJson(json.from.coords) };
91
- leg.to = { coords: Coordinates.fromCompressedJson(json.to.coords) };
92
156
  leg.distance = json.distance;
93
157
  leg.duration = json.duration;
94
- leg.coords = json.coords.map(Coordinates.fromCompressedJson);
95
- if (json.from.name) {
96
- leg.from.name = json.from.name;
97
- }
98
- if (json.to.name) {
99
- leg.to.name = json.to.name;
100
- }
101
- if (json.startTime) {
158
+
159
+ if (typeof json.startTime === 'number') {
102
160
  leg.startTime = json.startTime;
103
161
  }
104
- if (json.endTime) {
162
+ if (typeof json.endTime === 'number') {
105
163
  leg.endTime = json.endTime;
106
164
  }
107
- if (json.transportInfo) {
165
+
166
+ leg.from = {
167
+ coords: Coordinates.fromCompressedJson(json.from.coords),
168
+ name: typeof json.from.name === 'string' ? json.from.name : null
169
+ };
170
+ leg.to = {
171
+ coords: Coordinates.fromCompressedJson(json.to.coords),
172
+ name: typeof json.to.name === 'string' ? json.to.name : null
173
+ };
174
+
175
+ leg.coords = json.coords.map(Coordinates.fromCompressedJson);
176
+
177
+ if (typeof json.transportInfo === 'object') {
108
178
  leg.transportInfo = json.transportInfo;
109
179
  }
110
- if (json.steps) {
180
+ if (typeof json.steps === 'object') {
111
181
  leg.steps = json.steps.map(Step.fromJson);
112
182
  }
113
183
  return leg;