@wemap/osm 5.6.1 → 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.
- package/dist/wemap-osm.es.js +12 -2
- package/dist/wemap-osm.es.js.map +1 -1
- package/index.js +5 -27
- package/package.json +4 -6
- package/src/{model/OsmParser.spec.js → OsmParser.spec.js} +1 -1
- package/assets/bureaux-wemap-montpellier-network.osm +0 -162
- package/assets/gare-de-lyon-extract.osm +0 -174
- package/assets/itinerary-grenoble-otp-1.json +0 -1536
- package/assets/itinerary-grenoble-otp-2.json +0 -1092
- package/assets/itinerary-lehavre-cityway-1.json +0 -6799
- package/assets/itinerary-lehavre-cityway-2.json +0 -2133
- package/assets/itinerary-lehavre-cityway-3.json +0 -12577
- package/assets/itinerary-lehavre-cityway-4.json +0 -1451
- package/assets/itinerary-lehavre-cityway-5.json +0 -5925
- package/assets/itinerary-montpellier-osrm-3.json +0 -1
- package/assets/itinerary-montpellier-outdoor-without-steps.json +0 -110
- package/assets/itinerary-montpellier-outdoor.json +0 -513
- package/assets/itinerary-with-duplicate-nodes.json +0 -110
- package/assets/network-conveying-backward.osm +0 -74
- package/assets/network-elevator.osm +0 -48
- package/assets/network-simple.osm +0 -27
- package/assets/network-with-modifiers.osm +0 -39
- package/assets/one-way.osm +0 -46
- package/src/routers/Itinerary.js +0 -196
- package/src/routers/Itinerary.type.spec.js +0 -105
- package/src/routers/Leg.js +0 -113
- package/src/routers/LevelChange.js +0 -65
- package/src/routers/RouterResponse.js +0 -19
- package/src/routers/RouterResponse.type.spec.js +0 -24
- package/src/routers/Step.js +0 -118
- package/src/routers/Utils.js +0 -54
- package/src/routers/cityway/CitywayUtils.js +0 -240
- package/src/routers/cityway/CitywayUtils.spec.js +0 -109
- package/src/routers/custom/OsmNetworkUtils.js +0 -199
- package/src/routers/custom/OsmNetworkUtils.spec.js +0 -109
- package/src/routers/custom/OsmRouter.js +0 -27
- package/src/routers/custom/OsmRouter.spec.js +0 -222
- package/src/routers/custom/OsmRouterOptions.js +0 -33
- package/src/routers/custom/OsmRouterUtils.js +0 -46
- package/src/routers/custom/StepsGeneration.js +0 -104
- package/src/routers/info/ItineraryInfo.js +0 -34
- package/src/routers/info/ItineraryInfoManager.js +0 -148
- package/src/routers/info/ItineraryInfoManager.spec.js +0 -54
- package/src/routers/osrm/OsrmUtils.js +0 -269
- package/src/routers/osrm/OsrmUtils.spec.js +0 -457
- package/src/routers/otp/OtpUtils.js +0 -150
- package/src/routers/otp/OtpUtils.spec.js +0 -97
- /package/src/{model/OsmElement.js → OsmElement.js} +0 -0
- /package/src/{model/OsmElement.spec.js → OsmElement.spec.js} +0 -0
- /package/src/{model/OsmModel.js → OsmModel.js} +0 -0
- /package/src/{model/OsmModel.spec.js → OsmModel.spec.js} +0 -0
- /package/src/{model/OsmNode.js → OsmNode.js} +0 -0
- /package/src/{model/OsmNode.spec.js → OsmNode.spec.js} +0 -0
- /package/src/{model/OsmParser.js → OsmParser.js} +0 -0
- /package/src/{model/OsmWay.js → OsmWay.js} +0 -0
- /package/src/{model/OsmWay.spec.js → OsmWay.spec.js} +0 -0
package/src/routers/Leg.js
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
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;
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { Level, GraphNode, GraphUtils } from '@wemap/geo';
|
|
2
|
-
|
|
3
|
-
import OsmElement from '../model/OsmElement.js';
|
|
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;
|
|
@@ -1,19 +0,0 @@
|
|
|
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;
|
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
|
package/src/routers/Step.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
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;
|
package/src/routers/Utils.js
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { diffAngle } from '@wemap/maths';
|
|
2
|
-
|
|
3
|
-
import Itinerary from './Itinerary.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @param {Itinerary} itinerary
|
|
7
|
-
*/
|
|
8
|
-
export function generateStepsMetadata(itinerary) {
|
|
9
|
-
|
|
10
|
-
let counter = 1;
|
|
11
|
-
|
|
12
|
-
itinerary.legs.forEach((leg, legId) => {
|
|
13
|
-
leg.steps.forEach((step, stepId) => {
|
|
14
|
-
|
|
15
|
-
if (counter === 1) {
|
|
16
|
-
step.firstStep = true;
|
|
17
|
-
}
|
|
18
|
-
if (legId === itinerary.legs.length - 1
|
|
19
|
-
&& stepId === leg.steps.length - 1) {
|
|
20
|
-
step.lastStep = true;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
step.number = counter++;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/*
|
|
27
|
-
* Generate previousBearing, nextBearing and angle
|
|
28
|
-
*/
|
|
29
|
-
|
|
30
|
-
let coordsBeforeStep;
|
|
31
|
-
if (step._idCoordsInLeg > 0) {
|
|
32
|
-
coordsBeforeStep = leg.coords[step._idCoordsInLeg - 1];
|
|
33
|
-
} else if (legId === 0) {
|
|
34
|
-
coordsBeforeStep = itinerary.from;
|
|
35
|
-
} else {
|
|
36
|
-
coordsBeforeStep = itinerary.legs[legId - 1].to.coords;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
let coordsAfterStep;
|
|
40
|
-
if (step._idCoordsInLeg !== leg.coords.length - 1) {
|
|
41
|
-
coordsAfterStep = leg.coords[step._idCoordsInLeg + 1];
|
|
42
|
-
} else if (legId === itinerary.legs.length - 1) {
|
|
43
|
-
coordsAfterStep = itinerary.to;
|
|
44
|
-
} else {
|
|
45
|
-
coordsAfterStep = itinerary.legs[legId + 1].from.coords;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
step.previousBearing = coordsBeforeStep.bearingTo(step.coords);
|
|
49
|
-
step.nextBearing = step.coords.bearingTo(coordsAfterStep);
|
|
50
|
-
step.angle = diffAngle(step.previousBearing, step.nextBearing + Math.PI);
|
|
51
|
-
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
}
|
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-depth */
|
|
2
|
-
/* eslint-disable max-statements */
|
|
3
|
-
import { Coordinates } from '@wemap/geo';
|
|
4
|
-
import Logger from '@wemap/logger';
|
|
5
|
-
|
|
6
|
-
import Itinerary from '../Itinerary.js';
|
|
7
|
-
import Leg from '../Leg.js';
|
|
8
|
-
import RouterResponse from '../RouterResponse.js';
|
|
9
|
-
import Step from '../Step.js';
|
|
10
|
-
import { generateStepsMetadata } from '../Utils.js';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @param {object} json
|
|
14
|
-
* @returns {Coordinates}
|
|
15
|
-
*/
|
|
16
|
-
export function jsonToCoordinates(json) {
|
|
17
|
-
return new Coordinates(json.Lat, json.Long);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* @param {string} jsonDate
|
|
22
|
-
* @returns {number}
|
|
23
|
-
*/
|
|
24
|
-
function jsonDateToTimestamp(jsonDate) {
|
|
25
|
-
const [dateStr, timeStr] = jsonDate.split(' ');
|
|
26
|
-
const [dayStr, monthStr, yearStr] = dateStr.split('/');
|
|
27
|
-
const [hoursStr, minutesStr, secondsStr] = timeStr.split(':');
|
|
28
|
-
const date = new Date(
|
|
29
|
-
Number(yearStr), Number(monthStr) - 1, Number(dayStr),
|
|
30
|
-
Number(hoursStr), Number(minutesStr), Number(secondsStr)
|
|
31
|
-
);
|
|
32
|
-
return date.getTime();
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {string} wktGeometry
|
|
37
|
-
* @returns {Coordinates[]}
|
|
38
|
-
*/
|
|
39
|
-
function parseWKTGeometry(wktGeometry) {
|
|
40
|
-
const tmpCoordsStr = wktGeometry.match(/LINESTRING \((.*)\)/i);
|
|
41
|
-
if (!tmpCoordsStr) {
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
44
|
-
return tmpCoordsStr[1].split(',').map(str => {
|
|
45
|
-
const sp = str.trim().split(' ');
|
|
46
|
-
return new Coordinates(Number(sp[1]), Number(sp[0]));
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param {string} iso8601Duration
|
|
52
|
-
* @see https://stackoverflow.com/a/29153059/2239938
|
|
53
|
-
*/
|
|
54
|
-
function parseDuration(iso8601Duration) {
|
|
55
|
-
const iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
56
|
-
|
|
57
|
-
var matches = iso8601Duration.match(iso8601DurationRegex);
|
|
58
|
-
|
|
59
|
-
// const sign = typeof matches[1] === 'undefined' ? '+' : '-',
|
|
60
|
-
const years = typeof matches[2] === 'undefined' ? 0 : Number(matches[2]);
|
|
61
|
-
const months = typeof matches[3] === 'undefined' ? 0 : Number(matches[3]);
|
|
62
|
-
const weeks = typeof matches[4] === 'undefined' ? 0 : Number(matches[4]);
|
|
63
|
-
const days = typeof matches[5] === 'undefined' ? 0 : Number(matches[5]);
|
|
64
|
-
const hours = typeof matches[6] === 'undefined' ? 0 : Number(matches[6]);
|
|
65
|
-
const minutes = typeof matches[7] === 'undefined' ? 0 : Number(matches[7]);
|
|
66
|
-
const seconds = typeof matches[8] === 'undefined' ? 0 : Number(matches[8]);
|
|
67
|
-
|
|
68
|
-
return seconds
|
|
69
|
-
+ minutes * 60
|
|
70
|
-
+ hours * 3600
|
|
71
|
-
+ days * 86400
|
|
72
|
-
+ weeks * (86400 * 7)
|
|
73
|
-
+ months * (86400 * 30)
|
|
74
|
-
+ years * (86400 * 365.25);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Generate multi itineraries from Cityway JSON
|
|
79
|
-
* @param {object} json JSON file provided by Cityway.
|
|
80
|
-
* @returns {?RouterResponse}
|
|
81
|
-
* @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
|
|
82
|
-
*/
|
|
83
|
-
export function createRouterResponseFromJson(json) {
|
|
84
|
-
|
|
85
|
-
if (json.StatusCode !== 200 || !json.Data || !json.Data.length) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const routerResponse = new RouterResponse();
|
|
90
|
-
routerResponse.routerName = 'cityway';
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// Do not know if it the best approach, but it works...
|
|
94
|
-
const allJsonTrips = json.Data.reduce((acc, dataObj) => {
|
|
95
|
-
acc.push(...dataObj.response.trips.Trip);
|
|
96
|
-
return acc;
|
|
97
|
-
}, []);
|
|
98
|
-
|
|
99
|
-
for (const trip of allJsonTrips) {
|
|
100
|
-
|
|
101
|
-
const itinerary = new Itinerary();
|
|
102
|
-
|
|
103
|
-
itinerary.duration = parseDuration(trip.Duration);
|
|
104
|
-
itinerary.startTime = jsonDateToTimestamp(trip.Departure.Time);
|
|
105
|
-
itinerary.from = jsonToCoordinates(trip.Departure.Site.Position);
|
|
106
|
-
itinerary.endTime = jsonDateToTimestamp(trip.Arrival.Time);
|
|
107
|
-
itinerary.to = jsonToCoordinates(trip.Arrival.Site.Position);
|
|
108
|
-
routerResponse.itineraries.push(itinerary);
|
|
109
|
-
|
|
110
|
-
for (const jsonSection of trip.sections.Section) {
|
|
111
|
-
|
|
112
|
-
const jsonLeg = jsonSection.Leg ? jsonSection.Leg : jsonSection.PTRide;
|
|
113
|
-
|
|
114
|
-
const leg = new Leg();
|
|
115
|
-
|
|
116
|
-
leg.mode = jsonLeg.TransportMode;
|
|
117
|
-
leg.duration = parseDuration(jsonLeg.Duration);
|
|
118
|
-
leg.startTime = jsonDateToTimestamp(jsonLeg.Departure.Time);
|
|
119
|
-
leg.endTime = jsonDateToTimestamp(jsonLeg.Arrival.Time);
|
|
120
|
-
leg.coords = [];
|
|
121
|
-
|
|
122
|
-
if (leg.mode === 'WALK' || leg.mode === 'BICYCLE') {
|
|
123
|
-
|
|
124
|
-
leg.from = {
|
|
125
|
-
name: jsonLeg.Departure.Site.Name,
|
|
126
|
-
coords: jsonToCoordinates(jsonLeg.Departure.Site.Position)
|
|
127
|
-
};
|
|
128
|
-
leg.to = {
|
|
129
|
-
name: jsonLeg.Arrival.Site.Name,
|
|
130
|
-
coords: jsonToCoordinates(jsonLeg.Arrival.Site.Position)
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
leg.steps = [];
|
|
134
|
-
for (const jsonPathLink of jsonLeg.pathLinks.PathLink) {
|
|
135
|
-
const step = new Step();
|
|
136
|
-
let stepCoords;
|
|
137
|
-
if (jsonPathLink.Geometry) {
|
|
138
|
-
stepCoords = parseWKTGeometry(jsonPathLink.Geometry);
|
|
139
|
-
} else {
|
|
140
|
-
stepCoords = [leg.from.coords, leg.to.coords];
|
|
141
|
-
}
|
|
142
|
-
step.coords = stepCoords[0];
|
|
143
|
-
step._idCoordsInLeg = leg.coords.length;
|
|
144
|
-
stepCoords.forEach((coords, idx) => {
|
|
145
|
-
if (
|
|
146
|
-
idx !== 0
|
|
147
|
-
|| leg.coords.length === 0
|
|
148
|
-
|| !leg.coords[leg.coords.length - 1].equalsTo(coords)
|
|
149
|
-
) {
|
|
150
|
-
leg.coords.push(coords);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
step.name = jsonPathLink.Departure.Site.Name;
|
|
156
|
-
step.levelChange = null;
|
|
157
|
-
|
|
158
|
-
step.distance = jsonPathLink.Distance;
|
|
159
|
-
|
|
160
|
-
leg.steps.push(step);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
} else if (leg.mode === 'BUS' || leg.mode === 'TRAMWAY' || leg.mode === 'FUNICULAR') {
|
|
164
|
-
|
|
165
|
-
leg.from = {
|
|
166
|
-
name: jsonLeg.Departure.StopPlace.Name,
|
|
167
|
-
coords: jsonToCoordinates(jsonLeg.Departure.StopPlace.Position)
|
|
168
|
-
};
|
|
169
|
-
leg.to = {
|
|
170
|
-
name: jsonLeg.Arrival.StopPlace.Name,
|
|
171
|
-
coords: jsonToCoordinates(jsonLeg.Arrival.StopPlace.Position)
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
let transportName = jsonLeg.Line.Number;
|
|
175
|
-
if (leg.mode === 'TRAMWAY') {
|
|
176
|
-
leg.mode = 'TRAM';
|
|
177
|
-
// In order to remove the "TRAM " prefix.
|
|
178
|
-
transportName = transportName.substr(5);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
leg.transportInfo = {
|
|
182
|
-
name: transportName,
|
|
183
|
-
routeColor: jsonLeg.Line.Color,
|
|
184
|
-
routeTextColor: jsonLeg.Line.TextColor,
|
|
185
|
-
directionName: jsonLeg.Destination
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
for (const jsonStep of jsonLeg.steps.Step) {
|
|
189
|
-
const stepCoords = parseWKTGeometry(jsonStep.Geometry);
|
|
190
|
-
stepCoords.forEach((coords, idx) => {
|
|
191
|
-
if (
|
|
192
|
-
idx !== 0
|
|
193
|
-
|| leg.coords.length === 0
|
|
194
|
-
|| !leg.coords[leg.coords.length - 1].equalsTo(coords)
|
|
195
|
-
) {
|
|
196
|
-
leg.coords.push(coords);
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
const legStep = new Step();
|
|
202
|
-
legStep.coords = leg.coords[0];
|
|
203
|
-
legStep._idCoordsInLeg = 0;
|
|
204
|
-
legStep.name = jsonLeg.Line.Name;
|
|
205
|
-
legStep.levelChange = null;
|
|
206
|
-
legStep.distance = jsonLeg.Distance;
|
|
207
|
-
leg.steps = [legStep];
|
|
208
|
-
} else {
|
|
209
|
-
Logger.warn(`[CitywayParser] Unknown leg mode: ${leg.mode}`);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
leg.distance = leg.coords.reduce((acc, coords, idx, arr) => {
|
|
213
|
-
if (idx === 0) {
|
|
214
|
-
return acc;
|
|
215
|
-
}
|
|
216
|
-
return acc + arr[idx - 1].distanceTo(coords);
|
|
217
|
-
}, 0);
|
|
218
|
-
|
|
219
|
-
itinerary.legs.push(leg);
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
itinerary.distance = itinerary.coords.reduce((acc, coords, idx, arr) => {
|
|
224
|
-
if (idx === 0) {
|
|
225
|
-
return acc;
|
|
226
|
-
}
|
|
227
|
-
return acc + arr[idx - 1].distanceTo(coords);
|
|
228
|
-
}, 0);
|
|
229
|
-
|
|
230
|
-
// All legs have to be parsed before computing steps metadata
|
|
231
|
-
generateStepsMetadata(itinerary);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
routerResponse.from = routerResponse.itineraries[0].from;
|
|
235
|
-
routerResponse.to = routerResponse.itineraries[routerResponse.itineraries.length - 1].to;
|
|
236
|
-
|
|
237
|
-
return routerResponse;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|