@wemap/geo 4.0.1 → 4.0.3
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/index.js +1 -0
- package/package.json +3 -3
- package/src/graph/MapMatching.js +28 -7
- package/src/graph/MapMatching.spec.js +1 -1
- package/src/graph/Projection.js +21 -0
- package/src/rotations/Attitude.js +32 -9
package/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export { default as Itinerary } from './src/graph/Itinerary.js';
|
|
|
20
20
|
export { default as Network } from './src/graph/Network.js';
|
|
21
21
|
export { default as Node } from './src/graph/Node.js';
|
|
22
22
|
export { default as MapMatching } from './src/graph/MapMatching.js';
|
|
23
|
+
export { default as Projection } from './src/graph/Projection.js';
|
|
23
24
|
export { default as Step } from './src/graph/Step.js';
|
|
24
25
|
export * as GraphUtils from './src/graph/Utils.js';
|
|
25
26
|
export { default as NoRouteFoundError } from './src/graph/NoRouteFoundError.js';
|
package/package.json
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"directory": "packages/geo"
|
|
13
13
|
},
|
|
14
14
|
"name": "@wemap/geo",
|
|
15
|
-
"version": "4.0.
|
|
15
|
+
"version": "4.0.3",
|
|
16
16
|
"bugs": {
|
|
17
17
|
"url": "https://github.com/wemap/wemap-modules-js/issues"
|
|
18
18
|
},
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"license": "ISC",
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@wemap/logger": "^4.0.0",
|
|
31
|
-
"@wemap/maths": "^4.0.
|
|
31
|
+
"@wemap/maths": "^4.0.3"
|
|
32
32
|
},
|
|
33
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "91a82028ddda32038999582da381d1d0d8acd091"
|
|
34
34
|
}
|
package/src/graph/MapMatching.js
CHANGED
|
@@ -7,6 +7,7 @@ import Coordinates from '../coordinates/Coordinates.js';
|
|
|
7
7
|
import Level from '../coordinates/Level.js';
|
|
8
8
|
|
|
9
9
|
import Network from './Network.js';
|
|
10
|
+
import Projection from './Projection.js';
|
|
10
11
|
|
|
11
12
|
class MapMatching {
|
|
12
13
|
|
|
@@ -105,8 +106,7 @@ class MapMatching {
|
|
|
105
106
|
// if mapmatching bearing is enabled do not use nodes matching
|
|
106
107
|
if (checkEdge) {
|
|
107
108
|
// condition for optimisation
|
|
108
|
-
const diffAngle = diffAngleLines(
|
|
109
|
-
edge.bearing, location.bearing);
|
|
109
|
+
const diffAngle = diffAngleLines(edge.bearing, location.bearing);
|
|
110
110
|
if (diffAngle > this._maxAngleBearing) {
|
|
111
111
|
// Do not try to project if angle is greater than the threshold
|
|
112
112
|
checkEdge = false;
|
|
@@ -119,6 +119,21 @@ class MapMatching {
|
|
|
119
119
|
return [checkEdge, checkNode1, checkNode2];
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @param {Coordinates} fromCoordinates
|
|
125
|
+
* @param {Coordinates} toCoordinates
|
|
126
|
+
*/
|
|
127
|
+
static _assignLatLngLevel(fromCoordinates, toCoordinates) {
|
|
128
|
+
toCoordinates.lat = fromCoordinates.lat;
|
|
129
|
+
toCoordinates.lng = fromCoordinates.lng;
|
|
130
|
+
toCoordinates.level = fromCoordinates.level;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {Edge} _edge
|
|
135
|
+
* @param {Coordinates} _projection
|
|
136
|
+
*/
|
|
122
137
|
static _updateProjectionLevelFromEdge = (_edge, _projection) => {
|
|
123
138
|
if (_edge.level) {
|
|
124
139
|
_projection.level = _edge.level.clone();
|
|
@@ -131,6 +146,7 @@ class MapMatching {
|
|
|
131
146
|
* @param {boolean} useBearing
|
|
132
147
|
* @param {boolean} useMultiLevelSegments
|
|
133
148
|
* @param {function} acceptEdgeFn
|
|
149
|
+
* @returns {Projection}
|
|
134
150
|
*/
|
|
135
151
|
getProjection(location, useDistance = false, useBearing = false,
|
|
136
152
|
useMultiLevelSegments = true, acceptEdgeFn = () => true) {
|
|
@@ -147,9 +163,10 @@ class MapMatching {
|
|
|
147
163
|
return null;
|
|
148
164
|
}
|
|
149
165
|
|
|
150
|
-
const projection =
|
|
166
|
+
const projection = new Projection();
|
|
151
167
|
projection.origin = location;
|
|
152
168
|
projection.distanceFromNearestElement = Number.MAX_VALUE;
|
|
169
|
+
projection.projection = location.clone();
|
|
153
170
|
|
|
154
171
|
const isProjectionBetter = (distanceOfNewProjection) => {
|
|
155
172
|
return distanceOfNewProjection < projection.distanceFromNearestElement
|
|
@@ -168,7 +185,7 @@ class MapMatching {
|
|
|
168
185
|
if (isProjectionBetter(distNode1) || distNode1 <= Constants.EPS_MM) {
|
|
169
186
|
projection.distanceFromNearestElement = distNode1;
|
|
170
187
|
projection.nearestElement = edge.node1;
|
|
171
|
-
|
|
188
|
+
MapMatching._assignLatLngLevel(edge.node1.coords, projection.projection);
|
|
172
189
|
MapMatching._updateProjectionLevelFromEdge(edge, projection.projection);
|
|
173
190
|
|
|
174
191
|
if (distNode1 <= Constants.EPS_MM
|
|
@@ -185,7 +202,7 @@ class MapMatching {
|
|
|
185
202
|
|
|
186
203
|
projection.distanceFromNearestElement = distNode2;
|
|
187
204
|
projection.nearestElement = edge.node2;
|
|
188
|
-
|
|
205
|
+
MapMatching._assignLatLngLevel(edge.node2.coords, projection.projection);
|
|
189
206
|
MapMatching._updateProjectionLevelFromEdge(edge, projection.projection);
|
|
190
207
|
|
|
191
208
|
if (distNode2 <= Constants.EPS_MM
|
|
@@ -202,19 +219,23 @@ class MapMatching {
|
|
|
202
219
|
if (isProjectionBetter(distEdge)) {
|
|
203
220
|
projection.distanceFromNearestElement = distEdge;
|
|
204
221
|
projection.nearestElement = edge;
|
|
205
|
-
projection.projection
|
|
222
|
+
MapMatching._assignLatLngLevel(segmentProjection, projection.projection);
|
|
206
223
|
MapMatching._updateProjectionLevelFromEdge(edge, projection.projection);
|
|
207
224
|
}
|
|
208
225
|
}
|
|
209
226
|
}
|
|
210
227
|
}
|
|
211
228
|
|
|
212
|
-
|
|
229
|
+
|
|
230
|
+
if (!projection.nearestElement) {
|
|
213
231
|
return null;
|
|
214
232
|
}
|
|
215
233
|
|
|
234
|
+
projection.projection.accuracy += projection.distanceFromNearestElement;
|
|
235
|
+
|
|
216
236
|
return projection;
|
|
217
237
|
}
|
|
238
|
+
|
|
218
239
|
}
|
|
219
240
|
|
|
220
241
|
export default MapMatching;
|
|
@@ -85,7 +85,7 @@ describe('MapMatching', () => {
|
|
|
85
85
|
const owMapMatching = new MapMatching(owNetwork);
|
|
86
86
|
result = owMapMatching.getProjection(new Coordinates(43.6092086, 3.8842598, 10));
|
|
87
87
|
expect(result).is.not.null;
|
|
88
|
-
expect(result.projection.alt).equals(
|
|
88
|
+
expect(result.projection.alt).equals(10);
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
it('with bearing', () => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import Coordinates from '../coordinates/Coordinates.js';
|
|
2
|
+
import Edge from './Edge.js';
|
|
3
|
+
import Node from './Node.js';
|
|
4
|
+
|
|
5
|
+
class Projection {
|
|
6
|
+
|
|
7
|
+
/** @type {Coordinates} */
|
|
8
|
+
origin;
|
|
9
|
+
|
|
10
|
+
/** @type {number} */
|
|
11
|
+
distanceFromNearestElement;
|
|
12
|
+
|
|
13
|
+
/** @type {Coordinates} */
|
|
14
|
+
projection;
|
|
15
|
+
|
|
16
|
+
/** @type {Node|Edge} */
|
|
17
|
+
nearestElement;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default Projection;
|
|
@@ -12,9 +12,9 @@ class Attitude {
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
*
|
|
15
|
-
* @param {
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {
|
|
15
|
+
* @param {number[]} quaternion
|
|
16
|
+
* @param {number} time
|
|
17
|
+
* @param {number} accuracy
|
|
18
18
|
*/
|
|
19
19
|
constructor(quaternion, time, accuracy) {
|
|
20
20
|
this.quaternion = quaternion;
|
|
@@ -27,14 +27,14 @@ class Attitude {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
* @returns {
|
|
30
|
+
* @returns {number[]}
|
|
31
31
|
*/
|
|
32
32
|
get quaternion() {
|
|
33
33
|
return this._quaternion;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
/**
|
|
37
|
-
* @param {
|
|
37
|
+
* @param {number[]} quaternion
|
|
38
38
|
*/
|
|
39
39
|
set quaternion(quaternion) {
|
|
40
40
|
if (!Array.isArray(quaternion)
|
|
@@ -48,14 +48,14 @@ class Attitude {
|
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
|
-
* @returns {
|
|
51
|
+
* @returns {number}
|
|
52
52
|
*/
|
|
53
53
|
get time() {
|
|
54
54
|
return this._time;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* @param {
|
|
58
|
+
* @param {number} time
|
|
59
59
|
*/
|
|
60
60
|
set time(time) {
|
|
61
61
|
if (typeof time === 'number') {
|
|
@@ -69,14 +69,14 @@ class Attitude {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
|
-
* @returns {
|
|
72
|
+
* @returns {number}
|
|
73
73
|
*/
|
|
74
74
|
get accuracy() {
|
|
75
75
|
return this._accuracy;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
|
-
* @param {
|
|
79
|
+
* @param {number} accuracy
|
|
80
80
|
*/
|
|
81
81
|
set accuracy(accuracy) {
|
|
82
82
|
if (typeof accuracy === 'number' && accuracy >= 0 && accuracy <= Math.PI) {
|
|
@@ -89,6 +89,7 @@ class Attitude {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
/** @type {number[]} */
|
|
92
93
|
get eulerAngles() {
|
|
93
94
|
if (this._eulerAngles === null) {
|
|
94
95
|
this._eulerAngles = Rotations.quaternionToEulerZXY(this.quaternion);
|
|
@@ -96,10 +97,12 @@ class Attitude {
|
|
|
96
97
|
return this._eulerAngles;
|
|
97
98
|
}
|
|
98
99
|
|
|
100
|
+
/** @type {number[]} */
|
|
99
101
|
get eulerAnglesDegrees() {
|
|
100
102
|
return this.eulerAngles.map(x => rad2deg(x));
|
|
101
103
|
}
|
|
102
104
|
|
|
105
|
+
/** @type {number} */
|
|
103
106
|
get heading() {
|
|
104
107
|
if (this._heading === null) {
|
|
105
108
|
let offset = 0;
|
|
@@ -111,6 +114,7 @@ class Attitude {
|
|
|
111
114
|
return this._heading;
|
|
112
115
|
}
|
|
113
116
|
|
|
117
|
+
/** @type {number} */
|
|
114
118
|
get headingDegrees() {
|
|
115
119
|
return rad2deg(this.heading);
|
|
116
120
|
}
|
|
@@ -124,6 +128,7 @@ class Attitude {
|
|
|
124
128
|
|
|
125
129
|
// Handle null comparison
|
|
126
130
|
if (att1 === null && att1 === att2) {
|
|
131
|
+
// TODO not sure to return true here.
|
|
127
132
|
return true;
|
|
128
133
|
}
|
|
129
134
|
|
|
@@ -131,21 +136,39 @@ class Attitude {
|
|
|
131
136
|
return false;
|
|
132
137
|
}
|
|
133
138
|
|
|
139
|
+
if (att1 === att2) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
134
143
|
return Quaternion.equalsTo(att1.quaternion, att2.quaternion);
|
|
135
144
|
}
|
|
136
145
|
|
|
146
|
+
/**
|
|
147
|
+
* @param {Attitude} other
|
|
148
|
+
* @returns {boolean}
|
|
149
|
+
*/
|
|
137
150
|
equalsTo(other) {
|
|
138
151
|
return Attitude.equalsTo(this, other);
|
|
139
152
|
}
|
|
140
153
|
|
|
154
|
+
/**
|
|
155
|
+
* @returns {object}
|
|
156
|
+
*/
|
|
141
157
|
toJson() {
|
|
142
158
|
return this.quaternion;
|
|
143
159
|
}
|
|
144
160
|
|
|
161
|
+
/**
|
|
162
|
+
* @param {object} json
|
|
163
|
+
* @returns {Attitude}
|
|
164
|
+
*/
|
|
145
165
|
static fromJson(json) {
|
|
146
166
|
return new Attitude(json);
|
|
147
167
|
}
|
|
148
168
|
|
|
169
|
+
/**
|
|
170
|
+
* @returns {Attitude}
|
|
171
|
+
*/
|
|
149
172
|
clone() {
|
|
150
173
|
return new Attitude(this.quaternion.slice(0), this.time, this.accuracy);
|
|
151
174
|
}
|