@wemap/osm 2.7.6 → 2.7.7

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.
@@ -0,0 +1,103 @@
1
+ /* eslint-disable max-statements */
2
+ import { expect } from 'chai';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+
6
+ import OsmParser from '../model/OsmParser';
7
+ import OsmNetwork from './OsmNetwork';
8
+
9
+
10
+ const loadFile = fileName => {
11
+ const filePath = path.resolve(__dirname, '../../assets/' + fileName);
12
+ return fs.readFileSync(filePath, 'utf8');
13
+ };
14
+
15
+ describe('OsmNetwork - simple', () => {
16
+
17
+ let osmModel, osmNetwork;
18
+ const osmXmlString = loadFile('network-simple.osm');
19
+
20
+ it('Network creation', () => {
21
+
22
+ osmModel = OsmParser.parseOsmXmlString(osmXmlString);
23
+ osmNetwork = OsmNetwork.fromOsmModel(osmModel);
24
+
25
+ expect(osmNetwork.nodes.length).equals(3);
26
+ expect(osmNetwork.edges.length).equals(2);
27
+ });
28
+
29
+
30
+ it('Network creation - waySelectionFilter', () => {
31
+
32
+ const selectionNetwork = OsmNetwork.fromOsmModel(osmModel, () => true);
33
+
34
+ expect(selectionNetwork.nodes.length).equals(4);
35
+ expect(selectionNetwork.edges.length).equals(3);
36
+ });
37
+
38
+ it('Network creation - elevator', () => {
39
+
40
+ const elevatorModel = OsmParser.parseOsmXmlString(loadFile('network-elevator.osm'));
41
+ const elevatorNetwork = OsmNetwork.fromOsmModel(elevatorModel);
42
+
43
+ expect(elevatorNetwork.nodes.length).equals(7);
44
+ expect(elevatorNetwork.edges.length).equals(6);
45
+
46
+
47
+ const osmModel2 = OsmParser.parseOsmXmlString(`
48
+ <osm>
49
+ <node id='1' lat='43' lon='4'>
50
+ <tag k='highway' v='elevator' />
51
+ <tag k='level' v='0;1' />
52
+ </node>
53
+ <node id='2' lat='43' lon='3' />
54
+ <way id='3'>
55
+ <nd ref='1' />
56
+ <nd ref='2' />
57
+ <tag k='highway' v='footway' />
58
+ <tag k='level' v='0;1' />
59
+ </way>
60
+ </osm>
61
+ `);
62
+ expect(() => OsmNetwork.fromOsmModel(osmModel2)).throw(Error);
63
+ });
64
+
65
+
66
+ it('getNodeById', () => {
67
+ let node = osmNetwork.getNodeById(1);
68
+ expect(node).not.null;
69
+ expect(node.data.tags.name).equals('p1');
70
+
71
+ node = osmNetwork.getNodeById(5);
72
+ expect(node).undefined;
73
+ });
74
+
75
+
76
+ it('getNodeByName', () => {
77
+ let node = osmNetwork.getNodeByName('p1');
78
+ expect(node).not.undefined;
79
+
80
+ node = osmNetwork.getNodeByName('p5');
81
+ expect(node).undefined;
82
+ });
83
+
84
+ it('getEdgesById', () => {
85
+ let edges = osmNetwork.getEdgesById(101);
86
+ expect(edges.length).equals(2);
87
+ expect(edges[0].data.tags.name).equals('w1');
88
+ expect(edges[0].node1.data.tags.name).equals('p1');
89
+ expect(edges[0].node2.data.tags.name).equals('p2');
90
+ expect(edges[1].data.tags.name).equals('w1');
91
+ expect(edges[1].node1.data.tags.name).equals('p2');
92
+ expect(edges[1].node2.data.tags.name).equals('p3');
93
+
94
+ edges = osmNetwork.getEdgesById(3);
95
+ expect(edges.length).equals(0);
96
+ });
97
+
98
+ it('toDetailedString', () => {
99
+ expect(() => osmNetwork.toDetailedString()).not.throw(Error);
100
+ });
101
+ });
102
+
103
+
@@ -20,28 +20,26 @@ class OsmRouter extends GraphRouter {
20
20
  };
21
21
 
22
22
  const edgeWeightFn = edge => {
23
- if (edge.data && edge.data.tags && edge.data.tags.highway === 'elevator') {
23
+ if (edge.data.tags.highway === 'elevator') {
24
24
  return 30;
25
25
  }
26
26
  return Utils.getDurationFromLength(edge.length);
27
27
  };
28
28
 
29
29
  const acceptOneWayFn = (edge, reversed) => {
30
- if (edge.data && edge.data.tags) {
31
- const {
32
- oneway, highway, conveying
33
- } = edge.data.tags;
34
- if (reversed && (oneway === 'yes' || oneway === 'true' || oneway === '1')) {
30
+ const {
31
+ oneway, highway, conveying
32
+ } = edge.data.tags;
33
+ if (reversed && (oneway === 'yes' || oneway === 'true' || oneway === '1')) {
34
+ return false;
35
+ }
36
+ if (conveying && highway) {
37
+ if (conveying === 'forward' && reversed) {
38
+ return false;
39
+ } if (conveying === 'backward' && !reversed) {
40
+ return false;
41
+ } if (conveying === 'yes' && reversed) {
35
42
  return false;
36
- }
37
- if (conveying && highway) {
38
- if (conveying === 'forward' && reversed) {
39
- return false;
40
- } if (conveying === 'backward' && !reversed) {
41
- return false;
42
- } if (conveying === 'yes' && reversed) {
43
- return false;
44
- }
45
43
  }
46
44
  }
47
45
  return true;
@@ -12,9 +12,16 @@ import OsmParser from '../model/OsmParser';
12
12
  import OsmRouter from './OsmRouter';
13
13
  import OsmNetwork from './OsmNetwork';
14
14
 
15
- import {
16
- itineraryStart, itineraryEnd
17
- } from '../../../graph/tests/CommonTest';
15
+ const itineraryStart = new WGS84(43.6092754, 3.8842306, null, new Level(2));
16
+ const itineraryEnd = new WGS84(43.6092602, 3.8842669, null, new Level(1));
17
+
18
+
19
+ const loadNetwork = fileName => {
20
+ const filePath = path.resolve(__dirname, '../../assets/' + fileName);
21
+ const osmXmlString = fs.readFileSync(filePath, 'utf8');
22
+ const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
23
+ return OsmNetwork.fromOsmModel(osmModel);
24
+ };
18
25
 
19
26
  const verifyNodesOrder = (nodes, names) => {
20
27
  expect(nodes.length).equals(names.length);
@@ -32,14 +39,9 @@ const generateNodeNames = (start, end) =>
32
39
 
33
40
  describe('OsmRouter - Multi-level itinerary', () => {
34
41
 
35
- const filePath = path.resolve(__dirname, '../../assets/bureaux-wemap-montpellier-network.osm');
36
- const osmXmlString = fs.readFileSync(filePath, 'utf8');
37
-
38
- const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
39
- const networkModel = OsmNetwork.fromOsmModel(osmModel);
42
+ const networkModel = loadNetwork('bureaux-wemap-montpellier-network.osm');
40
43
  const router = new OsmRouter(networkModel);
41
44
 
42
-
43
45
  const itinerary = router.getShortestPath(itineraryStart, itineraryEnd);
44
46
 
45
47
  const p = [];
@@ -93,11 +95,7 @@ describe('OsmRouter - Multi-level itinerary', () => {
93
95
 
94
96
  describe('OsmRouter - One Way itinerary', () => {
95
97
 
96
- const filePath = path.resolve(__dirname, '../../assets/one-way.osm');
97
- const osmXmlString = fs.readFileSync(filePath, 'utf8');
98
-
99
- const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
100
- const networkModel = OsmNetwork.fromOsmModel(osmModel);
98
+ const networkModel = loadNetwork('one-way.osm');
101
99
  const router = new OsmRouter(networkModel);
102
100
 
103
101
  it('do not use oneway', () => {
@@ -118,11 +116,7 @@ describe('OsmRouter - One Way itinerary', () => {
118
116
 
119
117
  describe('OsmRouter - Conveying', () => {
120
118
 
121
- const filePath = path.resolve(__dirname, '../../assets/gare-de-lyon-extract.osm');
122
- const osmXmlString = fs.readFileSync(filePath, 'utf8');
123
-
124
- const osmModel = OsmParser.parseOsmXmlString(osmXmlString);
125
- const networkModel = OsmNetwork.fromOsmModel(osmModel);
119
+ const networkModel = loadNetwork('gare-de-lyon-extract.osm');
126
120
  const router = new OsmRouter(networkModel);
127
121
 
128
122
  it('do not use oneway conveying', () => {
@@ -141,3 +135,24 @@ describe('OsmRouter - Conveying', () => {
141
135
  });
142
136
 
143
137
 
138
+ describe('OsmRouter - Conveying - backward', () => {
139
+
140
+ const networkModel = loadNetwork('network-conveying-backward.osm');
141
+ const router = new OsmRouter(networkModel);
142
+
143
+ it('do not use oneway conveying', () => {
144
+
145
+ const start = networkModel.getNodeByName('p6');
146
+ const end = networkModel.getNodeByName('p13');
147
+
148
+ const itinerary = router.getShortestPath(start, end);
149
+ expect(itinerary).is.not.undefined;
150
+ verifyNodesOrder(itinerary.nodes, ['p6', 'p7', 'p10', 'p11', 'p12', 'p13']);
151
+
152
+ const itineraryOtherWay = router.getShortestPath(end, start);
153
+ expect(itineraryOtherWay).is.not.undefined;
154
+ verifyNodesOrder(itineraryOtherWay.nodes, ['p13', 'p12', 'p9', 'p8', 'p6']);
155
+ });
156
+ });
157
+
158
+
@@ -8,31 +8,10 @@ import {
8
8
  import {
9
9
  rad2deg, Utils as MathUtils, diffAngle, deg2rad
10
10
  } from '@wemap/maths';
11
- import Logger from '@wemap/logger';
12
11
 
13
12
 
14
13
  class OsrmUtils {
15
14
 
16
- static wgs84ToJson(wgs84) {
17
- const output = [wgs84.lng, wgs84.lat];
18
- if (wgs84.level) {
19
- output.push(wgs84.level.toString());
20
- }
21
- return output;
22
- }
23
-
24
- static jsonToWgs84(json) {
25
- const output = new WGS84(json[1], json[0]);
26
- if (json.length > 2) {
27
- output.level = Level.fromString(json[2]);
28
- }
29
- return output;
30
- }
31
-
32
- static nodesToJsonCoords(nodes) {
33
- return nodes.map(node => OsrmUtils.wgs84ToJson(node.coords));
34
- }
35
-
36
15
  static itineraryToOsrmJson(itinerary) {
37
16
 
38
17
  const itinerarySteps = itinerary.steps;
@@ -117,42 +96,6 @@ class OsrmUtils {
117
96
  };
118
97
  }
119
98
 
120
- static noRouteFoundJson(message) {
121
- return {
122
- 'code': 'NoRoute',
123
- message
124
- };
125
- }
126
-
127
-
128
- static getModifierFromAngle(_angle) {
129
-
130
- const angle = MathUtils.positiveMod(rad2deg(_angle), 360);
131
-
132
- if (angle > 0 && angle < 60) {
133
- return 'sharp right';
134
- }
135
- if (angle >= 60 && angle < 140) {
136
- return 'right';
137
- }
138
- if (angle >= 140 && angle < 160) {
139
- return 'slight right';
140
- }
141
- if (angle >= 160 && angle <= 200) {
142
- return 'straight';
143
- }
144
- if (angle > 200 && angle <= 220) {
145
- return 'slight left';
146
- }
147
- if (angle > 220 && angle <= 300) {
148
- return 'left';
149
- }
150
- if (angle > 300 && angle < 360) {
151
- return 'sharp left';
152
- }
153
- return 'u turn';
154
- }
155
-
156
99
  /**
157
100
  * Generate Itinerary from OSRM JSON, start and end.
158
101
  * @param {Object} json JSON file provided by OSRM.
@@ -168,7 +111,6 @@ class OsrmUtils {
168
111
  const {
169
112
  legs, geometry
170
113
  } = json.routes[0];
171
- const { steps } = legs[0];
172
114
 
173
115
  /**
174
116
  * Create nodes and edges from geometry
@@ -188,7 +130,8 @@ class OsrmUtils {
188
130
  previousNode = node;
189
131
  }
190
132
 
191
- if (steps && steps.length > 0) {
133
+ if (legs && legs[0]) {
134
+ const { steps } = legs[0];
192
135
  OsrmUtils.parseSteps(itinerary, steps);
193
136
  }
194
137
 
@@ -226,8 +169,8 @@ class OsrmUtils {
226
169
  const wgs84 = OsrmUtils.jsonToWgs84(coords);
227
170
  const node = itinerary.getNodeByCoords(wgs84);
228
171
  if (!node) {
229
- Logger.error('Cannot parse this itinerary coordinates');
230
- return;
172
+ throw new Error('Cannot parse these step coordinates, '
173
+ + 'they are not found in main itinerary: ' + wgs84.toString());
231
174
  }
232
175
  step.nodes.push(node);
233
176
 
@@ -282,6 +225,63 @@ class OsrmUtils {
282
225
  itinerary._steps.push(step);
283
226
  }
284
227
  }
228
+
229
+ static getModifierFromAngle(_angle) {
230
+
231
+ const angle = MathUtils.positiveMod(rad2deg(_angle), 360);
232
+
233
+ if (angle > 0 && angle < 60) {
234
+ return 'sharp right';
235
+ }
236
+ if (angle >= 60 && angle < 140) {
237
+ return 'right';
238
+ }
239
+ if (angle >= 140 && angle < 160) {
240
+ return 'slight right';
241
+ }
242
+ if (angle >= 160 && angle <= 200) {
243
+ return 'straight';
244
+ }
245
+ if (angle > 200 && angle <= 220) {
246
+ return 'slight left';
247
+ }
248
+ if (angle > 220 && angle <= 300) {
249
+ return 'left';
250
+ }
251
+ if (angle > 300 && angle < 360) {
252
+ return 'sharp left';
253
+ }
254
+ return 'u turn';
255
+ }
256
+
257
+ static wgs84ToJson(wgs84) {
258
+ const output = [wgs84.lng, wgs84.lat];
259
+ if (wgs84.level) {
260
+ output.push(wgs84.level.toString());
261
+ }
262
+ return output;
263
+ }
264
+
265
+ static jsonToWgs84(json) {
266
+ const output = new WGS84(json[1], json[0]);
267
+ if (json.length > 2) {
268
+ output.level = Level.fromString(json[2]);
269
+ }
270
+ return output;
271
+ }
272
+
273
+ static nodesToJsonCoords(nodes) {
274
+ return nodes.map(node => OsrmUtils.wgs84ToJson(node.coords));
275
+ }
276
+
277
+
278
+ static noRouteFoundJson(message) {
279
+ return {
280
+ 'code': 'NoRoute',
281
+ message
282
+ };
283
+ }
284
+
285
285
  }
286
286
 
287
287
  export default OsrmUtils;