@wemap/geo 4.0.13 → 5.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.
@@ -0,0 +1,203 @@
1
+ /* eslint-disable no-new */
2
+ import chai from 'chai';
3
+
4
+ import Logger from '@wemap/logger';
5
+
6
+ import Coordinates from '../coordinates/Coordinates.js';
7
+ import Level from '../coordinates/Level.js';
8
+
9
+ import GraphNode from './GraphNode.js';
10
+ import GraphEdge from './GraphEdge.js';
11
+
12
+ Logger.enable(false);
13
+
14
+ const { expect } = chai;
15
+
16
+ describe('GraphNode', () => {
17
+
18
+ it('creation', () => {
19
+
20
+ expect(() => new GraphNode()).throw(Error);
21
+ expect(() => new GraphNode({
22
+ lat: 45,
23
+ lng: 5
24
+ })).throw(Error);
25
+ expect(() => new GraphNode(new Coordinates(0, 0))).not.throw(Error);
26
+ expect(() => new GraphNode(new Coordinates(0, 0), 'foo')).not.throw(Error);
27
+
28
+ });
29
+
30
+
31
+ const pos1 = new Coordinates(45, 5);
32
+ const pos2 = new Coordinates(46, 5);
33
+ const node1 = new GraphNode(pos1);
34
+ const node2 = new GraphNode(pos2);
35
+
36
+ it('distanceTo', () => {
37
+ expect(node1.distanceTo(node2)).equals(pos1.distanceTo(pos2));
38
+ });
39
+
40
+ it('bearingTo', () => {
41
+ expect(node1.bearingTo(node2)).equals(pos1.bearingTo(pos2));
42
+ });
43
+
44
+ it('equalsTo', () => {
45
+ expect(node1.equalsTo(node2)).false;
46
+ expect(node1.equalsTo(node1)).true;
47
+ expect(new GraphNode(pos1).equalsTo(node1)).true;
48
+ });
49
+
50
+ it('clone', () => {
51
+
52
+ const node = new GraphNode(pos1);
53
+
54
+ const nodeBis = node.clone();
55
+ expect(nodeBis.coords).equals(node.coords);
56
+ nodeBis.edges.forEach((val, idx) => expect(val).equals(node.edges[idx]));
57
+ expect(nodeBis.builtFrom).equals(node.builtFrom);
58
+
59
+ });
60
+
61
+ it('toJson / fromJson', () => {
62
+
63
+ const node = new GraphNode(pos1);
64
+
65
+ const jsonNode = node.toJson();
66
+ expect(jsonNode).deep.equals([45, 5]);
67
+
68
+ const nodeBis = GraphNode.fromJson(jsonNode);
69
+ expect(nodeBis.coords.equalsTo(node.coords)).true;
70
+ });
71
+
72
+ // eslint-disable-next-line max-statements
73
+ it('generateNodesLevels', () => {
74
+
75
+ const cleanNodes = count => [...Array(count)].map((_ignore, idx) => new GraphNode(new Coordinates(0, 0), 'n' + idx));
76
+ const cleanNodesWithAdjEdges = (...levelEdges) => {
77
+ const _nodes = cleanNodes(levelEdges.length + 1);
78
+ levelEdges.forEach((level, idx) => new GraphEdge(_nodes[0], _nodes[idx + 1], level));
79
+ return _nodes;
80
+ };
81
+
82
+ let nodes;
83
+
84
+ /**
85
+ * Simple case with only adjacent nodes
86
+ */
87
+
88
+ nodes = cleanNodesWithAdjEdges(new Level(1), new Level(0));
89
+ expect(GraphNode.generateNodesLevels(nodes)).false;
90
+ expect(nodes[0].coords.level).is.null;
91
+
92
+ nodes = cleanNodesWithAdjEdges(new Level(1), new Level(1));
93
+ expect(GraphNode.generateNodesLevels(nodes)).true;
94
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
95
+
96
+ nodes = cleanNodesWithAdjEdges(new Level(1), new Level(1, 2));
97
+ expect(GraphNode.generateNodesLevels(nodes)).true;
98
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
99
+
100
+ nodes = cleanNodesWithAdjEdges(new Level(0, 1), new Level(1, 2));
101
+ expect(GraphNode.generateNodesLevels(nodes)).true;
102
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
103
+
104
+ nodes = cleanNodesWithAdjEdges(new Level(0, 1));
105
+ expect(GraphNode.generateNodesLevels(nodes)).true;
106
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(0, 1))).true;
107
+
108
+ /**
109
+ * More complex cases with no adjacent edges
110
+ */
111
+
112
+ nodes = cleanNodes(4);
113
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
114
+ new GraphEdge(nodes[1], nodes[2], new Level(1, 2), 'e1');
115
+ new GraphEdge(nodes[2], nodes[3], new Level(1, 2), 'e2');
116
+ expect(GraphNode.generateNodesLevels(nodes)).true;
117
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
118
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(1))).true;
119
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(1, 2))).true;
120
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(2))).true;
121
+
122
+
123
+ nodes = cleanNodes(5);
124
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
125
+ new GraphEdge(nodes[1], nodes[2], new Level(1, 2), 'e1');
126
+ new GraphEdge(nodes[2], nodes[3], new Level(1, 2), 'e2');
127
+ new GraphEdge(nodes[2], nodes[4], null, 'e3');
128
+ expect(GraphNode.generateNodesLevels(nodes)).true;
129
+
130
+
131
+ nodes = cleanNodes(4);
132
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
133
+ new GraphEdge(nodes[1], nodes[2], new Level(0, 1), 'e1');
134
+ new GraphEdge(nodes[2], nodes[3], new Level(0, 1), 'e2');
135
+ expect(GraphNode.generateNodesLevels(nodes)).true;
136
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
137
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(1))).true;
138
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(0, 1))).true;
139
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(0))).true;
140
+
141
+
142
+ nodes = cleanNodes(4);
143
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
144
+ new GraphEdge(nodes[1], nodes[2], new Level(1, 2), 'e1');
145
+ new GraphEdge(nodes[2], nodes[3], new Level(1, 2), 'e2');
146
+ new GraphEdge(nodes[1], nodes[3], new Level(1), 'e3');
147
+ expect(GraphNode.generateNodesLevels(nodes)).true;
148
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
149
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(1))).true;
150
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(2))).true;
151
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(1))).true;
152
+
153
+
154
+ nodes = cleanNodes(4);
155
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
156
+ new GraphEdge(nodes[1], nodes[2], new Level(0, 1), 'e1');
157
+ new GraphEdge(nodes[2], nodes[3], new Level(0, 1), 'e2');
158
+ new GraphEdge(nodes[1], nodes[3], new Level(1), 'e3');
159
+ expect(GraphNode.generateNodesLevels(nodes)).true;
160
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(1))).true;
161
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(1))).true;
162
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(0))).true;
163
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(1))).true;
164
+
165
+
166
+ nodes = cleanNodes(6);
167
+ new GraphEdge(nodes[0], nodes[1], new Level(1), 'e0');
168
+ new GraphEdge(nodes[1], nodes[2], new Level(1, 2), 'e1');
169
+ new GraphEdge(nodes[2], nodes[3], new Level(1, 2), 'e2');
170
+ new GraphEdge(nodes[2], nodes[4], new Level(1, 2), 'e3');
171
+ new GraphEdge(nodes[4], nodes[5], new Level(2), 'e4');
172
+ expect(GraphNode.generateNodesLevels(nodes)).false;
173
+
174
+
175
+ nodes = cleanNodes(5);
176
+ new GraphEdge(nodes[0], nodes[1], new Level(1, 2));
177
+ new GraphEdge(nodes[1], nodes[2], new Level(1, 2));
178
+ new GraphEdge(nodes[2], nodes[3], new Level(1, 2));
179
+ new GraphEdge(nodes[3], nodes[4], new Level(1));
180
+ expect(GraphNode.generateNodesLevels(nodes)).true;
181
+ expect(Level.equalsTo(nodes[0].coords.level, new Level(2))).true;
182
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(1, 2))).true;
183
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(1, 2))).true;
184
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(1))).true;
185
+ expect(Level.equalsTo(nodes[4].coords.level, new Level(1))).true;
186
+
187
+
188
+ nodes = cleanNodes(6);
189
+ new GraphEdge(nodes[0], nodes[1], new Level(0), 'e0');
190
+ new GraphEdge(nodes[1], nodes[2], new Level(0, 1), 'e1');
191
+ new GraphEdge(nodes[2], nodes[3], new Level(0, 1), 'e2');
192
+ new GraphEdge(nodes[3], nodes[4], new Level(0, 1), 'e3');
193
+ new GraphEdge(nodes[4], nodes[5], new Level(1), 'e4');
194
+ expect(GraphNode.generateNodesLevels(nodes)).true;
195
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(0))).true;
196
+ expect(Level.equalsTo(nodes[1].coords.level, new Level(0))).true;
197
+ expect(Level.equalsTo(nodes[2].coords.level, new Level(0, 1))).true;
198
+ expect(Level.equalsTo(nodes[3].coords.level, new Level(0, 1))).true;
199
+ expect(Level.equalsTo(nodes[4].coords.level, new Level(1))).true;
200
+ expect(Level.equalsTo(nodes[5].coords.level, new Level(1))).true;
201
+ });
202
+
203
+ });
@@ -1,8 +1,8 @@
1
1
  import Coordinates from '../coordinates/Coordinates.js';
2
- import Edge from './Edge.js';
3
- import Node from './Node.js';
2
+ import Edge from './GraphEdge.js';
3
+ import Node from './GraphNode.js';
4
4
 
5
- class Projection {
5
+ class GraphProjection {
6
6
 
7
7
  /** @type {Coordinates} */
8
8
  origin;
@@ -18,4 +18,4 @@ class Projection {
18
18
 
19
19
  }
20
20
 
21
- export default Projection;
21
+ export default GraphProjection;
@@ -0,0 +1,17 @@
1
+
2
+ import GraphEdge from './GraphEdge.js';
3
+ import GraphNode from './GraphNode.js';
4
+
5
+ /**
6
+ * @template T
7
+ * @param {GraphEdge<T>[]} edges
8
+ * @param {GraphNode<T>} node1
9
+ * @param {GraphNode<T>} node2
10
+ * @returns {?GraphEdge<T>}
11
+ */
12
+ export function getEdgeByNodes(edges, node1, node2) {
13
+ return edges.find(edge =>
14
+ node1 === edge.node1 && node2 === edge.node2
15
+ || node2 === edge.node1 && node1 === edge.node2
16
+ );
17
+ }
@@ -4,10 +4,11 @@ import { diffAngleLines } from '@wemap/maths';
4
4
 
5
5
  import Constants from '../Constants.js';
6
6
  import Coordinates from '../coordinates/Coordinates.js';
7
+ import UserPosition from '../coordinates/UserPosition.js';
7
8
  import Level from '../coordinates/Level.js';
8
9
 
9
10
  import Network from './Network.js';
10
- import Projection from './Projection.js';
11
+ import GraphProjection from './GraphProjection.js';
11
12
 
12
13
  class MapMatching {
13
14
 
@@ -146,7 +147,7 @@ class MapMatching {
146
147
  * @param {boolean} useBearing
147
148
  * @param {boolean} useMultiLevelSegments
148
149
  * @param {function} acceptEdgeFn
149
- * @returns {Projection}
150
+ * @returns {GraphProjection}
150
151
  */
151
152
  getProjection(location, useDistance = false, useBearing = false,
152
153
  useMultiLevelSegments = true, acceptEdgeFn = () => true) {
@@ -163,7 +164,7 @@ class MapMatching {
163
164
  return null;
164
165
  }
165
166
 
166
- const projection = new Projection();
167
+ const projection = new GraphProjection();
167
168
  projection.origin = location;
168
169
  projection.distanceFromNearestElement = Number.MAX_VALUE;
169
170
  projection.projection = location.clone();
@@ -231,8 +232,9 @@ class MapMatching {
231
232
  return null;
232
233
  }
233
234
 
234
- projection.projection.accuracy += projection.distanceFromNearestElement;
235
-
235
+ if (projection.projection instanceof UserPosition) {
236
+ projection.projection.accuracy += projection.distanceFromNearestElement;
237
+ }
236
238
  return projection;
237
239
  }
238
240
 
@@ -8,10 +8,10 @@ import Coordinates from '../coordinates/Coordinates.js';
8
8
  import Level from '../coordinates/Level.js';
9
9
  import UserPosition from '../coordinates/UserPosition.js';
10
10
 
11
- import Edge from './Edge.js';
11
+ import GraphEdge from './GraphEdge.js';
12
+ import GraphNode from './GraphNode.js';
12
13
  import MapMatching from './MapMatching.js';
13
14
  import Network from './Network.js';
14
- import Node from './Node.js';
15
15
 
16
16
  import { network } from '../../tests/CommonTest.js';
17
17
 
@@ -20,14 +20,14 @@ const { expect } = chai;
20
20
  describe('MapMatching', () => {
21
21
 
22
22
  const nodes = [
23
- new Node(new Coordinates(43.6091194, 3.884099), 'p0'),
24
- new Node(new Coordinates(43.6093629, 3.8842777), 'p1'),
25
- new Node(new Coordinates(43.6092785, 3.8845052), 'p2')
23
+ new GraphNode(new Coordinates(43.6091194, 3.884099), 'p0'),
24
+ new GraphNode(new Coordinates(43.6093629, 3.8842777), 'p1'),
25
+ new GraphNode(new Coordinates(43.6092785, 3.8845052), 'p2')
26
26
  ];
27
27
 
28
28
  const edges = [
29
- new Edge(nodes[0], nodes[1], null, 'e0'),
30
- new Edge(nodes[1], nodes[2], null, 'e1')
29
+ new GraphEdge(nodes[0], nodes[1], null, 'e0'),
30
+ new GraphEdge(nodes[1], nodes[2], null, 'e1')
31
31
  ];
32
32
 
33
33
  let mapMatching;
@@ -70,17 +70,17 @@ describe('MapMatching', () => {
70
70
 
71
71
  result = mapMatching.getProjection(location);
72
72
  expect(result).is.not.null;
73
- expect(result.nearestElement).instanceOf(Edge);
74
- expect(result.nearestElement.name).equal('e0');
73
+ expect(result.nearestElement).instanceOf(GraphEdge);
74
+ expect(result.nearestElement.builtFrom).equal('e0');
75
75
  expect(result.projection.distanceTo(expected)).to.below(Constants.EPS_MM);
76
76
  expect(Level.equalsTo(expected.level, result.projection.level)).true;
77
77
 
78
78
  const owNodes = [
79
- new Node(new Coordinates(43.6091194, 3.884099, 5)),
80
- new Node(new Coordinates(43.6093629, 3.8842777, 10))
79
+ new GraphNode(new Coordinates(43.6091194, 3.884099, 5)),
80
+ new GraphNode(new Coordinates(43.6093629, 3.8842777, 10))
81
81
  ];
82
82
  const owNetwork = new Network(owNodes, [
83
- new Edge(owNodes[0], owNodes[1])
83
+ new GraphEdge(owNodes[0], owNodes[1])
84
84
  ]);
85
85
  const owMapMatching = new MapMatching(owNetwork);
86
86
  result = owMapMatching.getProjection(new Coordinates(43.6092086, 3.8842598, 10));
@@ -95,8 +95,8 @@ describe('MapMatching', () => {
95
95
  location.bearing = deg2rad(101.9);
96
96
  result = mapMatching.getProjection(location, true, true);
97
97
  expect(result).is.not.null;
98
- expect(result.nearestElement).instanceOf(Edge);
99
- expect(result.nearestElement.name).equal('e1');
98
+ expect(result.nearestElement).instanceOf(GraphEdge);
99
+ expect(result.nearestElement.builtFrom).equal('e1');
100
100
  expect(result.projection.distanceTo(expected)).to.below(Constants.EPS_MM);
101
101
  expect(Level.equalsTo(expected.level, result.projection.level)).true;
102
102
  });
@@ -107,24 +107,24 @@ describe('MapMatching', () => {
107
107
 
108
108
  pointToTest = nodes[0].coords.destinationPoint(0.0001, nodes[0].bearingTo(nodes[1]));
109
109
  result = mapMatching.getProjection(pointToTest);
110
- expect(result.nearestElement).instanceOf(Node);
111
- expect(result.nearestElement.name).equal('p0');
110
+ expect(result.nearestElement).instanceOf(GraphNode);
111
+ expect(result.nearestElement.builtFrom).equal('p0');
112
112
 
113
113
  pointToTest = nodes[1].coords.destinationPoint(0.0001, nodes[1].bearingTo(nodes[0]));
114
114
  result = mapMatching.getProjection(pointToTest);
115
- expect(result.nearestElement).instanceOf(Node);
116
- expect(result.nearestElement.name).equal('p1');
115
+ expect(result.nearestElement).instanceOf(GraphNode);
116
+ expect(result.nearestElement.builtFrom).equal('p1');
117
117
 
118
118
  pointToTest = nodes[0].coords.destinationPoint(0.005, nodes[0].bearingTo(nodes[1]));
119
119
  result = mapMatching.getProjection(pointToTest);
120
- expect(result.nearestElement).instanceOf(Edge);
121
- expect(result.nearestElement.name).equal('e0');
120
+ expect(result.nearestElement).instanceOf(GraphEdge);
121
+ expect(result.nearestElement.builtFrom).equal('e0');
122
122
  expect(result.projection.distanceTo(pointToTest)).to.below(Constants.EPS_MM);
123
123
 
124
124
  pointToTest = nodes[1].coords.destinationPoint(0.005, nodes[1].bearingTo(nodes[0]));
125
125
  result = mapMatching.getProjection(pointToTest);
126
- expect(result.nearestElement).instanceOf(Edge);
127
- expect(result.nearestElement.name).equal('e0');
126
+ expect(result.nearestElement).instanceOf(GraphEdge);
127
+ expect(result.nearestElement.builtFrom).equal('e0');
128
128
  expect(result.projection.distanceTo(pointToTest)).to.below(Constants.EPS_MM);
129
129
 
130
130
  });
@@ -243,12 +243,12 @@ describe('MapMatching - multilevels', () => {
243
243
  currentPosition = new Coordinates(43.6093381, 3.8841926, null, new Level(1));
244
244
  projection = mapMatching.getProjection(currentPosition, true, false, false);
245
245
  expect(projection).is.not.null;
246
- expect(projection.nearestElement.name).equals('p14');
246
+ expect(projection.nearestElement.builtFrom).equals('p14');
247
247
 
248
248
  currentPosition = new Coordinates(43.6093381, 3.8841926, null, new Level(2));
249
249
  projection = mapMatching.getProjection(currentPosition, true, false, false);
250
250
  expect(projection).is.not.null;
251
- expect(projection.nearestElement.name).equals('p11');
251
+ expect(projection.nearestElement.builtFrom).equals('p11');
252
252
 
253
253
 
254
254
  // On Segments
@@ -260,12 +260,12 @@ describe('MapMatching - multilevels', () => {
260
260
  currentPosition = new Coordinates(43.6093258, 3.8842272, null, new Level(1));
261
261
  projection = mapMatching.getProjection(currentPosition, true, false, false);
262
262
  expect(projection).is.not.null;
263
- expect(projection.nearestElement.name).equals('e14');
263
+ expect(projection.nearestElement.builtFrom).equals('e14');
264
264
 
265
265
  currentPosition = new Coordinates(43.6093258, 3.8842272, null, new Level(2));
266
266
  projection = mapMatching.getProjection(currentPosition, true, false, false);
267
267
  expect(projection).is.not.null;
268
- expect(projection.nearestElement.name).equals('e10');
268
+ expect(projection.nearestElement.builtFrom).equals('e10');
269
269
 
270
270
  });
271
271
 
@@ -1,23 +1,28 @@
1
1
  import BoundingBox from '../coordinates/BoundingBox.js';
2
2
  import Coordinates from '../coordinates/Coordinates.js';
3
+ import Level from '../coordinates/Level.js';
3
4
 
4
- import Edge from './Edge.js';
5
- import Node from './Node.js';
5
+ import GraphEdge from './GraphEdge.js';
6
+ import GraphNode from './GraphNode.js';
7
+ import { getEdgeByNodes } from './GraphUtils.js';
6
8
 
7
9
  /**
10
+ * @template T
11
+ *
8
12
  * A typical network with nodes (Node) and edges (Edge)
9
13
  */
10
14
  class Network {
11
15
 
12
- /** @type {Node[]} */
16
+ /** @type {GraphNode<T>[]} */
13
17
  nodes;
14
18
 
15
- /** @type {Edge[]} */
19
+ /** @type {GraphEdge<T>[]} */
16
20
  edges;
17
21
 
18
22
  /**
19
- * @param {Node[]} nodes
20
- * @param {Edge[]} edges
23
+ * @template T
24
+ * @param {GraphNode<T>[]} nodes
25
+ * @param {GraphEdge<T>[]} edges
21
26
  */
22
27
  constructor(nodes, edges) {
23
28
  this.nodes = Array.isArray(nodes) ? nodes : [];
@@ -25,50 +30,24 @@ class Network {
25
30
  }
26
31
 
27
32
  /**
33
+ * @template T
28
34
  * @param {Coordinates} coords
29
- * @returns {?Node}
35
+ * @returns {?GraphNode<T>}
30
36
  */
31
37
  getNodeByCoords(coords) {
32
38
  return this.nodes.find(node => node.coords.equalsTo(coords));
33
39
  }
34
40
 
35
41
  /**
36
- * @param {string} name
37
- * @returns {?Node}
38
- */
39
- getNodeByName(name) {
40
- return this.nodes.find(node => node.name === name);
41
- }
42
-
43
- /**
44
- * @param {Node} node1
45
- * @param {Node} node2
46
- * @returns {?Edge}
42
+ * @template T
43
+ * @param {GraphNode<T>} node1
44
+ * @param {GraphNode<T>} node2
45
+ * @returns {?GraphEdge<T>}
47
46
  */
48
47
  getEdgeByNodes(node1, node2) {
49
- return Network.getEdgeByNodes(this.edges, node1, node2);
50
- }
51
-
52
- /**
53
- * @param {string} name
54
- * @returns {?Edge}
55
- */
56
- getEdgeByName(name) {
57
- return this.edges.find(edge => edge.name === name);
48
+ return getEdgeByNodes(this.edges, node1, node2);
58
49
  }
59
50
 
60
- /**
61
- * @param {Edge[]} edges
62
- * @param {Node} node1
63
- * @param {Node} node2
64
- * @returns {?Edge}
65
- */
66
- static getEdgeByNodes(edges, node1, node2) {
67
- return edges.find(edge =>
68
- node1 === edge.node1 && node2 === edge.node2
69
- || node2 === edge.node1 && node1 === edge.node2
70
- );
71
- }
72
51
 
73
52
  /**
74
53
  * @param {?number} extendedMeasure
@@ -93,12 +72,12 @@ class Network {
93
72
 
94
73
  let nodeToStringFn = _nodeToStringFn;
95
74
  if (!nodeToStringFn) {
96
- nodeToStringFn = node => `${node.name}`;
75
+ nodeToStringFn = node => `${node.builtFrom}`;
97
76
  }
98
77
 
99
78
  let edgeToStringFn = _edgeToStringFn;
100
79
  if (!_edgeToStringFn) {
101
- edgeToStringFn = edge => `${edge.name}`;
80
+ edgeToStringFn = edge => `${edge.builtFrom}`;
102
81
  }
103
82
 
104
83
  let output
@@ -131,9 +110,14 @@ class Network {
131
110
  this.nodes.indexOf(edge.node1),
132
111
  this.nodes.indexOf(edge.node2)
133
112
  ];
134
- const properties = edge.extractProperties();
135
- if (Object.keys(properties).length > 0) {
136
- output.push(properties);
113
+ if (edge.level !== null) {
114
+ output.push(edge.level.toString());
115
+ }
116
+ if (edge.isOneway) {
117
+ if (edge.level === null) {
118
+ output.push(null);
119
+ }
120
+ output.push(true);
137
121
  }
138
122
  return output;
139
123
  })
@@ -148,21 +132,74 @@ class Network {
148
132
 
149
133
  const network = new Network();
150
134
 
151
- network.nodes = json.nodes.map(Node.fromJson);
135
+ network.nodes = json.nodes.map(GraphNode.fromJson);
152
136
 
153
137
  network.edges = json.edges.map(jsonEdge => {
154
- const edge = new Edge(
138
+ const edge = new GraphEdge(
155
139
  network.nodes[jsonEdge[0]],
156
140
  network.nodes[jsonEdge[1]]
157
141
  );
158
- if (jsonEdge.length > 2) {
159
- edge.applyProperties(jsonEdge[2]);
142
+ if (jsonEdge.length > 2 && jsonEdge[2] !== null) {
143
+ edge.level = Level.fromString(jsonEdge[2]);
144
+ }
145
+ if (jsonEdge.length > 3 && jsonEdge[3]) {
146
+ edge.isOneway = true;
160
147
  }
161
148
  return edge;
162
149
  });
163
150
 
164
151
  return network;
165
152
  }
153
+
154
+
155
+ /**
156
+ * Convert Array of Coordinates array to a network
157
+ * @param {Coordinates[][]} segments
158
+ * @returns {Network}
159
+ */
160
+ static fromCoordinates(segments) {
161
+
162
+ const network = new Network();
163
+
164
+ const getOrCreateNode = coords =>
165
+ network.nodes.find(_coords => _coords.equalsTo(coords)) || new GraphNode(coords);
166
+
167
+ const createEdgeFromCoords = (coords1, coords2) =>
168
+ new GraphEdge(coords1, coords2, Level.union(coords1.level, coords2.level));
169
+
170
+ for (const segment of segments) {
171
+
172
+ let previousNode = null;
173
+ for (const coords of segment) {
174
+ const currentNode = getOrCreateNode(coords);
175
+
176
+ if (previousNode) {
177
+ const edge = createEdgeFromCoords(currentNode, previousNode);
178
+ network.edges.push(edge);
179
+ }
180
+
181
+ network.nodes.push(currentNode);
182
+ previousNode = currentNode;
183
+ }
184
+ }
185
+
186
+ return network;
187
+ }
188
+
189
+ /**
190
+ * Create edges From MultiLevel Itinerary for a given level
191
+ * @param {Level} targetLevel level for selection.
192
+ * @param {Boolean} useMultiLevelEdges use segments which intersect both levels (stairs, elevators...)
193
+ * @returns {GraphEdge[]} Ordered edges
194
+ */
195
+ getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
196
+ return this.edges.filter(
197
+ ({ level }) => useMultiLevelEdges
198
+ ? Level.intersect(targetLevel, level) !== null
199
+ : Level.contains(targetLevel, level)
200
+ );
201
+ }
202
+
166
203
  }
167
204
 
168
205
  export default Network;