@wemap/osm 3.2.16 → 4.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/assets/bureaux-wemap-montpellier-network.osm +10 -0
- package/assets/network-elevator.osm +26 -26
- package/index.js +7 -19
- package/package.json +5 -6
- package/src/model/OsmModel.js +1 -0
- package/src/model/OsmWay.js +4 -2
- package/src/network/OsmNetworkUtils.js +159 -0
- package/src/network/OsmNetworkUtils.spec.js +130 -0
- package/src/network/OsmRouter.spec.js +29 -18
- package/src/osrm/OsrmUtils.js +224 -256
- package/src/osrm/OsrmUtils.spec.js +46 -31
- package/src/network/OsmNetwork.js +0 -156
- package/src/network/OsmNetwork.spec.js +0 -107
- package/src/network/OsmRouter.js +0 -75
|
@@ -5,16 +5,19 @@ import path from 'path';
|
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
|
|
7
7
|
import {
|
|
8
|
-
Level, Coordinates
|
|
8
|
+
Level, Coordinates, Edge, GraphRouter
|
|
9
9
|
} from '@wemap/geo';
|
|
10
|
-
import {
|
|
10
|
+
import { verifyCoherence } from '@wemap/geo/tests/CommonTest.js';
|
|
11
11
|
|
|
12
12
|
import OsmParser from '../model/OsmParser.js';
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
import OsmNetworkUtils from '../network/OsmNetworkUtils.js';
|
|
14
|
+
import {
|
|
15
|
+
itineraryToOsrmJson,
|
|
16
|
+
jsonToCoordinates,
|
|
17
|
+
createItineraryFromJson,
|
|
18
|
+
getModifierFromAngle,
|
|
19
|
+
noRouteFoundJson
|
|
20
|
+
} from './OsrmUtils.js';
|
|
18
21
|
|
|
19
22
|
const { expect } = chai;
|
|
20
23
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -24,8 +27,8 @@ const load = fileName => {
|
|
|
24
27
|
const filePath = path.resolve(__dirname, '../../assets/' + fileName);
|
|
25
28
|
const osmXmlString = fs.readFileSync(filePath, 'utf8');
|
|
26
29
|
const model = OsmParser.parseOsmXmlString(osmXmlString);
|
|
27
|
-
const network =
|
|
28
|
-
const router = new
|
|
30
|
+
const network = OsmNetworkUtils.createNetworkFromOsmModel(model);
|
|
31
|
+
const router = new GraphRouter(network);
|
|
29
32
|
return {
|
|
30
33
|
network,
|
|
31
34
|
router
|
|
@@ -48,7 +51,7 @@ describe('OsrmUtils - itineraryToOsrmJson', () => {
|
|
|
48
51
|
const itinerary = router.getShortestPath(wemapIndoorStart, wemapIndoorEnd);
|
|
49
52
|
wemapIndoorItinerary = itinerary;
|
|
50
53
|
|
|
51
|
-
const osrmJson =
|
|
54
|
+
const osrmJson = itineraryToOsrmJson(itinerary);
|
|
52
55
|
wemapIndoorJsonItinerary = osrmJson;
|
|
53
56
|
const itinerarySteps = itinerary.steps;
|
|
54
57
|
|
|
@@ -64,7 +67,7 @@ describe('OsrmUtils - itineraryToOsrmJson', () => {
|
|
|
64
67
|
for (let i = 1; i < 11; i++) {
|
|
65
68
|
expect(
|
|
66
69
|
network.getNodeByName('p' + (i + 6)).coords.equalsTo(
|
|
67
|
-
|
|
70
|
+
jsonToCoordinates(coordinates[i]))
|
|
68
71
|
).true;
|
|
69
72
|
}
|
|
70
73
|
|
|
@@ -76,7 +79,7 @@ describe('OsrmUtils - itineraryToOsrmJson', () => {
|
|
|
76
79
|
const {
|
|
77
80
|
location, type
|
|
78
81
|
} = steps[i].maneuver;
|
|
79
|
-
expect(itinerarySteps[i].node.coords.equalsTo(
|
|
82
|
+
expect(itinerarySteps[i].node.coords.equalsTo(jsonToCoordinates(location))).true;
|
|
80
83
|
|
|
81
84
|
let expectedType;
|
|
82
85
|
switch (i) {
|
|
@@ -141,7 +144,7 @@ describe('OsrmUtils - itineraryToOsrmJson', () => {
|
|
|
141
144
|
|
|
142
145
|
const itinerary = router.getShortestPath(start, end);
|
|
143
146
|
|
|
144
|
-
wemapOutdoorJsonItinerary =
|
|
147
|
+
wemapOutdoorJsonItinerary = itineraryToOsrmJson(itinerary);
|
|
145
148
|
|
|
146
149
|
wemapOutdoorStart = start.coords;
|
|
147
150
|
wemapOutdoorEnd = end.coords;
|
|
@@ -158,7 +161,7 @@ describe('OsrmUtils - itineraryToOsrmJson', () => {
|
|
|
158
161
|
const end = network.getNodeByName('end');
|
|
159
162
|
|
|
160
163
|
const itinerary = router.getShortestPath(start, end);
|
|
161
|
-
expect(() =>
|
|
164
|
+
expect(() => itineraryToOsrmJson(itinerary)).not.throw(Error);
|
|
162
165
|
|
|
163
166
|
});
|
|
164
167
|
|
|
@@ -178,7 +181,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
178
181
|
const start = new Coordinates(43.6007871, 3.8757218000000004);
|
|
179
182
|
const end = new Coordinates(43.598877, 3.873866);
|
|
180
183
|
|
|
181
|
-
const itinerary =
|
|
184
|
+
const itinerary = createItineraryFromJson(json, start, end);
|
|
182
185
|
|
|
183
186
|
expect(json.routes[0].geometry.coordinates.length).equal(itinerary.nodes.length);
|
|
184
187
|
expect(itinerary.nodes.length).equal(itinerary.edges.length + 1);
|
|
@@ -190,7 +193,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
190
193
|
let step;
|
|
191
194
|
step = steps[0];
|
|
192
195
|
expect(Coordinates.equalsTo(step.location, new Coordinates(43.600777, 3.875607))).true;
|
|
193
|
-
expect(
|
|
196
|
+
expect(getModifierFromAngle(step.angle)).equals('left');
|
|
194
197
|
expect(step.nodes.length).equals(6);
|
|
195
198
|
expect(step.edges.length).equals(5);
|
|
196
199
|
expect(step.firstStep).true;
|
|
@@ -199,7 +202,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
199
202
|
|
|
200
203
|
step = steps[1];
|
|
201
204
|
expect(Coordinates.equalsTo(step.location, new Coordinates(43.599881, 3.876396))).true;
|
|
202
|
-
expect(
|
|
205
|
+
expect(getModifierFromAngle(step.angle)).equals('right');
|
|
203
206
|
expect(step.nodes.length).equals(12);
|
|
204
207
|
expect(step.edges.length).equals(11);
|
|
205
208
|
expect(step.firstStep).false;
|
|
@@ -208,7 +211,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
208
211
|
|
|
209
212
|
step = steps[2];
|
|
210
213
|
expect(Coordinates.equalsTo(step.location, new Coordinates(43.599577, 3.874655))).true;
|
|
211
|
-
expect(
|
|
214
|
+
expect(getModifierFromAngle(step.angle)).equals('left');
|
|
212
215
|
expect(step.nodes.length).equals(2);
|
|
213
216
|
expect(step.edges.length).equals(1);
|
|
214
217
|
expect(step.firstStep).false;
|
|
@@ -217,7 +220,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
217
220
|
|
|
218
221
|
step = steps[3];
|
|
219
222
|
expect(Coordinates.equalsTo(step.location, new Coordinates(43.599063, 3.874623))).true;
|
|
220
|
-
expect(
|
|
223
|
+
expect(getModifierFromAngle(step.angle)).equals('right');
|
|
221
224
|
expect(step.nodes.length).equals(2);
|
|
222
225
|
expect(step.edges.length).equals(1);
|
|
223
226
|
expect(step.firstStep).false;
|
|
@@ -226,7 +229,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
226
229
|
|
|
227
230
|
step = steps[4];
|
|
228
231
|
expect(Coordinates.equalsTo(step.location, new Coordinates(43.59906, 3.873865))).true;
|
|
229
|
-
expect(
|
|
232
|
+
expect(getModifierFromAngle(step.angle)).equals('left');
|
|
230
233
|
expect(step.nodes.length).equals(1);
|
|
231
234
|
expect(step.edges.length).equals(0);
|
|
232
235
|
expect(step.firstStep).false;
|
|
@@ -248,7 +251,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
248
251
|
|
|
249
252
|
it('Without levels (from itineraryToOsrmJson)', () => {
|
|
250
253
|
|
|
251
|
-
const itinerary =
|
|
254
|
+
const itinerary = createItineraryFromJson(wemapOutdoorJsonItinerary,
|
|
252
255
|
wemapOutdoorStart, wemapOutdoorEnd);
|
|
253
256
|
|
|
254
257
|
expect(itinerary.nodes.length).equal(wemapOutdoorItinerary.nodes.length);
|
|
@@ -282,7 +285,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
282
285
|
const start = new Coordinates(43.6007871, 3.8757218000000004);
|
|
283
286
|
const end = new Coordinates(43.598877, 3.873866);
|
|
284
287
|
|
|
285
|
-
const itinerary =
|
|
288
|
+
const itinerary = createItineraryFromJson(json, start, end);
|
|
286
289
|
|
|
287
290
|
expect(json.routes[0].geometry.coordinates.length).equal(itinerary.nodes.length);
|
|
288
291
|
expect(itinerary.nodes.length).equal(itinerary.edges.length + 1);
|
|
@@ -295,7 +298,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
295
298
|
|
|
296
299
|
it('With levels (from itineraryToOsrmJson)', () => {
|
|
297
300
|
|
|
298
|
-
const itinerary =
|
|
301
|
+
const itinerary = createItineraryFromJson(wemapIndoorJsonItinerary,
|
|
299
302
|
wemapIndoorStart, wemapIndoorEnd);
|
|
300
303
|
|
|
301
304
|
expect(itinerary.nodes.length).equal(wemapIndoorItinerary.nodes.length);
|
|
@@ -329,7 +332,7 @@ describe('OsrmUtils - createItineraryFromJson', () => {
|
|
|
329
332
|
const start = new Coordinates(44.810569099999995, 4.9503924999999995);
|
|
330
333
|
const end = new Coordinates(44.302673, 4.556377);
|
|
331
334
|
|
|
332
|
-
const itinerary =
|
|
335
|
+
const itinerary = createItineraryFromJson(json, start, end);
|
|
333
336
|
itinerary.edges.forEach(edge => {
|
|
334
337
|
expect(edge).instanceOf(Edge);
|
|
335
338
|
});
|
|
@@ -352,22 +355,34 @@ describe('OsrmUtils - itineraryToOsrmJson - createItineraryFromJson - way/node',
|
|
|
352
355
|
const end = new Coordinates(43.60949854, 3.88452048, null, new Level(0));
|
|
353
356
|
const itinerary = router.getShortestPath(start, end);
|
|
354
357
|
|
|
355
|
-
const osrmJson =
|
|
358
|
+
const osrmJson = itineraryToOsrmJson(itinerary);
|
|
356
359
|
const jsonSteps = osrmJson.routes[0].legs[0].steps;
|
|
357
360
|
|
|
358
|
-
expect(jsonSteps[0].wemap.
|
|
359
|
-
expect(jsonSteps[
|
|
361
|
+
expect(jsonSteps[0].wemap.nextEdgeProperties.name).equals('w2');
|
|
362
|
+
expect(jsonSteps[0].wemap.nextEdgeProperties.level).equals('2');
|
|
363
|
+
expect(jsonSteps[0].wemap.nodeProperties.name).equals('w2');
|
|
364
|
+
|
|
365
|
+
expect(jsonSteps[4].wemap.nextEdgeProperties.name).equals('p19');
|
|
366
|
+
expect(jsonSteps[4].wemap.nextEdgeProperties.level).equals('0;2');
|
|
367
|
+
expect(jsonSteps[4].wemap.nodeProperties.name).equals('p19');
|
|
368
|
+
|
|
369
|
+
expect(jsonSteps[6].name).equals('p21');
|
|
370
|
+
expect(jsonSteps[6].wemap.nextEdgeProperties).is.undefined;
|
|
371
|
+
expect(jsonSteps[6].wemap.nodeProperties.name).equals('p21');
|
|
372
|
+
|
|
373
|
+
const itineraryBis = createItineraryFromJson(osrmJson, start, end);
|
|
374
|
+
verifyCoherence(itineraryBis);
|
|
360
375
|
|
|
361
|
-
|
|
362
|
-
expect(itineraryBis.
|
|
363
|
-
expect(itineraryBis.steps
|
|
376
|
+
expect(itineraryBis.nodes.length).equals(itinerary.nodes.length);
|
|
377
|
+
expect(itineraryBis.edges.length).equals(itinerary.edges.length);
|
|
378
|
+
expect(itineraryBis.steps.length).equals(itinerary.steps.length);
|
|
364
379
|
});
|
|
365
380
|
});
|
|
366
381
|
|
|
367
382
|
describe('OsrmUtils - Output JSON', () => {
|
|
368
383
|
|
|
369
384
|
it('noRouteFoundJson', () => {
|
|
370
|
-
expect(
|
|
385
|
+
expect(noRouteFoundJson('foo')).deep.equals({
|
|
371
386
|
'code': 'NoRoute',
|
|
372
387
|
'message': 'foo'
|
|
373
388
|
});
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { Level } from '@wemap/geo';
|
|
2
|
-
import {
|
|
3
|
-
Edge, Node, Network
|
|
4
|
-
} from '@wemap/graph';
|
|
5
|
-
|
|
6
|
-
import OsmModel from '../model/OsmModel.js';
|
|
7
|
-
|
|
8
|
-
const HIGHWAYS_PEDESTRIANS = ['footway', 'steps', 'pedestrian', 'living_street', 'path', 'track', 'sidewalk'];
|
|
9
|
-
const DEFAULT_WAY_SELECTOR = way => HIGHWAYS_PEDESTRIANS.includes(way.tags.highway) || way.tags.footway === 'sidewalk';
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* A typical network with nodes (Node) and edges (Edge)
|
|
13
|
-
*/
|
|
14
|
-
class OsmNetwork extends Network {
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @param {OsmModel} osmModel
|
|
18
|
-
* @param {function} _waySelectionFilter
|
|
19
|
-
* @returns {OsmNetwork}
|
|
20
|
-
*/
|
|
21
|
-
static fromOsmModel(osmModel, _waySelectionFilter) {
|
|
22
|
-
|
|
23
|
-
const waySelectionFilter = _waySelectionFilter || DEFAULT_WAY_SELECTOR;
|
|
24
|
-
|
|
25
|
-
const networkModel = new OsmNetwork();
|
|
26
|
-
|
|
27
|
-
const getOrCreateNode = osmNode => {
|
|
28
|
-
let node = networkModel.nodes.find(graphNode => osmNode.id === graphNode.data.id);
|
|
29
|
-
if (!node) {
|
|
30
|
-
node = new Node(osmNode.coords, osmNode);
|
|
31
|
-
networkModel.nodes.push(node);
|
|
32
|
-
}
|
|
33
|
-
return node;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
osmModel.ways.forEach(way => {
|
|
37
|
-
if (!waySelectionFilter(way)) {
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
let firstNode = getOrCreateNode(way.nodes[0]);
|
|
42
|
-
for (let i = 1; i < way.nodes.length; i++) {
|
|
43
|
-
const secondNode = getOrCreateNode(way.nodes[i]);
|
|
44
|
-
|
|
45
|
-
const edge = new Edge(firstNode, secondNode);
|
|
46
|
-
edge.data = way;
|
|
47
|
-
edge.level = way.level;
|
|
48
|
-
networkModel.edges.push(edge);
|
|
49
|
-
|
|
50
|
-
firstNode = secondNode;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
networkModel.nodes.forEach(node => {
|
|
56
|
-
if (node.data.tags.highway === 'elevator') {
|
|
57
|
-
// We have to clone this node for each connected edge
|
|
58
|
-
OsmNetwork._createNodesAndEdgesFromElevator(networkModel, node);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
Node.generateNodesLevels(networkModel.nodes);
|
|
63
|
-
|
|
64
|
-
return networkModel;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
static _createNodesAndEdgesFromElevator(networkModel, node) {
|
|
68
|
-
|
|
69
|
-
const createdNodes = [];
|
|
70
|
-
const isLevelAlreadyCreated = level => createdNodes.some(
|
|
71
|
-
createdNode => Level.equalsTo(level, createdNode.coords.level)
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
// Create nodes from node.edges
|
|
75
|
-
node.edges.forEach(edge => {
|
|
76
|
-
if (edge.level.isRange) {
|
|
77
|
-
throw new Error('Cannot handle this elevator edge due to ambiguity');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (isLevelAlreadyCreated(edge.level)) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const newNode = node.clone();
|
|
85
|
-
newNode.coords = node.coords.clone();
|
|
86
|
-
newNode.coords.level = edge.level.clone();
|
|
87
|
-
|
|
88
|
-
const otherNode = edge.node1 === node ? edge.node2 : edge.node1;
|
|
89
|
-
otherNode.edges = otherNode.edges.filter(_edge => _edge !== edge);
|
|
90
|
-
const modifiedEdge = new Edge(newNode, otherNode, edge.data, edge.level);
|
|
91
|
-
networkModel.edges.push(modifiedEdge);
|
|
92
|
-
|
|
93
|
-
createdNodes.push(newNode);
|
|
94
|
-
networkModel.nodes.push(newNode);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Create edges from createdNodes
|
|
98
|
-
for (let i = 0; i < createdNodes.length; i++) {
|
|
99
|
-
for (let j = i + 1; j < createdNodes.length; j++) {
|
|
100
|
-
|
|
101
|
-
const createdNode1 = createdNodes[i];
|
|
102
|
-
const createdNode2 = createdNodes[j];
|
|
103
|
-
|
|
104
|
-
const newEdge = new Edge(
|
|
105
|
-
createdNode1,
|
|
106
|
-
createdNode2,
|
|
107
|
-
createdNode1.data,
|
|
108
|
-
new Level(createdNode1.coords.level.val, createdNode2.coords.level.val)
|
|
109
|
-
);
|
|
110
|
-
networkModel.edges.push(newEdge);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
networkModel.nodes = networkModel.nodes.filter(_node => _node !== node);
|
|
115
|
-
networkModel.edges = networkModel.edges.filter(edge =>
|
|
116
|
-
!node.edges.some(_edge => _edge === edge)
|
|
117
|
-
);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* @param {number} id
|
|
122
|
-
* @returns {Node}
|
|
123
|
-
*/
|
|
124
|
-
getNodeById(id) {
|
|
125
|
-
return this.nodes.find(node => node.data.id === id);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* @param {name} name
|
|
130
|
-
* @returns {Node}
|
|
131
|
-
*/
|
|
132
|
-
getNodeByName(name) {
|
|
133
|
-
return this.nodes.find(node => node.data.tags.name === name);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @param {number} id
|
|
138
|
-
* @returns {Edge[]}
|
|
139
|
-
*/
|
|
140
|
-
getEdgesById(id) {
|
|
141
|
-
return this.edges.filter(edge => edge.data.id === id);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* @returns {string}
|
|
146
|
-
*/
|
|
147
|
-
toDetailedString() {
|
|
148
|
-
return super.toDetailedString(
|
|
149
|
-
node => node.data.tags.name,
|
|
150
|
-
edge => edge.data.id
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export default OsmNetwork;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
|
-
import chai from 'chai';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
|
|
7
|
-
import OsmParser from '../model/OsmParser.js';
|
|
8
|
-
import OsmNetwork from './OsmNetwork.js';
|
|
9
|
-
|
|
10
|
-
const { expect } = chai;
|
|
11
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const loadFile = fileName => {
|
|
15
|
-
const filePath = path.resolve(__dirname, '../../assets/' + fileName);
|
|
16
|
-
return fs.readFileSync(filePath, 'utf8');
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
describe('OsmNetwork - simple', () => {
|
|
20
|
-
|
|
21
|
-
let osmModel, osmNetwork;
|
|
22
|
-
const osmXmlString = loadFile('network-simple.osm');
|
|
23
|
-
|
|
24
|
-
it('Network creation', () => {
|
|
25
|
-
|
|
26
|
-
osmModel = OsmParser.parseOsmXmlString(osmXmlString);
|
|
27
|
-
osmNetwork = OsmNetwork.fromOsmModel(osmModel);
|
|
28
|
-
|
|
29
|
-
expect(osmNetwork.nodes.length).equals(3);
|
|
30
|
-
expect(osmNetwork.edges.length).equals(2);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
it('Network creation - waySelectionFilter', () => {
|
|
35
|
-
|
|
36
|
-
const selectionNetwork = OsmNetwork.fromOsmModel(osmModel, () => true);
|
|
37
|
-
|
|
38
|
-
expect(selectionNetwork.nodes.length).equals(4);
|
|
39
|
-
expect(selectionNetwork.edges.length).equals(3);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('Network creation - elevator', () => {
|
|
43
|
-
|
|
44
|
-
const elevatorModel = OsmParser.parseOsmXmlString(loadFile('network-elevator.osm'));
|
|
45
|
-
const elevatorNetwork = OsmNetwork.fromOsmModel(elevatorModel);
|
|
46
|
-
|
|
47
|
-
expect(elevatorNetwork.nodes.length).equals(7);
|
|
48
|
-
expect(elevatorNetwork.edges.length).equals(6);
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const osmModel2 = OsmParser.parseOsmXmlString(`
|
|
52
|
-
<osm>
|
|
53
|
-
<node id='1' lat='43' lon='4'>
|
|
54
|
-
<tag k='highway' v='elevator' />
|
|
55
|
-
<tag k='level' v='0;1' />
|
|
56
|
-
</node>
|
|
57
|
-
<node id='2' lat='43' lon='3' />
|
|
58
|
-
<way id='3'>
|
|
59
|
-
<nd ref='1' />
|
|
60
|
-
<nd ref='2' />
|
|
61
|
-
<tag k='highway' v='footway' />
|
|
62
|
-
<tag k='level' v='0;1' />
|
|
63
|
-
</way>
|
|
64
|
-
</osm>
|
|
65
|
-
`);
|
|
66
|
-
expect(() => OsmNetwork.fromOsmModel(osmModel2)).throw(Error);
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
it('getNodeById', () => {
|
|
71
|
-
let node = osmNetwork.getNodeById(1);
|
|
72
|
-
expect(node).not.null;
|
|
73
|
-
expect(node.data.tags.name).equals('p1');
|
|
74
|
-
|
|
75
|
-
node = osmNetwork.getNodeById(5);
|
|
76
|
-
expect(node).undefined;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
it('getNodeByName', () => {
|
|
81
|
-
let node = osmNetwork.getNodeByName('p1');
|
|
82
|
-
expect(node).not.undefined;
|
|
83
|
-
|
|
84
|
-
node = osmNetwork.getNodeByName('p5');
|
|
85
|
-
expect(node).undefined;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('getEdgesById', () => {
|
|
89
|
-
let edges = osmNetwork.getEdgesById(101);
|
|
90
|
-
expect(edges.length).equals(2);
|
|
91
|
-
expect(edges[0].data.tags.name).equals('w1');
|
|
92
|
-
expect(edges[0].node1.data.tags.name).equals('p1');
|
|
93
|
-
expect(edges[0].node2.data.tags.name).equals('p2');
|
|
94
|
-
expect(edges[1].data.tags.name).equals('w1');
|
|
95
|
-
expect(edges[1].node1.data.tags.name).equals('p2');
|
|
96
|
-
expect(edges[1].node2.data.tags.name).equals('p3');
|
|
97
|
-
|
|
98
|
-
edges = osmNetwork.getEdgesById(3);
|
|
99
|
-
expect(edges.length).equals(0);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('toDetailedString', () => {
|
|
103
|
-
expect(() => osmNetwork.toDetailedString()).not.throw(Error);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
|
package/src/network/OsmRouter.js
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { Coordinates } from '@wemap/geo';
|
|
2
|
-
import {
|
|
3
|
-
Edge, GraphRouter, Node, Utils
|
|
4
|
-
} from '@wemap/graph';
|
|
5
|
-
|
|
6
|
-
const DEFAULT_OPTIONS = { useStairs: true };
|
|
7
|
-
|
|
8
|
-
class OsmRouter extends GraphRouter {
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @param {Node|Coordinates} start
|
|
12
|
-
* @param {Node|Coordinates} end
|
|
13
|
-
* @param {object} _options
|
|
14
|
-
*/
|
|
15
|
-
getShortestPath(start, end, _options) {
|
|
16
|
-
|
|
17
|
-
const options = Object.assign({}, DEFAULT_OPTIONS, _options);
|
|
18
|
-
|
|
19
|
-
return super.getShortestPath(
|
|
20
|
-
start, end,
|
|
21
|
-
options.useStairs ? null : OsmRouter.edgeSelectionFilter,
|
|
22
|
-
OsmRouter.edgeWeightFn,
|
|
23
|
-
OsmRouter.acceptOneWayFn
|
|
24
|
-
);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @param {Edge} edge
|
|
29
|
-
* @returns {boolean}
|
|
30
|
-
*/
|
|
31
|
-
static edgeSelectionFilter = edge => {
|
|
32
|
-
return !edge.data || !edge.data.tags
|
|
33
|
-
|| (
|
|
34
|
-
edge.data.tags.stairs !== 'yes'
|
|
35
|
-
&& edge.data.tags.highway !== 'steps'
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @param {Edge} edge
|
|
41
|
-
* @returns {boolean}
|
|
42
|
-
*/
|
|
43
|
-
static edgeWeightFn = edge => {
|
|
44
|
-
if (edge.data.tags.highway === 'elevator') {
|
|
45
|
-
return 30;
|
|
46
|
-
}
|
|
47
|
-
return Utils.getDurationFromLength(edge.length);
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* @param {Edge} edge
|
|
52
|
-
* @param {boolean} reversed
|
|
53
|
-
* @returns {boolean}
|
|
54
|
-
*/
|
|
55
|
-
static acceptOneWayFn = (edge, reversed) => {
|
|
56
|
-
const {
|
|
57
|
-
oneway, highway, conveying
|
|
58
|
-
} = edge.data.tags;
|
|
59
|
-
if (reversed && (oneway === 'yes' || oneway === 'true' || oneway === '1')) {
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
if (conveying && highway) {
|
|
63
|
-
if (conveying === 'forward' && reversed) {
|
|
64
|
-
return false;
|
|
65
|
-
} if (conveying === 'backward' && !reversed) {
|
|
66
|
-
return false;
|
|
67
|
-
} if (conveying === 'yes' && reversed) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return true;
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export default OsmRouter;
|