@wemap/osm 5.8.0 → 6.2.2
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 +2 -1760
- package/dist/wemap-osm.es.js.map +1 -1
- package/index.js +5 -28
- 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-deutsche-bahn-1.json +0 -368
- 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 -197
- 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/deutsche-bahn/DeutscheBahnRouterUtils.js +0 -93
- package/src/routers/deutsche-bahn/DeutscheBahnRouterUtils.spec.js +0 -54
- 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
|
-
|