@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
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { GraphRouterOptions } from '@wemap/geo';
|
|
2
|
-
|
|
3
|
-
import OsmElement from '../../model/OsmElement.js';
|
|
4
|
-
|
|
5
|
-
class OsmRouterOptions extends GraphRouterOptions {
|
|
6
|
-
|
|
7
|
-
/** @type {OsmRouterOptions} */
|
|
8
|
-
static DEFAULT = new OsmRouterOptions();
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @returns {OsmRouterOptions}
|
|
12
|
-
*/
|
|
13
|
-
static get WITHOUT_STAIRS() {
|
|
14
|
-
const options = new OsmRouterOptions();
|
|
15
|
-
options.acceptEdgeFn = edge => edge.builtFrom.tags.highway !== 'steps';
|
|
16
|
-
return options;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Get route duration
|
|
21
|
-
* @param {Number} speed in km/h
|
|
22
|
-
*/
|
|
23
|
-
static getDurationFromLength(length, speed = 5) {
|
|
24
|
-
return length / (speed * 1000 / 3600);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/** @type {function(GraphEdge<OsmElement>):boolean} */
|
|
28
|
-
weightEdgeFn = edge => edge.builtFrom.isElevator ? 30 : OsmRouterOptions.getDurationFromLength(edge.length);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default OsmRouterOptions;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { GraphItinerary } from '@wemap/geo';
|
|
2
|
-
|
|
3
|
-
import OsmElement from '../../model/OsmElement.js';
|
|
4
|
-
import Itinerary from '../Itinerary.js';
|
|
5
|
-
import Leg from '../Leg.js';
|
|
6
|
-
import StepsGeneration from './StepsGeneration.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @param {GraphItinerary<OsmElement>} graphItinerary
|
|
10
|
-
* @param {string} mode
|
|
11
|
-
* @returns {Leg}
|
|
12
|
-
*/
|
|
13
|
-
export function createLegFromGraphItinerary(graphItinerary, mode = 'WALK') {
|
|
14
|
-
|
|
15
|
-
const leg = new Leg();
|
|
16
|
-
|
|
17
|
-
leg.from = { coords: graphItinerary.start };
|
|
18
|
-
leg.to = { coords: graphItinerary.end };
|
|
19
|
-
leg.coords = graphItinerary.nodes.map(node => node.coords);
|
|
20
|
-
leg.distance = graphItinerary.edges.reduce((acc, edge) => acc + edge.length, 0);
|
|
21
|
-
leg.duration = graphItinerary.edgesWeights.reduce((acc, weight) => acc + weight, 0);
|
|
22
|
-
leg.mode = mode;
|
|
23
|
-
leg.steps = StepsGeneration.fromGraphItinerary(graphItinerary);
|
|
24
|
-
|
|
25
|
-
return leg;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {GraphItinerary<OsmElement>} graphItinerary
|
|
30
|
-
* @param {string} mode
|
|
31
|
-
* @returns {Itinerary}
|
|
32
|
-
*/
|
|
33
|
-
export function createItineraryFromGraphItinerary(graphItinerary, mode = 'WALK') {
|
|
34
|
-
|
|
35
|
-
const leg = createLegFromGraphItinerary(graphItinerary, mode);
|
|
36
|
-
|
|
37
|
-
const itinerary = new Itinerary();
|
|
38
|
-
|
|
39
|
-
itinerary.from = graphItinerary.start;
|
|
40
|
-
itinerary.to = graphItinerary.end;
|
|
41
|
-
itinerary.distance = leg.distance;
|
|
42
|
-
itinerary.duration = leg.duration;
|
|
43
|
-
itinerary.legs.push(leg);
|
|
44
|
-
|
|
45
|
-
return itinerary;
|
|
46
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
/* eslint-disable complexity */
|
|
2
|
-
/* eslint-disable max-statements */
|
|
3
|
-
import { Coordinates, GraphItinerary } from '@wemap/geo';
|
|
4
|
-
import { diffAngle, deg2rad } from '@wemap/maths';
|
|
5
|
-
|
|
6
|
-
import OsmElement from '../../model/OsmElement.js';
|
|
7
|
-
import Step from '../Step.js';
|
|
8
|
-
import LevelChange from '../LevelChange.js';
|
|
9
|
-
|
|
10
|
-
const SKIP_STEP_ANGLE_MAX = deg2rad(20);
|
|
11
|
-
|
|
12
|
-
class StepsGeneration {
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* @param {GraphItinerary<OsmElement>} itinerary
|
|
16
|
-
* @returns {Step[]}
|
|
17
|
-
*/
|
|
18
|
-
static fromGraphItinerary(itinerary) {
|
|
19
|
-
|
|
20
|
-
const steps = [];
|
|
21
|
-
|
|
22
|
-
const { start, end, nodes, edges } = itinerary;
|
|
23
|
-
|
|
24
|
-
let currentStep, previousStep;
|
|
25
|
-
let previousBearing = start.bearingTo(nodes[0].coords);
|
|
26
|
-
|
|
27
|
-
for (let i = 0; i < nodes.length - 1; i++) {
|
|
28
|
-
|
|
29
|
-
const isFirstStep = !currentStep;
|
|
30
|
-
|
|
31
|
-
const node = nodes[i];
|
|
32
|
-
const nextNode = nodes[i + 1];
|
|
33
|
-
const edge = edges[i];
|
|
34
|
-
|
|
35
|
-
const bearing = edge.bearing;
|
|
36
|
-
const angle = diffAngle(previousBearing, bearing + Math.PI);
|
|
37
|
-
|
|
38
|
-
let splitByAngle = Math.abs(diffAngle(Math.PI, angle)) >= SKIP_STEP_ANGLE_MAX;
|
|
39
|
-
|
|
40
|
-
const splitByLevel = edge.level && edge.level.isRange
|
|
41
|
-
&& node.coords.level && !node.coords.level.isRange;
|
|
42
|
-
splitByAngle = splitByAngle && !(node.coords.level && node.coords.level.isRange);
|
|
43
|
-
|
|
44
|
-
const splitStepCondition = splitByAngle || splitByLevel;
|
|
45
|
-
|
|
46
|
-
const isSubwayEntrance = node ? node.builtFrom.tags.railway === 'subway_entrance' : false;
|
|
47
|
-
|
|
48
|
-
// New step creation
|
|
49
|
-
if (isFirstStep || splitStepCondition || isSubwayEntrance) {
|
|
50
|
-
|
|
51
|
-
previousStep = currentStep;
|
|
52
|
-
|
|
53
|
-
currentStep = new Step();
|
|
54
|
-
currentStep.coords = node.coords;
|
|
55
|
-
currentStep.number = steps.length + 1;
|
|
56
|
-
currentStep.angle = angle;
|
|
57
|
-
currentStep.previousBearing = previousBearing;
|
|
58
|
-
currentStep.nextBearing = bearing;
|
|
59
|
-
currentStep.name = edge.builtFrom.tags.name || null;
|
|
60
|
-
currentStep.distance = 0;
|
|
61
|
-
currentStep.duration = 0;
|
|
62
|
-
|
|
63
|
-
if (isSubwayEntrance) {
|
|
64
|
-
currentStep.extras.subwayEntrance = true;
|
|
65
|
-
currentStep.name = node.builtFrom.tags.name;
|
|
66
|
-
if (node.builtFrom.tags.ref) {
|
|
67
|
-
currentStep.extras.subwayEntranceRef = node.builtFrom.tags.ref;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (splitByLevel) {
|
|
72
|
-
currentStep.levelChange = LevelChange.fromTwoNodes(node, nextNode);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
steps.push(currentStep);
|
|
76
|
-
|
|
77
|
-
if (!previousStep) {
|
|
78
|
-
currentStep.firstStep = true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
currentStep.distance += edge.length;
|
|
83
|
-
currentStep.duration += itinerary.edgesWeights[i];
|
|
84
|
-
previousBearing = bearing;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const lastNode = nodes[nodes.length - 1];
|
|
88
|
-
const lastStep = new Step();
|
|
89
|
-
lastStep.coords = lastNode.coords;
|
|
90
|
-
lastStep.number = steps.length + 1;
|
|
91
|
-
lastStep.previousBearing = previousBearing;
|
|
92
|
-
lastStep.distance = lastNode.coords.distanceTo(end);
|
|
93
|
-
if (!Coordinates.equalsTo(lastNode.coords, end)) {
|
|
94
|
-
lastStep.nextBearing = lastNode.coords.bearingTo(end);
|
|
95
|
-
lastStep.angle = diffAngle(lastStep.previousBearing, lastStep.nextBearing + Math.PI);
|
|
96
|
-
}
|
|
97
|
-
lastStep.lastStep = true;
|
|
98
|
-
steps.push(lastStep);
|
|
99
|
-
|
|
100
|
-
return steps;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
export default StepsGeneration;
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
|
-
|
|
3
|
-
import { Coordinates, GraphEdge, GraphItinerary, GraphNode, Level } from '@wemap/geo';
|
|
4
|
-
|
|
5
|
-
import OsmNode from '../../model/OsmNode.js';
|
|
6
|
-
import OsmWay from '../../model/OsmWay.js';
|
|
7
|
-
import Itinerary from '../Itinerary.js';
|
|
8
|
-
import RouterResponse from '../RouterResponse.js';
|
|
9
|
-
import { generateStepsMetadata } from '../Utils.js';
|
|
10
|
-
import OsmElement from '../../model/OsmElement.js';
|
|
11
|
-
import StepsGeneration from '../custom/StepsGeneration.js';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Generate multi itineraries from the DB JSON
|
|
15
|
-
* @param {object} json JSON file provided by the DB.
|
|
16
|
-
* @param {Coordinates} from itinerary start
|
|
17
|
-
* @param {Coordinates} to itinerary end
|
|
18
|
-
* @returns {?RouterResponse}
|
|
19
|
-
*/
|
|
20
|
-
export function createRouterResponseFromJson(json, from, to) {
|
|
21
|
-
|
|
22
|
-
const { segments: jsonSegments } = json;
|
|
23
|
-
|
|
24
|
-
if (!jsonSegments) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const routerResponse = new RouterResponse();
|
|
29
|
-
routerResponse.routerName = 'deutsche-bahn';
|
|
30
|
-
|
|
31
|
-
routerResponse.from = from;
|
|
32
|
-
routerResponse.to = to;
|
|
33
|
-
|
|
34
|
-
/** @type {GraphEdge<OsmElement>[]} */
|
|
35
|
-
const edges = [];
|
|
36
|
-
|
|
37
|
-
/** @type {GraphNode<OsmElement>[]} */
|
|
38
|
-
const nodes = [];
|
|
39
|
-
|
|
40
|
-
/** @type {number[]} */
|
|
41
|
-
const edgesWeights = [];
|
|
42
|
-
|
|
43
|
-
let id = 1;
|
|
44
|
-
for (const jsonSegment of jsonSegments) {
|
|
45
|
-
|
|
46
|
-
const level = new Level(jsonSegment.fromLevel, jsonSegment.toLevel);
|
|
47
|
-
const osmWay = new OsmWay(id++, null, level);
|
|
48
|
-
|
|
49
|
-
for (const jsonPoint of jsonSegment.polyline) {
|
|
50
|
-
const coord = new Coordinates(jsonPoint.lat, jsonPoint.lon, null, level);
|
|
51
|
-
|
|
52
|
-
if (nodes.length !== 0
|
|
53
|
-
&& nodes[nodes.length - 1].coords.equalsTo(coord)) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const osmNode = new OsmNode(id++, coord);
|
|
58
|
-
const node = new GraphNode(osmNode.coords, osmNode);
|
|
59
|
-
|
|
60
|
-
if (nodes.length !== 0) {
|
|
61
|
-
const prevNode = nodes[nodes.length - 1];
|
|
62
|
-
const edge = new GraphEdge(prevNode, node, level, osmWay);
|
|
63
|
-
edges.push(edge);
|
|
64
|
-
edgesWeights.push(prevNode.coords.distanceTo(osmNode));
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
nodes.push(node);
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** @type {GraphItinerary<OsmElement>} */
|
|
73
|
-
const graphItinerary = new GraphItinerary();
|
|
74
|
-
graphItinerary.nodes = nodes;
|
|
75
|
-
graphItinerary.edges = edges;
|
|
76
|
-
graphItinerary.edgesWeights = edgesWeights;
|
|
77
|
-
graphItinerary.start = nodes[0].coords;
|
|
78
|
-
graphItinerary.end = nodes[nodes.length - 1].coords;
|
|
79
|
-
|
|
80
|
-
const points = nodes.map(node => node.coords);
|
|
81
|
-
const itinerary = Itinerary.fromOrderedCoordinates(points, from, to);
|
|
82
|
-
itinerary.legs[0].steps = StepsGeneration.fromGraphItinerary(graphItinerary);
|
|
83
|
-
itinerary.legs[0].steps.map((step, idx) => (step._idCoordsInLeg = idx));
|
|
84
|
-
|
|
85
|
-
// All legs have to be parsed before computing steps metadata
|
|
86
|
-
generateStepsMetadata(itinerary);
|
|
87
|
-
|
|
88
|
-
routerResponse.itineraries.push(itinerary);
|
|
89
|
-
|
|
90
|
-
return routerResponse;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
|
-
import chai from 'chai';
|
|
3
|
-
import chaiAlmost from 'chai-almost';
|
|
4
|
-
import fs from 'fs';
|
|
5
|
-
import path from 'path';
|
|
6
|
-
import { fileURLToPath } from 'url';
|
|
7
|
-
|
|
8
|
-
import { Coordinates, Level } from '@wemap/geo';
|
|
9
|
-
|
|
10
|
-
import { createRouterResponseFromJson } from './DeutscheBahnRouterUtils.js';
|
|
11
|
-
|
|
12
|
-
import { verifyRouterResponseData } from '../RouterResponse.type.spec.js';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const { expect } = chai;
|
|
16
|
-
chai.use(chaiAlmost(0.1));
|
|
17
|
-
|
|
18
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
-
|
|
20
|
-
describe('OtpUtils - createRouterResponseFromJson', () => {
|
|
21
|
-
|
|
22
|
-
it('RouterResponse - 1', () => {
|
|
23
|
-
|
|
24
|
-
const filePath = path.resolve(__dirname, '../../../assets/itinerary-deutsche-bahn-1.json');
|
|
25
|
-
const fileString = fs.readFileSync(filePath, 'utf8');
|
|
26
|
-
const json = JSON.parse(fileString);
|
|
27
|
-
|
|
28
|
-
const from = new Coordinates(52.5258473, 13.3683657, null, new Level(-10));
|
|
29
|
-
const to = new Coordinates(52.52499085853664, 13.369467296949914, null, new Level(0));
|
|
30
|
-
|
|
31
|
-
const routerResponse = createRouterResponseFromJson(json, from, to);
|
|
32
|
-
verifyRouterResponseData(routerResponse);
|
|
33
|
-
|
|
34
|
-
expect(routerResponse.routerName).equal('deutsche-bahn');
|
|
35
|
-
expect(routerResponse.itineraries.length).equal(1);
|
|
36
|
-
expect(routerResponse.from.equalsTo(from)).true;
|
|
37
|
-
expect(routerResponse.to.equalsTo(to)).true;
|
|
38
|
-
|
|
39
|
-
const itinerary1 = routerResponse.itineraries[0];
|
|
40
|
-
expect(itinerary1.coords.length).equal(77);
|
|
41
|
-
expect(itinerary1.distance).almost.equal(129.673);
|
|
42
|
-
expect(itinerary1.duration).almost.equal(93.365);
|
|
43
|
-
|
|
44
|
-
const itinerary1leg1 = itinerary1.legs[0];
|
|
45
|
-
expect(itinerary1leg1.distance).almost.equal(129.673);
|
|
46
|
-
expect(itinerary1leg1.mode).equal('WALK');
|
|
47
|
-
expect(itinerary1leg1.from.name).is.null;
|
|
48
|
-
expect(itinerary1leg1.from.coords.equalsTo(from)).true;
|
|
49
|
-
expect(itinerary1leg1.to.name).is.null;
|
|
50
|
-
expect(itinerary1leg1.to.coords.equalsTo(to)).true;
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
|
|
@@ -1,34 +0,0 @@
|
|
|
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;
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
|
-
import { Coordinates, GraphEdge, GraphNode, MapMatching, Network } from '@wemap/geo';
|
|
3
|
-
|
|
4
|
-
import Itinerary from '../Itinerary.js';
|
|
5
|
-
import Leg from '../Leg.js';
|
|
6
|
-
import Step from '../Step.js';
|
|
7
|
-
import ItineraryInfo from './ItineraryInfo.js';
|
|
8
|
-
|
|
9
|
-
class ItineraryInfoManager {
|
|
10
|
-
|
|
11
|
-
/** @type {Itinerary} */
|
|
12
|
-
_itinerary;
|
|
13
|
-
|
|
14
|
-
/** @type {Network} */
|
|
15
|
-
_network;
|
|
16
|
-
|
|
17
|
-
/** @type {Network} */
|
|
18
|
-
_mapMatching;
|
|
19
|
-
|
|
20
|
-
/** @type {Step[]} */
|
|
21
|
-
_steps;
|
|
22
|
-
|
|
23
|
-
/** @type {Step[]} */
|
|
24
|
-
_coordsNextStep;
|
|
25
|
-
|
|
26
|
-
/** @type {Step[]} */
|
|
27
|
-
_coordsPreviousStep;
|
|
28
|
-
|
|
29
|
-
/** @type {number[]} */
|
|
30
|
-
_coordsDistanceTraveled;
|
|
31
|
-
|
|
32
|
-
/** @type {Leg[]} */
|
|
33
|
-
_coordsLeg;
|
|
34
|
-
|
|
35
|
-
/** @type {Itinerary} */
|
|
36
|
-
set itinerary(itinerary) {
|
|
37
|
-
|
|
38
|
-
if (itinerary === null) {
|
|
39
|
-
this._itinerary = null;
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
this._itinerary = itinerary;
|
|
44
|
-
this._steps = itinerary.steps;
|
|
45
|
-
this._network = itinerary.toNetwork();
|
|
46
|
-
this._mapMatching = new MapMatching(this._network);
|
|
47
|
-
|
|
48
|
-
this._coordsNextStep = new Array(itinerary.coords.length);
|
|
49
|
-
this._coordsPreviousStep = new Array(itinerary.coords.length);
|
|
50
|
-
this._coordsDistanceTraveled = new Array(itinerary.coords.length);
|
|
51
|
-
this._coordsLeg = new Array(itinerary.coords.length);
|
|
52
|
-
|
|
53
|
-
let stepId = 0;
|
|
54
|
-
let previousStep = null;
|
|
55
|
-
let nextStep = this._steps[0];
|
|
56
|
-
let distanceTraveled = 0;
|
|
57
|
-
|
|
58
|
-
itinerary.coords.forEach((coords, idx, arr) => {
|
|
59
|
-
if (stepId < this._steps.length && this._steps[stepId].coords.equalsTo(coords)) {
|
|
60
|
-
previousStep = this._steps[stepId];
|
|
61
|
-
nextStep = stepId === this._steps.length - 1 ? null : this._steps[stepId + 1];
|
|
62
|
-
stepId++;
|
|
63
|
-
}
|
|
64
|
-
if (idx !== 0) {
|
|
65
|
-
distanceTraveled += arr[idx - 1].distanceTo(coords);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
this._coordsNextStep[idx] = nextStep;
|
|
69
|
-
this._coordsPreviousStep[idx] = previousStep;
|
|
70
|
-
this._coordsDistanceTraveled[idx] = distanceTraveled;
|
|
71
|
-
this._coordsLeg[idx] = itinerary.legs.find(leg => leg.coords.includes(coords));
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* @param {Coordinates} position
|
|
77
|
-
* @returns {ItineraryInfo}
|
|
78
|
-
*/
|
|
79
|
-
getInfo(position) {
|
|
80
|
-
|
|
81
|
-
if (!this._itinerary) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (!(position instanceof Coordinates)) {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const projection = this._mapMatching.getProjection(position);
|
|
90
|
-
if (!projection) {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
let itineraryInfo = null;
|
|
95
|
-
|
|
96
|
-
if (projection.nearestElement instanceof GraphNode) {
|
|
97
|
-
const idx = this._itinerary.coords.findIndex(
|
|
98
|
-
coords => projection.nearestElement.coords === coords
|
|
99
|
-
);
|
|
100
|
-
if (idx === -1) {
|
|
101
|
-
throw new Error('ItineraryInfoManager: could not find projection in itinerary (Node)');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
itineraryInfo = new ItineraryInfo();
|
|
105
|
-
itineraryInfo.nextStep = this._coordsNextStep[idx];
|
|
106
|
-
itineraryInfo.previousStep = this._coordsPreviousStep[idx];
|
|
107
|
-
itineraryInfo.projection = projection;
|
|
108
|
-
itineraryInfo.leg = this._coordsLeg[idx];
|
|
109
|
-
itineraryInfo.traveledDistance = this._coordsDistanceTraveled[idx];
|
|
110
|
-
itineraryInfo.remainingDistance = this._itinerary.distance - itineraryInfo.traveledDistance;
|
|
111
|
-
itineraryInfo.traveledPercentage = itineraryInfo.traveledDistance / this._itinerary.distance;
|
|
112
|
-
itineraryInfo.remainingPercentage = itineraryInfo.remainingDistance / this._itinerary.distance;
|
|
113
|
-
|
|
114
|
-
} else if (projection.nearestElement instanceof GraphEdge) {
|
|
115
|
-
|
|
116
|
-
let firstNode = projection.nearestElement.node1.coords;
|
|
117
|
-
let idx = this._itinerary.coords.findIndex(coords => firstNode === coords);
|
|
118
|
-
if (idx === -1) {
|
|
119
|
-
throw new Error('ItineraryInfoManager: could not find projection in itinerary (Edge)');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// graphEdge is not necessarly ordered. We have to look for the first point
|
|
123
|
-
if (idx === this._itinerary.coords.length - 1
|
|
124
|
-
|| this._itinerary.coords[idx + 1] !== projection.nearestElement.node2.coords
|
|
125
|
-
) {
|
|
126
|
-
firstNode = projection.nearestElement.node2.coords;
|
|
127
|
-
idx--;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
itineraryInfo = new ItineraryInfo();
|
|
131
|
-
itineraryInfo.nextStep = this._coordsNextStep[idx];
|
|
132
|
-
itineraryInfo.previousStep = this._coordsPreviousStep[idx];
|
|
133
|
-
itineraryInfo.projection = projection;
|
|
134
|
-
itineraryInfo.leg = this._coordsLeg[idx];
|
|
135
|
-
itineraryInfo.traveledDistance = this._coordsDistanceTraveled[idx]
|
|
136
|
-
+ projection.projection.distanceTo(firstNode);
|
|
137
|
-
itineraryInfo.remainingDistance = this._itinerary.distance - itineraryInfo.traveledDistance;
|
|
138
|
-
itineraryInfo.traveledPercentage = itineraryInfo.traveledDistance / this._itinerary.distance;
|
|
139
|
-
itineraryInfo.remainingPercentage = itineraryInfo.remainingDistance / this._itinerary.distance;
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return itineraryInfo;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export default ItineraryInfoManager;
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import chai from 'chai';
|
|
2
|
-
import chaiAlmost from 'chai-almost';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
|
|
7
|
-
import { Coordinates, GraphEdge, GraphNode } from '@wemap/geo';
|
|
8
|
-
|
|
9
|
-
import { createRouterResponseFromJson } from '../otp/OtpUtils.js';
|
|
10
|
-
import ItineraryInfoManager from './ItineraryInfoManager.js';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const { expect } = chai;
|
|
14
|
-
chai.use(chaiAlmost(0.1));
|
|
15
|
-
|
|
16
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
const filePath = path.resolve(__dirname, '../../../assets/itinerary-grenoble-otp-1.json');
|
|
20
|
-
const fileString = fs.readFileSync(filePath, 'utf8');
|
|
21
|
-
const json = JSON.parse(fileString);
|
|
22
|
-
const routerResponse = createRouterResponseFromJson(json);
|
|
23
|
-
|
|
24
|
-
let position, itineraryInfo;
|
|
25
|
-
|
|
26
|
-
describe('ItineraryInfoManager', () => {
|
|
27
|
-
|
|
28
|
-
it('verify integrity', () => {
|
|
29
|
-
|
|
30
|
-
const itinerary = routerResponse.itineraries[0];
|
|
31
|
-
const iim = new ItineraryInfoManager();
|
|
32
|
-
iim.itinerary = itinerary;
|
|
33
|
-
|
|
34
|
-
position = new Coordinates(45.1641153, 5.741293);
|
|
35
|
-
itineraryInfo = iim.getInfo(position);
|
|
36
|
-
expect(itineraryInfo.projection.nearestElement).instanceOf(GraphNode);
|
|
37
|
-
expect(itineraryInfo.nextStep).is.null;
|
|
38
|
-
expect(itineraryInfo.previousStep).equals(itinerary.legs[2].steps[3]);
|
|
39
|
-
expect(itineraryInfo.remainingDistance).almost.equals(56.095);
|
|
40
|
-
expect(itineraryInfo.remainingPercentage).almost.equals(0.0155);
|
|
41
|
-
expect(itineraryInfo.leg).almost.equals(itinerary.legs[2]);
|
|
42
|
-
|
|
43
|
-
position = new Coordinates(45.1641691, 5.7413891);
|
|
44
|
-
itineraryInfo = iim.getInfo(position);
|
|
45
|
-
expect(itineraryInfo.projection.nearestElement).instanceOf(GraphEdge);
|
|
46
|
-
expect(itineraryInfo.nextStep).equals(itinerary.legs[2].steps[3]);
|
|
47
|
-
expect(itineraryInfo.previousStep).equals(itinerary.legs[2].steps[2]);
|
|
48
|
-
expect(itineraryInfo.remainingDistance).almost.equals(65.671);
|
|
49
|
-
expect(itineraryInfo.remainingPercentage).almost.equals(0.018);
|
|
50
|
-
expect(itineraryInfo.leg).almost.equals(itinerary.legs[2]);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
|