@wemap/geo 9.0.1 → 9.0.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-geo.es.js +3271 -0
- package/dist/wemap-geo.es.js.map +1 -0
- package/package.json +2 -2
- package/src/coordinates/Coordinates.js +1 -1
- package/src/coordinates/Level.js +21 -1
- package/src/coordinates/Level.spec.js +46 -22
- package/src/graph/GraphNode.js +9 -9
- package/src/graph/MapMatching.js +49 -33
- package/src/graph/MapMatching.spec.js +125 -20
- package/src/graph/Network.js +1 -1
- package/tests/CommonTest.js +35 -24
package/src/graph/GraphNode.js
CHANGED
|
@@ -97,7 +97,7 @@ class GraphNode {
|
|
|
97
97
|
return new GraphNode(Coordinates.fromCompressedJson(json));
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
_generateLevelFromEdges() {
|
|
101
101
|
let tmpLevel = null;
|
|
102
102
|
for (let i = 0; i < this.edges.length; i++) {
|
|
103
103
|
const edge = this.edges[i];
|
|
@@ -105,7 +105,7 @@ class GraphNode {
|
|
|
105
105
|
if (tmpLevel === null) {
|
|
106
106
|
tmpLevel = Level.clone(edge.level);
|
|
107
107
|
} else {
|
|
108
|
-
tmpLevel = Level.
|
|
108
|
+
tmpLevel = Level.intersection(tmpLevel, edge.level);
|
|
109
109
|
if (tmpLevel === null) {
|
|
110
110
|
Logger.error('Error: Something bad happend during parsing: We cannot retrieve node level from adjacent ways: ' + this.coords);
|
|
111
111
|
return false;
|
|
@@ -121,7 +121,7 @@ class GraphNode {
|
|
|
121
121
|
/**
|
|
122
122
|
* We suppose generateLevelFromEdges() was called before
|
|
123
123
|
*/
|
|
124
|
-
|
|
124
|
+
_inferNodeLevelByRecursion() {
|
|
125
125
|
const { level } = this.coords;
|
|
126
126
|
if (level === null || !Level.isRange(level)) {
|
|
127
127
|
return true;
|
|
@@ -181,7 +181,7 @@ class GraphNode {
|
|
|
181
181
|
/**
|
|
182
182
|
* We suppose generateLevelFromEdges() was called before
|
|
183
183
|
*/
|
|
184
|
-
|
|
184
|
+
_inferNodeLevelByNeighboors() {
|
|
185
185
|
const { level } = this.coords;
|
|
186
186
|
if (level === null || !Level.isRange(level)) {
|
|
187
187
|
return true;
|
|
@@ -205,7 +205,7 @@ class GraphNode {
|
|
|
205
205
|
* Set node.io to true for nodes that make the link between
|
|
206
206
|
* indoor and outdoor edges
|
|
207
207
|
*/
|
|
208
|
-
|
|
208
|
+
_checkIO() {
|
|
209
209
|
this.io = this._coords.level !== null
|
|
210
210
|
&& this.edges.some(edge => edge.level === null);
|
|
211
211
|
return true;
|
|
@@ -215,7 +215,7 @@ class GraphNode {
|
|
|
215
215
|
* @param {GraphNode[]} nodes
|
|
216
216
|
*/
|
|
217
217
|
static generateNodesLevels(nodes) {
|
|
218
|
-
const success = nodes.reduce((acc, node) => acc && node.
|
|
218
|
+
const success = nodes.reduce((acc, node) => acc && node._generateLevelFromEdges(), true);
|
|
219
219
|
if (!success) {
|
|
220
220
|
return false;
|
|
221
221
|
}
|
|
@@ -224,12 +224,12 @@ class GraphNode {
|
|
|
224
224
|
// (e.g stairs without network at one of its bounds)
|
|
225
225
|
// To infer this node level, we use inferNodeLevelByRecursion()
|
|
226
226
|
const res = nodes.reduce((acc, node) => acc
|
|
227
|
-
&& node.
|
|
228
|
-
&& node.
|
|
227
|
+
&& node._inferNodeLevelByNeighboors()
|
|
228
|
+
&& node._inferNodeLevelByRecursion()
|
|
229
229
|
, true);
|
|
230
230
|
|
|
231
231
|
// Finally define nodes that are links between indoor and outdoor
|
|
232
|
-
nodes.forEach(node => node.
|
|
232
|
+
nodes.forEach(node => node._checkIO());
|
|
233
233
|
|
|
234
234
|
return res;
|
|
235
235
|
}
|
package/src/graph/MapMatching.js
CHANGED
|
@@ -81,37 +81,29 @@ class MapMatching {
|
|
|
81
81
|
*/
|
|
82
82
|
_shouldProjectOnEdgeAndNodes(edge, location, useBearing, useMultiLevelSegments, acceptEdgeFn) {
|
|
83
83
|
|
|
84
|
+
// ignore projections if edge is not accepted
|
|
84
85
|
if (!acceptEdgeFn(edge)) {
|
|
85
|
-
// if edge selection is not verified
|
|
86
86
|
return [false, false, false];
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
let
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
// Verify if edge level only if one of both is defined
|
|
95
|
-
(location.level !== null || edge.level !== null)
|
|
96
|
-
&& (
|
|
97
|
-
// if edge level intersect location level
|
|
98
|
-
!(Level.intersect(location.level, edge.level) !== null)
|
|
99
|
-
// ignore MultiLevelSegments if option used
|
|
100
|
-
|| (!useMultiLevelSegments && Level.isRange(edge.level))
|
|
101
|
-
)) {
|
|
102
|
-
checkEdge = false;
|
|
103
|
-
}
|
|
89
|
+
// First, check if levels intersects
|
|
90
|
+
let checkEdge = Level.intersect(location.level, edge.level);
|
|
91
|
+
let checkNode1 = Level.intersect(location.level, edge.node1.coords.level);
|
|
92
|
+
let checkNode2 = Level.intersect(location.level, edge.node2.coords.level);
|
|
104
93
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
94
|
+
// Second, in case of IO nodes, accept matching if location's level is null
|
|
95
|
+
checkNode1 ||= edge.node1.io && location.level === null;
|
|
96
|
+
checkNode2 ||= edge.node2.io && location.level === null;
|
|
108
97
|
|
|
109
|
-
|
|
110
|
-
|
|
98
|
+
// Third, check if level is a range if useMultiLevelSegments is false
|
|
99
|
+
if (!useMultiLevelSegments) {
|
|
100
|
+
checkEdge &&= !Level.isRange(edge.level);
|
|
101
|
+
checkNode1 &&= !Level.isRange(edge.node1.coords.level);
|
|
102
|
+
checkNode2 &&= !Level.isRange(edge.node2.coords.level);
|
|
111
103
|
}
|
|
112
104
|
|
|
105
|
+
// Finally, check edges bearing if option is used
|
|
113
106
|
if (useBearing) {
|
|
114
|
-
// if mapmatching bearing is enabled do not use nodes matching
|
|
115
107
|
if (checkEdge) {
|
|
116
108
|
// condition for optimisation
|
|
117
109
|
const diffAngle = diffAngleLines(edge.bearing, location.bearing);
|
|
@@ -120,6 +112,7 @@ class MapMatching {
|
|
|
120
112
|
checkEdge = false;
|
|
121
113
|
}
|
|
122
114
|
}
|
|
115
|
+
// if mapmatching bearing is enabled do not use nodes matching
|
|
123
116
|
checkNode1 = false;
|
|
124
117
|
checkNode2 = false;
|
|
125
118
|
}
|
|
@@ -135,7 +128,22 @@ class MapMatching {
|
|
|
135
128
|
static _assignLatLngLevel(fromCoordinates, toCoordinates) {
|
|
136
129
|
toCoordinates.lat = fromCoordinates.lat;
|
|
137
130
|
toCoordinates.lng = fromCoordinates.lng;
|
|
138
|
-
toCoordinates.level = fromCoordinates.level;
|
|
131
|
+
toCoordinates.level = Level.clone(fromCoordinates.level);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* IO Nodes are typical because they have a non-null level but projection car works on them.
|
|
136
|
+
* This function handles the case where the projection is on an IO node and a location with
|
|
137
|
+
* a null level is required.
|
|
138
|
+
*
|
|
139
|
+
* @param {Coordinates} projection
|
|
140
|
+
* @param {Coordinates} location
|
|
141
|
+
* @param {GraphNode} projectionNode
|
|
142
|
+
*/
|
|
143
|
+
static _handleLevelsWithIONodes(projection, location, projectionNode) {
|
|
144
|
+
if (location.level === null && projectionNode.io) {
|
|
145
|
+
projection.level = null;
|
|
146
|
+
}
|
|
139
147
|
}
|
|
140
148
|
|
|
141
149
|
/**
|
|
@@ -147,12 +155,16 @@ class MapMatching {
|
|
|
147
155
|
};
|
|
148
156
|
|
|
149
157
|
/**
|
|
158
|
+
* Main function for map-matching, the networks have to be set before calling this function
|
|
159
|
+
* The function will returns a GraphProjection object given a coordinates object and a set
|
|
160
|
+
* of options (useDistance, useBearing, useMultiLevelSegments, acceptEdgeFn).
|
|
161
|
+
*
|
|
150
162
|
* @param {!Coordinates} location
|
|
151
163
|
* @param {boolean} useDistance
|
|
152
164
|
* @param {boolean} useBearing
|
|
153
165
|
* @param {boolean} useMultiLevelSegments
|
|
154
166
|
* @param {function} acceptEdgeFn
|
|
155
|
-
* @returns {GraphProjection}
|
|
167
|
+
* @returns {?GraphProjection}
|
|
156
168
|
*/
|
|
157
169
|
getProjection(location, useDistance = false, useBearing = false,
|
|
158
170
|
useMultiLevelSegments = true, acceptEdgeFn = () => true) {
|
|
@@ -166,22 +178,29 @@ class MapMatching {
|
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
if (useBearing && (!location.bearing || !this._maxAngleBearing)) {
|
|
181
|
+
// If useBearing is true and bearing is not set in coordinates, return null
|
|
169
182
|
return null;
|
|
170
183
|
}
|
|
171
184
|
|
|
185
|
+
// Build a new GraphProjection object from parameters
|
|
172
186
|
const projection = new GraphProjection();
|
|
173
187
|
projection.origin = location;
|
|
174
188
|
projection.distanceFromNearestElement = Number.MAX_VALUE;
|
|
175
189
|
projection.projection = location.clone();
|
|
176
190
|
|
|
191
|
+
// Define a function to know if a projection is better than the current one
|
|
177
192
|
const isProjectionBetter = (distanceOfNewProjection) => {
|
|
178
193
|
return distanceOfNewProjection < projection.distanceFromNearestElement
|
|
179
194
|
&& (!useDistance || distanceOfNewProjection <= this._maxDistance);
|
|
180
195
|
};
|
|
181
196
|
|
|
182
|
-
|
|
183
|
-
|
|
197
|
+
// Loop on all the network edges
|
|
198
|
+
// Each time a better projection is found (see isProjectionBetter()),
|
|
199
|
+
// the current projection is replaced
|
|
200
|
+
for (const edge of this.network.edges) {
|
|
184
201
|
|
|
202
|
+
// Check if the specified edge and its nodes can be used for projection. See the
|
|
203
|
+
// documentation of the corresponding function for more information.
|
|
185
204
|
const [checkEdge, checkNode1, checkNode2] = this._shouldProjectOnEdgeAndNodes(
|
|
186
205
|
edge, location, useBearing, useMultiLevelSegments, acceptEdgeFn);
|
|
187
206
|
|
|
@@ -192,12 +211,11 @@ class MapMatching {
|
|
|
192
211
|
projection.distanceFromNearestElement = distNode1;
|
|
193
212
|
projection.nearestElement = edge.node1;
|
|
194
213
|
MapMatching._assignLatLngLevel(edge.node1.coords, projection.projection);
|
|
214
|
+
MapMatching._handleLevelsWithIONodes(projection.projection, location, edge.node1);
|
|
195
215
|
|
|
196
|
-
if (distNode1 <= Constants.EPS_MM
|
|
197
|
-
&& location.level === edge.node1.coords.level) {
|
|
216
|
+
if (distNode1 <= Constants.EPS_MM) {
|
|
198
217
|
break;
|
|
199
218
|
}
|
|
200
|
-
MapMatching._updateProjectionLevelFromEdge(edge, projection.projection);
|
|
201
219
|
}
|
|
202
220
|
}
|
|
203
221
|
|
|
@@ -205,16 +223,14 @@ class MapMatching {
|
|
|
205
223
|
|
|
206
224
|
const distNode2 = location.distanceTo(edge.node2.coords);
|
|
207
225
|
if (isProjectionBetter(distNode2) || distNode2 <= Constants.EPS_MM) {
|
|
208
|
-
|
|
209
226
|
projection.distanceFromNearestElement = distNode2;
|
|
210
227
|
projection.nearestElement = edge.node2;
|
|
211
228
|
MapMatching._assignLatLngLevel(edge.node2.coords, projection.projection);
|
|
229
|
+
MapMatching._handleLevelsWithIONodes(projection.projection, location, edge.node2);
|
|
212
230
|
|
|
213
|
-
if (distNode2 <= Constants.EPS_MM
|
|
214
|
-
&& location.level === edge.node2.coords.level) {
|
|
231
|
+
if (distNode2 <= Constants.EPS_MM) {
|
|
215
232
|
break;
|
|
216
233
|
}
|
|
217
|
-
MapMatching._updateProjectionLevelFromEdge(edge, projection.projection);
|
|
218
234
|
}
|
|
219
235
|
}
|
|
220
236
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-statements */
|
|
1
2
|
import chai from 'chai';
|
|
2
3
|
|
|
3
4
|
import { deg2rad } from '@wemap/maths';
|
|
@@ -156,116 +157,220 @@ describe('MapMatching - multilevels', () => {
|
|
|
156
157
|
it('matching node levels', () => {
|
|
157
158
|
let currentPosition, projection;
|
|
158
159
|
|
|
159
|
-
currentPosition = new Coordinates(43.6091773, 3.8842584, null,
|
|
160
|
+
currentPosition = new Coordinates(43.6091773, 3.8842584, null, -1);
|
|
160
161
|
projection = mapMatching.getProjection(currentPosition);
|
|
161
162
|
expect(projection).is.null;
|
|
162
163
|
|
|
164
|
+
currentPosition = new Coordinates(43.6091773, 3.8842584, null, null);
|
|
165
|
+
projection = mapMatching.getProjection(currentPosition);
|
|
166
|
+
expect(projection).is.not.null;
|
|
167
|
+
expect(projection.projection.level).is.null;
|
|
168
|
+
expect(projection.nearestElement.builtFrom).equals('p22');
|
|
169
|
+
|
|
163
170
|
currentPosition = new Coordinates(43.6091773, 3.8842584, null, 1);
|
|
164
171
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
165
172
|
expect(projection).is.not.null;
|
|
166
|
-
expect(
|
|
173
|
+
expect(projection.projection.level).equals(1);
|
|
174
|
+
expect(projection.nearestElement.builtFrom).equals('p16');
|
|
167
175
|
|
|
168
176
|
currentPosition = new Coordinates(43.6091773, 3.8842584, null, 2);
|
|
169
177
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
170
178
|
expect(projection).is.not.null;
|
|
171
|
-
expect(
|
|
179
|
+
expect(projection.projection.level).equals(2);
|
|
180
|
+
expect(projection.nearestElement.builtFrom).equals('p5');
|
|
172
181
|
|
|
173
182
|
});
|
|
174
183
|
|
|
175
184
|
it('matching edge levels', () => {
|
|
176
185
|
let currentPosition, projection;
|
|
177
186
|
|
|
178
|
-
currentPosition = new Coordinates(43.6092811, 3.8842406, null,
|
|
187
|
+
currentPosition = new Coordinates(43.6092811, 3.8842406, null, -1);
|
|
179
188
|
projection = mapMatching.getProjection(currentPosition);
|
|
180
189
|
expect(projection).is.null;
|
|
181
190
|
|
|
191
|
+
currentPosition = new Coordinates(43.6095474, 3.8844914, null, null);
|
|
192
|
+
projection = mapMatching.getProjection(currentPosition);
|
|
193
|
+
expect(projection).is.not.null;
|
|
194
|
+
expect(projection.projection.level).is.null;
|
|
195
|
+
expect(projection.nearestElement.builtFrom).equals('e24');
|
|
196
|
+
|
|
182
197
|
currentPosition = new Coordinates(43.6092811, 3.8842406, null, 1);
|
|
183
198
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
184
199
|
expect(projection).is.not.null;
|
|
185
|
-
expect(
|
|
200
|
+
expect(projection.projection.level).equals(1);
|
|
201
|
+
expect(projection.nearestElement.builtFrom).equals('e15');
|
|
186
202
|
|
|
187
203
|
currentPosition = new Coordinates(43.6092811, 3.8842406, null, 2);
|
|
188
204
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
189
205
|
expect(projection).is.not.null;
|
|
190
|
-
expect(
|
|
206
|
+
expect(projection.projection.level).equals(2);
|
|
207
|
+
expect(projection.nearestElement.builtFrom).equals('e7');
|
|
191
208
|
|
|
192
209
|
});
|
|
193
210
|
|
|
194
211
|
it('matching stairs nodes levels', () => {
|
|
195
212
|
let currentPosition, projection;
|
|
196
213
|
|
|
197
|
-
currentPosition = new Coordinates(43.6093691, 3.8842057, null,
|
|
214
|
+
currentPosition = new Coordinates(43.6093691, 3.8842057, null, -1);
|
|
198
215
|
projection = mapMatching.getProjection(currentPosition);
|
|
199
216
|
expect(projection).is.null;
|
|
200
217
|
|
|
201
218
|
currentPosition = new Coordinates(43.6093691, 3.8842057, null, 1);
|
|
202
219
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
203
220
|
expect(projection).is.not.null;
|
|
204
|
-
expect(
|
|
221
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
222
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
205
223
|
|
|
206
224
|
currentPosition = new Coordinates(43.6093691, 3.8842057, null, 2);
|
|
207
225
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
208
226
|
expect(projection).is.not.null;
|
|
209
|
-
expect(
|
|
227
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
228
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
229
|
+
|
|
230
|
+
currentPosition = new Coordinates(43.6093691, 3.8842057, null, [1, 2]);
|
|
231
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
232
|
+
expect(projection).is.not.null;
|
|
233
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
234
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
210
235
|
|
|
211
236
|
});
|
|
212
237
|
|
|
213
238
|
it('matching stairs edge levels', () => {
|
|
214
239
|
let currentPosition, projection;
|
|
215
240
|
|
|
216
|
-
currentPosition = new Coordinates(43.6093476, 3.8841978, null,
|
|
241
|
+
currentPosition = new Coordinates(43.6093476, 3.8841978, null, -1);
|
|
217
242
|
projection = mapMatching.getProjection(currentPosition);
|
|
218
243
|
expect(projection).is.null;
|
|
219
244
|
|
|
220
245
|
currentPosition = new Coordinates(43.6093476, 3.8841978, null, 1);
|
|
221
246
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
222
247
|
expect(projection).is.not.null;
|
|
223
|
-
expect(
|
|
224
|
-
expect(Level.
|
|
248
|
+
expect(projection.nearestElement.builtFrom).equals('e11');
|
|
249
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
225
250
|
|
|
226
251
|
currentPosition = new Coordinates(43.6093476, 3.8841978, null, 2);
|
|
227
252
|
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
228
253
|
expect(projection).is.not.null;
|
|
229
|
-
expect(
|
|
230
|
-
expect(Level.
|
|
254
|
+
expect(projection.nearestElement.builtFrom).equals('e11');
|
|
255
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
256
|
+
|
|
257
|
+
currentPosition = new Coordinates(43.6093476, 3.8841978, null, [1, 2]);
|
|
258
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
259
|
+
expect(projection).is.not.null;
|
|
260
|
+
expect(projection.nearestElement.builtFrom).equals('e11');
|
|
261
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
231
262
|
|
|
232
263
|
});
|
|
233
264
|
|
|
234
|
-
it('useMultiLevelSegments', () => {
|
|
265
|
+
it('useMultiLevelSegments = false', () => {
|
|
235
266
|
let currentPosition, projection;
|
|
236
267
|
|
|
237
268
|
// On Nodes
|
|
238
269
|
|
|
239
|
-
currentPosition = new Coordinates(43.6093381, 3.8841926, null,
|
|
270
|
+
currentPosition = new Coordinates(43.6093381, 3.8841926, null, -1);
|
|
240
271
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
241
272
|
expect(projection).is.null;
|
|
273
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
274
|
+
expect(projection).is.null;
|
|
275
|
+
|
|
276
|
+
currentPosition = new Coordinates(43.6093381, 3.8841926, null, 0);
|
|
277
|
+
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
278
|
+
expect(projection).is.not.null;
|
|
279
|
+
expect(projection.projection.level).equals(0);
|
|
280
|
+
expect(projection.nearestElement.builtFrom).equals('p19c');
|
|
281
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
282
|
+
expect(projection.nearestElement.builtFrom).equals('p19c');
|
|
242
283
|
|
|
243
284
|
currentPosition = new Coordinates(43.6093381, 3.8841926, null, 1);
|
|
244
285
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
245
286
|
expect(projection).is.not.null;
|
|
287
|
+
expect(projection.projection.level).equals(1);
|
|
246
288
|
expect(projection.nearestElement.builtFrom).equals('p14');
|
|
289
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
290
|
+
expect(projection.nearestElement.builtFrom).equals('e11');
|
|
247
291
|
|
|
248
292
|
currentPosition = new Coordinates(43.6093381, 3.8841926, null, 2);
|
|
249
293
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
250
294
|
expect(projection).is.not.null;
|
|
295
|
+
expect(projection.projection.level).equals(2);
|
|
251
296
|
expect(projection.nearestElement.builtFrom).equals('p11');
|
|
252
|
-
|
|
297
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
298
|
+
expect(projection.nearestElement.builtFrom).equals('e11');
|
|
253
299
|
|
|
254
300
|
// On Segments
|
|
255
301
|
|
|
256
|
-
currentPosition = new Coordinates(43.
|
|
302
|
+
currentPosition = new Coordinates(43.6093551, 3.88425725, null, -1);
|
|
257
303
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
258
304
|
expect(projection).is.null;
|
|
259
305
|
|
|
260
|
-
currentPosition = new Coordinates(43.
|
|
306
|
+
currentPosition = new Coordinates(43.6093551, 3.88425725, null, 0);
|
|
307
|
+
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
308
|
+
expect(projection).is.not.null;
|
|
309
|
+
expect(projection.projection.level).equals(0);
|
|
310
|
+
expect(projection.nearestElement.builtFrom).equals('e22');
|
|
311
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
312
|
+
expect(projection.nearestElement.builtFrom).equals('e22');
|
|
313
|
+
|
|
314
|
+
currentPosition = new Coordinates(43.6093551, 3.88425725, null, 1);
|
|
261
315
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
262
316
|
expect(projection).is.not.null;
|
|
263
|
-
expect(projection.
|
|
317
|
+
expect(projection.projection.level).equals(1);
|
|
318
|
+
expect(projection.nearestElement.builtFrom).equals('e17');
|
|
319
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
320
|
+
expect(projection.nearestElement.builtFrom).equals('e13');
|
|
264
321
|
|
|
265
322
|
currentPosition = new Coordinates(43.6093258, 3.8842272, null, 2);
|
|
266
323
|
projection = mapMatching.getProjection(currentPosition, true, false, false);
|
|
267
324
|
expect(projection).is.not.null;
|
|
325
|
+
expect(projection.projection.level).equals(2);
|
|
268
326
|
expect(projection.nearestElement.builtFrom).equals('e10');
|
|
327
|
+
projection = mapMatching.getProjection(currentPosition, true, false, true);
|
|
328
|
+
expect(projection.nearestElement.builtFrom).equals('e13');
|
|
329
|
+
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it('matching exact node position with eps', () => {
|
|
333
|
+
let currentPosition, projection;
|
|
334
|
+
|
|
335
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, -1);
|
|
336
|
+
projection = mapMatching.getProjection(currentPosition);
|
|
337
|
+
expect(projection).is.null;
|
|
338
|
+
|
|
339
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, null);
|
|
340
|
+
projection = mapMatching.getProjection(currentPosition);
|
|
341
|
+
expect(projection).is.not.null;
|
|
342
|
+
expect(projection.nearestElement.builtFrom).equals('p22');
|
|
343
|
+
expect(projection.projection.level).is.null;
|
|
344
|
+
|
|
345
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, [1, 2]);
|
|
346
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
347
|
+
expect(projection).is.not.null;
|
|
348
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
349
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
350
|
+
|
|
351
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, 1);
|
|
352
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
353
|
+
expect(projection).is.not.null;
|
|
354
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
355
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
356
|
+
|
|
357
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, 2);
|
|
358
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
359
|
+
expect(projection).is.not.null;
|
|
360
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
361
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
362
|
+
|
|
363
|
+
currentPosition = new Coordinates(43.60936289383032, 3.884212691390017, null, [0, 3]);
|
|
364
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
365
|
+
expect(projection).is.not.null;
|
|
366
|
+
expect(projection.nearestElement.builtFrom).equals('p12');
|
|
367
|
+
expect(Level.equals(projection.projection.level, [1, 2])).true;
|
|
368
|
+
|
|
369
|
+
currentPosition = new Coordinates(43.6093323, 3.8842483, null, 0);
|
|
370
|
+
projection = mapMatching.getProjection(currentPosition, true, false);
|
|
371
|
+
expect(projection).is.not.null;
|
|
372
|
+
expect(projection.nearestElement.builtFrom).equals('p19c');
|
|
373
|
+
expect(projection.projection.level).equals(0);
|
|
269
374
|
|
|
270
375
|
});
|
|
271
376
|
|
package/src/graph/Network.js
CHANGED
|
@@ -196,7 +196,7 @@ class Network {
|
|
|
196
196
|
getEdgesAtLevel(targetLevel, useMultiLevelEdges = true) {
|
|
197
197
|
return this.edges.filter(
|
|
198
198
|
({ level }) => useMultiLevelEdges
|
|
199
|
-
? Level.intersect(targetLevel, level)
|
|
199
|
+
? Level.intersect(targetLevel, level)
|
|
200
200
|
: Level.contains(targetLevel, level)
|
|
201
201
|
);
|
|
202
202
|
}
|
package/tests/CommonTest.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-inline-comments */
|
|
1
2
|
import chai from 'chai';
|
|
2
3
|
|
|
3
4
|
import Coordinates from '../src/coordinates/Coordinates.js';
|
|
@@ -9,7 +10,7 @@ import Network from '../src/graph/Network.js';
|
|
|
9
10
|
const { expect } = chai;
|
|
10
11
|
|
|
11
12
|
const nodes = [
|
|
12
|
-
new Node(new Coordinates(43.6092404, 3.884099), 'p0'),
|
|
13
|
+
new Node(new Coordinates(43.6092404, 3.884099), 'p0'), // 0
|
|
13
14
|
new Node(new Coordinates(43.6091965, 3.8841285), 'p1'),
|
|
14
15
|
new Node(new Coordinates(43.6091888, 3.8841263), 'p2'),
|
|
15
16
|
new Node(new Coordinates(43.6091361, 3.8841109), 'p3'),
|
|
@@ -19,7 +20,7 @@ const nodes = [
|
|
|
19
20
|
new Node(new Coordinates(43.609276, 3.8842467), 'p7'),
|
|
20
21
|
new Node(new Coordinates(43.6092935, 3.8842518), 'p8'),
|
|
21
22
|
new Node(new Coordinates(43.6093022, 3.8842702), 'p9'),
|
|
22
|
-
new Node(new Coordinates(43.6093123, 3.8842731), 'p10'),
|
|
23
|
+
new Node(new Coordinates(43.6093123, 3.8842731), 'p10'), // 10
|
|
23
24
|
new Node(new Coordinates(43.6093234, 3.8842009), 'p11'),
|
|
24
25
|
new Node(new Coordinates(43.6093629, 3.8842127), 'p12'),
|
|
25
26
|
new Node(new Coordinates(43.6093597, 3.8842336), 'p13'),
|
|
@@ -29,31 +30,41 @@ const nodes = [
|
|
|
29
30
|
new Node(new Coordinates(43.6093279, 3.8842777), 'p17'),
|
|
30
31
|
new Node(new Coordinates(43.6093279, 3.8842777), 'p18'),
|
|
31
32
|
new Node(new Coordinates(43.6093323, 3.8842483), 'p19a'),
|
|
32
|
-
new Node(new Coordinates(43.6093323, 3.8842483), 'p19b')
|
|
33
|
+
new Node(new Coordinates(43.6093323, 3.8842483), 'p19b'), // 20
|
|
34
|
+
new Node(new Coordinates(43.6093323, 3.8842483), 'p19c'),
|
|
35
|
+
new Node(new Coordinates(43.6093032, 3.8844388), 'p21'),
|
|
36
|
+
new Node(new Coordinates(43.6095297, 3.8845039), 'p22'),
|
|
37
|
+
new Node(new Coordinates(43.6095624, 3.8845134), 'p23')
|
|
33
38
|
];
|
|
34
39
|
|
|
40
|
+
const n = name => nodes.find(node => node.builtFrom === name);
|
|
41
|
+
|
|
35
42
|
const edges = [
|
|
36
|
-
new Edge(
|
|
37
|
-
new Edge(
|
|
38
|
-
new Edge(
|
|
39
|
-
new Edge(
|
|
40
|
-
new Edge(
|
|
41
|
-
new Edge(
|
|
42
|
-
new Edge(
|
|
43
|
-
new Edge(
|
|
44
|
-
new Edge(
|
|
45
|
-
new Edge(
|
|
46
|
-
new Edge(
|
|
47
|
-
new Edge(
|
|
48
|
-
new Edge(
|
|
49
|
-
new Edge(
|
|
50
|
-
new Edge(
|
|
51
|
-
new Edge(
|
|
52
|
-
new Edge(
|
|
53
|
-
new Edge(
|
|
54
|
-
new Edge(
|
|
55
|
-
new Edge(
|
|
56
|
-
new Edge(
|
|
43
|
+
new Edge(n('p1'), n('p2'), 2, 'e0'),
|
|
44
|
+
new Edge(n('p2'), n('p3'), 2, 'e1'),
|
|
45
|
+
new Edge(n('p3'), n('p4'), 2, 'e2'),
|
|
46
|
+
new Edge(n('p4'), n('p5'), 2, 'e3'),
|
|
47
|
+
new Edge(n('p5'), n('p6'), 2, 'e4'),
|
|
48
|
+
new Edge(n('p6'), n('p2'), 2, 'e5'),
|
|
49
|
+
new Edge(n('p6'), n('p7'), 2, 'e6'),
|
|
50
|
+
new Edge(n('p7'), n('p8'), 2, 'e7'),
|
|
51
|
+
new Edge(n('p8'), n('p9'), 2, 'e8'),
|
|
52
|
+
new Edge(n('p9'), n('p10'), 2, 'e9'),
|
|
53
|
+
new Edge(n('p10'), n('p11'), 2, 'e10'),
|
|
54
|
+
new Edge(n('p11'), n('p12'), [1, 2], 'e11'),
|
|
55
|
+
new Edge(n('p12'), n('p13'), [1, 2], 'e12'),
|
|
56
|
+
new Edge(n('p13'), n('p14'), [1, 2], 'e13'),
|
|
57
|
+
new Edge(n('p14'), n('p15'), 1, 'e14'),
|
|
58
|
+
new Edge(n('p15'), n('p16'), 1, 'e15'),
|
|
59
|
+
new Edge(n('p15'), n('p17'), 1, 'e16'),
|
|
60
|
+
new Edge(n('p19b'), n('p17'), 1, 'e17'),
|
|
61
|
+
new Edge(n('p10'), n('p18'), 2, 'e18'),
|
|
62
|
+
new Edge(n('p19a'), n('p18'), 2, 'e19'),
|
|
63
|
+
new Edge(n('p19a'), n('p19b'), [1, 2], 'e20'),
|
|
64
|
+
new Edge(n('p19b'), n('p19c'), [0, 1], 'e21'),
|
|
65
|
+
new Edge(n('p19c'), n('p21'), 0, 'e22'),
|
|
66
|
+
new Edge(n('p21'), n('p22'), 0, 'e23'),
|
|
67
|
+
new Edge(n('p22'), n('p23'), null, 'e24')
|
|
57
68
|
];
|
|
58
69
|
|
|
59
70
|
const network = new Network();
|