@wemap/geo 10.0.0-alpha.0 → 10.0.0-alpha.10
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.d.ts +1 -19
- package/package.json +4 -4
- package/src/coordinates/Coordinates.js +1 -59
- package/src/coordinates/Coordinates.spec.js +1 -24
- package/src/coordinates/GeoRef.js +1 -1
- package/src/coordinates/Level.js +0 -14
- package/src/coordinates/Level.spec.js +0 -11
- package/src/graph/GraphNode.js +9 -22
- package/src/graph/GraphNode.spec.js +13 -13
- package/src/graph/Network.js +9 -3
- package/src/rotations/Attitude.js +24 -0
- package/src/rotations/Attitude.spec.js +33 -3
package/index.d.ts
CHANGED
|
@@ -16,9 +16,6 @@ declare module '@wemap/geo' {
|
|
|
16
16
|
static toString(level: Level_t): string;
|
|
17
17
|
static equals(first: Level_t, second: Level_t): boolean;
|
|
18
18
|
static diff(first: Level_t, second: Level_t): null | number;
|
|
19
|
-
|
|
20
|
-
/** @deprecated */
|
|
21
|
-
static fromLegacy(level: (null | { isRange: boolean, val?: number, low?: number, up?: number })): Level_t;
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
type CoordinatesCompressedJson = [number, number] |
|
|
@@ -65,22 +62,6 @@ declare module '@wemap/geo' {
|
|
|
65
62
|
toCompressedJson(): CoordinatesCompressedJson;
|
|
66
63
|
static fromJson(json: CoordinatesJson): Coordinates;
|
|
67
64
|
static fromCompressedJson(json: CoordinatesCompressedJson): Coordinates;
|
|
68
|
-
|
|
69
|
-
/** @deprecated */
|
|
70
|
-
toLegacyJson(): any;
|
|
71
|
-
/** @deprecated */
|
|
72
|
-
toLegacyCompressedJson():
|
|
73
|
-
[number, number] |
|
|
74
|
-
[number, number, number] |
|
|
75
|
-
[number, number, number, string] |
|
|
76
|
-
[number, number, null, string];
|
|
77
|
-
/** @deprecated */
|
|
78
|
-
static fromLegacyCompressedJson(json:
|
|
79
|
-
[number, number] |
|
|
80
|
-
[number, number, number] |
|
|
81
|
-
[number, number, number, string] |
|
|
82
|
-
[number, number, null, string]): Coordinates;
|
|
83
|
-
|
|
84
65
|
}
|
|
85
66
|
|
|
86
67
|
export type AttitudeJson = Quaternion_t
|
|
@@ -104,6 +85,7 @@ declare module '@wemap/geo' {
|
|
|
104
85
|
static unitary(): Attitude;
|
|
105
86
|
static equals(attitude1: Attitude, attitude2: Attitude): boolean;
|
|
106
87
|
static fromJson(json: AttitudeJson): Attitude;
|
|
88
|
+
static diff(attitudeStart: Attitude, attitudeEnd: Attitude): Attitude;
|
|
107
89
|
}
|
|
108
90
|
|
|
109
91
|
export class GeoRef {
|
package/package.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"directory": "packages/geo"
|
|
14
14
|
},
|
|
15
15
|
"name": "@wemap/geo",
|
|
16
|
-
"version": "10.0.0-alpha.
|
|
16
|
+
"version": "10.0.0-alpha.10",
|
|
17
17
|
"bugs": {
|
|
18
18
|
"url": "https://github.com/wemap/wemap-modules-js/issues"
|
|
19
19
|
},
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
],
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@wemap/logger": "^
|
|
32
|
-
"@wemap/maths": "^
|
|
31
|
+
"@wemap/logger": "^10.0.0-alpha.8",
|
|
32
|
+
"@wemap/maths": "^10.0.0-alpha.10"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "5970289ef2b1f06f9df382878f72bf48f57c4c00"
|
|
35
35
|
}
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import Logger from '@wemap/logger';
|
|
2
|
-
|
|
3
1
|
import {
|
|
4
2
|
deg2rad, Vector3, Quaternion, rad2deg, wrap
|
|
5
3
|
} from '@wemap/maths';
|
|
@@ -448,32 +446,11 @@ class Coordinates {
|
|
|
448
446
|
return output;
|
|
449
447
|
}
|
|
450
448
|
|
|
451
|
-
/**
|
|
452
|
-
* @returns {!Object}
|
|
453
|
-
*/
|
|
454
|
-
toLegacyJson() {
|
|
455
|
-
const output = {
|
|
456
|
-
lat: this.lat,
|
|
457
|
-
lng: this.lng
|
|
458
|
-
};
|
|
459
|
-
if (this.alt !== null) {
|
|
460
|
-
output.alt = this.alt;
|
|
461
|
-
}
|
|
462
|
-
if (this.level !== null) {
|
|
463
|
-
output.level = Level.toString(this.level);
|
|
464
|
-
}
|
|
465
|
-
return output;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
449
|
/**
|
|
469
450
|
* @param {!Object} json
|
|
470
451
|
* @returns {!Coordinates}
|
|
471
452
|
*/
|
|
472
453
|
static fromJson(json) {
|
|
473
|
-
if (typeof json.level === 'string') {
|
|
474
|
-
Logger.warn('Still using legacy level format. Please update your project.');
|
|
475
|
-
return new Coordinates(json.lat, json.lng, json.alt, Level.fromString(json.level));
|
|
476
|
-
}
|
|
477
454
|
return new Coordinates(json.lat, json.lng, json.alt, json.level);
|
|
478
455
|
}
|
|
479
456
|
|
|
@@ -491,21 +468,6 @@ class Coordinates {
|
|
|
491
468
|
return output;
|
|
492
469
|
}
|
|
493
470
|
|
|
494
|
-
/**
|
|
495
|
-
* @returns {!Object}
|
|
496
|
-
* @deprecated
|
|
497
|
-
*/
|
|
498
|
-
toLegacyCompressedJson() {
|
|
499
|
-
const output = [this.lat, this.lng];
|
|
500
|
-
if (this.alt !== null || this.level !== null) {
|
|
501
|
-
output.push(this.alt);
|
|
502
|
-
}
|
|
503
|
-
if (this.level !== null) {
|
|
504
|
-
output.push(Level.toString(this.level));
|
|
505
|
-
}
|
|
506
|
-
return output;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
471
|
/**
|
|
510
472
|
* @param {!Object} json
|
|
511
473
|
* @returns {!Coordinates}
|
|
@@ -516,27 +478,7 @@ class Coordinates {
|
|
|
516
478
|
coords.alt = json[2];
|
|
517
479
|
}
|
|
518
480
|
if (json.length > 3) {
|
|
519
|
-
|
|
520
|
-
Logger.warn('Still using legacy level format. Please update your project.');
|
|
521
|
-
coords.level = Level.fromString(json[3]);
|
|
522
|
-
} else {
|
|
523
|
-
coords.level = json[3];
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return coords;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* @param {!Object} json
|
|
531
|
-
* @returns {!Coordinates}
|
|
532
|
-
*/
|
|
533
|
-
static fromLegacyCompressedJson(json) {
|
|
534
|
-
const coords = new Coordinates(json[0], json[1]);
|
|
535
|
-
if (json.length > 2) {
|
|
536
|
-
coords.alt = json[2];
|
|
537
|
-
}
|
|
538
|
-
if (json.length > 3) {
|
|
539
|
-
coords.level = Level.fromString(json[3]);
|
|
481
|
+
coords.level = json[3];
|
|
540
482
|
}
|
|
541
483
|
return coords;
|
|
542
484
|
}
|
|
@@ -250,12 +250,6 @@ describe('Coordinates', () => {
|
|
|
250
250
|
level: [1, 2]
|
|
251
251
|
});
|
|
252
252
|
|
|
253
|
-
expect(new Coordinates(5, -10, null, [1, 2]).toLegacyJson()).to.deep.equal({
|
|
254
|
-
lat: 5,
|
|
255
|
-
lng: -10,
|
|
256
|
-
level: '1;2'
|
|
257
|
-
});
|
|
258
|
-
|
|
259
253
|
expect(new Coordinates(5, -10, 3, [1, 2]).toJson()).to.deep.equal({
|
|
260
254
|
lat: 5,
|
|
261
255
|
lng: -10,
|
|
@@ -263,13 +257,6 @@ describe('Coordinates', () => {
|
|
|
263
257
|
level: [1, 2]
|
|
264
258
|
});
|
|
265
259
|
|
|
266
|
-
expect(new Coordinates(5, -10, 3, [1, 2]).toLegacyJson()).to.deep.equal({
|
|
267
|
-
lat: 5,
|
|
268
|
-
lng: -10,
|
|
269
|
-
alt: 3,
|
|
270
|
-
level: '1;2'
|
|
271
|
-
});
|
|
272
|
-
|
|
273
260
|
let position;
|
|
274
261
|
|
|
275
262
|
position = new Coordinates(0, 0);
|
|
@@ -296,20 +283,10 @@ describe('Coordinates', () => {
|
|
|
296
283
|
).true;
|
|
297
284
|
|
|
298
285
|
expect(Coordinates.equals(
|
|
299
|
-
Coordinates.fromCompressedJson([5, -10, null,
|
|
300
|
-
new Coordinates(5, -10, null, 1))
|
|
301
|
-
).true;
|
|
302
|
-
|
|
303
|
-
expect(Coordinates.equals(
|
|
304
|
-
Coordinates.fromCompressedJson([5, -10, null, '1;2']),
|
|
286
|
+
Coordinates.fromCompressedJson([5, -10, null, [1, 2]]),
|
|
305
287
|
new Coordinates(5, -10, null, [1, 2]))
|
|
306
288
|
).true;
|
|
307
289
|
|
|
308
|
-
expect(Coordinates.equals(
|
|
309
|
-
Coordinates.fromCompressedJson([5, -10, 10, '2;3']),
|
|
310
|
-
new Coordinates(5, -10, 10, [2, 3]))
|
|
311
|
-
).true;
|
|
312
|
-
|
|
313
290
|
});
|
|
314
291
|
|
|
315
292
|
});
|
|
@@ -23,7 +23,7 @@ class GeoRef {
|
|
|
23
23
|
const rotationOffset = Quaternion.fromAxisAngle([0, 0, 1], this.heading);
|
|
24
24
|
const enuToEcefRotationOrigin = Quaternion.multiply(rotationOffset, this.origin.enuToEcefRotation);
|
|
25
25
|
const ecefTranslation = Quaternion.rotate(enuToEcefRotationOrigin, enuTranslationScaled);
|
|
26
|
-
const ecef = Vector3.
|
|
26
|
+
const ecef = Vector3.sum(this.origin.ecef, ecefTranslation);
|
|
27
27
|
return Coordinates.fromECEF(ecef);
|
|
28
28
|
}
|
|
29
29
|
|
package/src/coordinates/Level.js
CHANGED
|
@@ -331,20 +331,6 @@ class Level {
|
|
|
331
331
|
|
|
332
332
|
return null;
|
|
333
333
|
}
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* @param {null|{isRange: boolean, val?: number, low?: number, up?: number}} legacyLevel
|
|
337
|
-
* @deprecated
|
|
338
|
-
*/
|
|
339
|
-
static fromLegacy(legacyLevel) {
|
|
340
|
-
if (legacyLevel === null) {
|
|
341
|
-
return null;
|
|
342
|
-
}
|
|
343
|
-
if (legacyLevel.isRange) {
|
|
344
|
-
return [legacyLevel.low, legacyLevel.up];
|
|
345
|
-
}
|
|
346
|
-
return legacyLevel.val;
|
|
347
|
-
}
|
|
348
334
|
}
|
|
349
335
|
|
|
350
336
|
export default Level;
|
|
@@ -225,15 +225,4 @@ describe('Level', () => {
|
|
|
225
225
|
expect(Level.diff([0, 1], [0, 1])).equals(0);
|
|
226
226
|
expect(Level.diff([0, 1], [0, 2])).is.null;
|
|
227
227
|
});
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
it('fromLegacy', () => {
|
|
231
|
-
expect(Level.fromLegacy(null)).is.null;
|
|
232
|
-
expect(Level.fromLegacy({ isRange: false, val: 0 })).equals(0);
|
|
233
|
-
expect(Level.fromLegacy({ isRange: false, val: 6 })).equals(6);
|
|
234
|
-
expect(Level.fromLegacy({ isRange: false, val: -5 })).equals(-5);
|
|
235
|
-
expect(Level.fromLegacy({ isRange: true, low: 0, up: 1 })).deep.equals([0, 1]);
|
|
236
|
-
expect(Level.fromLegacy({ isRange: true, low: -5, up: 5 })).deep.equals([-5, 5]);
|
|
237
|
-
});
|
|
238
|
-
|
|
239
228
|
});
|
package/src/graph/GraphNode.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import Logger from '@wemap/logger';
|
|
2
|
-
|
|
3
1
|
import Coordinates from '../coordinates/Coordinates.js';
|
|
4
2
|
import Level from '../coordinates/Level.js';
|
|
5
3
|
|
|
@@ -107,14 +105,12 @@ class GraphNode {
|
|
|
107
105
|
} else {
|
|
108
106
|
tmpLevel = Level.intersection(tmpLevel, edge.level);
|
|
109
107
|
if (tmpLevel === null) {
|
|
110
|
-
|
|
111
|
-
return false;
|
|
108
|
+
throw Error('Something bad happend during parsing: We cannot retrieve node level from adjacent ways: ' + this.coords);
|
|
112
109
|
}
|
|
113
110
|
}
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
this.coords.level = tmpLevel;
|
|
117
|
-
return true;
|
|
118
114
|
}
|
|
119
115
|
|
|
120
116
|
|
|
@@ -124,14 +120,14 @@ class GraphNode {
|
|
|
124
120
|
_inferNodeLevelByRecursion() {
|
|
125
121
|
const { level } = this.coords;
|
|
126
122
|
if (level === null || !Level.isRange(level)) {
|
|
127
|
-
return
|
|
123
|
+
return;
|
|
128
124
|
}
|
|
129
125
|
|
|
130
126
|
/**
|
|
131
127
|
* We can infer node level only if this one have one edge attached
|
|
132
128
|
*/
|
|
133
129
|
if (this.edges.length > 1) {
|
|
134
|
-
return
|
|
130
|
+
return;
|
|
135
131
|
}
|
|
136
132
|
|
|
137
133
|
/**
|
|
@@ -169,13 +165,10 @@ class GraphNode {
|
|
|
169
165
|
if (othersLevels !== null) {
|
|
170
166
|
if (!Level.isRange(othersLevels)) {
|
|
171
167
|
this.coords.level = othersLevels === level[0] ? level[1] : level[0];
|
|
172
|
-
return
|
|
168
|
+
return;
|
|
173
169
|
}
|
|
174
|
-
|
|
175
|
-
return false;
|
|
170
|
+
throw Error('Level of: ' + this.coords.toString() + ' cannot be decided');
|
|
176
171
|
}
|
|
177
|
-
|
|
178
|
-
return true;
|
|
179
172
|
}
|
|
180
173
|
|
|
181
174
|
/**
|
|
@@ -215,23 +208,17 @@ class GraphNode {
|
|
|
215
208
|
* @param {GraphNode[]} nodes
|
|
216
209
|
*/
|
|
217
210
|
static generateNodesLevels(nodes) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
211
|
+
|
|
212
|
+
nodes.forEach(node => node._generateLevelFromEdges());
|
|
222
213
|
|
|
223
214
|
// In some cases, node levels cannot be retrieve just using adjacent edges
|
|
224
215
|
// (e.g stairs without network at one of its bounds)
|
|
225
216
|
// To infer this node level, we use inferNodeLevelByRecursion()
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
&& node._inferNodeLevelByRecursion()
|
|
229
|
-
, true);
|
|
217
|
+
nodes.forEach(node => node._inferNodeLevelByNeighboors());
|
|
218
|
+
nodes.forEach(node => node._inferNodeLevelByRecursion());
|
|
230
219
|
|
|
231
220
|
// Finally define nodes that are links between indoor and outdoor
|
|
232
221
|
nodes.forEach(node => node._checkIO());
|
|
233
|
-
|
|
234
|
-
return res;
|
|
235
222
|
}
|
|
236
223
|
}
|
|
237
224
|
|
|
@@ -86,23 +86,23 @@ describe('GraphNode', () => {
|
|
|
86
86
|
*/
|
|
87
87
|
|
|
88
88
|
nodes = cleanNodesWithAdjEdges(1, 0);
|
|
89
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
89
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).throw(Error);
|
|
90
90
|
expect(nodes[0].coords.level).is.null;
|
|
91
91
|
|
|
92
92
|
nodes = cleanNodesWithAdjEdges(1, 1);
|
|
93
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
93
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
94
94
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
95
95
|
|
|
96
96
|
nodes = cleanNodesWithAdjEdges(1, [1, 2]);
|
|
97
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
97
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
98
98
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
99
99
|
|
|
100
100
|
nodes = cleanNodesWithAdjEdges([0, 1], [1, 2]);
|
|
101
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
101
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
102
102
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
103
103
|
|
|
104
104
|
nodes = cleanNodesWithAdjEdges([0, 1]);
|
|
105
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
105
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
106
106
|
expect(Level.equals(nodes[0].coords.level, [0, 1])).true;
|
|
107
107
|
|
|
108
108
|
/**
|
|
@@ -113,7 +113,7 @@ describe('GraphNode', () => {
|
|
|
113
113
|
new GraphEdge(nodes[0], nodes[1], 1, 'e0');
|
|
114
114
|
new GraphEdge(nodes[1], nodes[2], [1, 2], 'e1');
|
|
115
115
|
new GraphEdge(nodes[2], nodes[3], [1, 2], 'e2');
|
|
116
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
116
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
117
117
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
118
118
|
expect(Level.equals(nodes[1].coords.level, 1)).true;
|
|
119
119
|
expect(Level.equals(nodes[2].coords.level, [1, 2])).true;
|
|
@@ -125,14 +125,14 @@ describe('GraphNode', () => {
|
|
|
125
125
|
new GraphEdge(nodes[1], nodes[2], [1, 2], 'e1');
|
|
126
126
|
new GraphEdge(nodes[2], nodes[3], [1, 2], 'e2');
|
|
127
127
|
new GraphEdge(nodes[2], nodes[4], null, 'e3');
|
|
128
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
128
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
129
129
|
|
|
130
130
|
|
|
131
131
|
nodes = cleanNodes(4);
|
|
132
132
|
new GraphEdge(nodes[0], nodes[1], 1, 'e0');
|
|
133
133
|
new GraphEdge(nodes[1], nodes[2], [0, 1], 'e1');
|
|
134
134
|
new GraphEdge(nodes[2], nodes[3], [0, 1], 'e2');
|
|
135
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
135
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
136
136
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
137
137
|
expect(Level.equals(nodes[1].coords.level, 1)).true;
|
|
138
138
|
expect(Level.equals(nodes[2].coords.level, [0, 1])).true;
|
|
@@ -144,7 +144,7 @@ describe('GraphNode', () => {
|
|
|
144
144
|
new GraphEdge(nodes[1], nodes[2], [1, 2], 'e1');
|
|
145
145
|
new GraphEdge(nodes[2], nodes[3], [1, 2], 'e2');
|
|
146
146
|
new GraphEdge(nodes[1], nodes[3], 1, 'e3');
|
|
147
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
147
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
148
148
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
149
149
|
expect(Level.equals(nodes[1].coords.level, 1)).true;
|
|
150
150
|
expect(Level.equals(nodes[2].coords.level, 2)).true;
|
|
@@ -156,7 +156,7 @@ describe('GraphNode', () => {
|
|
|
156
156
|
new GraphEdge(nodes[1], nodes[2], [0, 1], 'e1');
|
|
157
157
|
new GraphEdge(nodes[2], nodes[3], [0, 1], 'e2');
|
|
158
158
|
new GraphEdge(nodes[1], nodes[3], 1, 'e3');
|
|
159
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
159
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
160
160
|
expect(Level.equals(nodes[0].coords.level, 1)).true;
|
|
161
161
|
expect(Level.equals(nodes[1].coords.level, 1)).true;
|
|
162
162
|
expect(Level.equals(nodes[2].coords.level, 0)).true;
|
|
@@ -169,7 +169,7 @@ describe('GraphNode', () => {
|
|
|
169
169
|
new GraphEdge(nodes[2], nodes[3], [1, 2], 'e2');
|
|
170
170
|
new GraphEdge(nodes[2], nodes[4], [1, 2], 'e3');
|
|
171
171
|
new GraphEdge(nodes[4], nodes[5], 2, 'e4');
|
|
172
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
172
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).throw(Error);
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
nodes = cleanNodes(5);
|
|
@@ -177,7 +177,7 @@ describe('GraphNode', () => {
|
|
|
177
177
|
new GraphEdge(nodes[1], nodes[2], [1, 2]);
|
|
178
178
|
new GraphEdge(nodes[2], nodes[3], [1, 2]);
|
|
179
179
|
new GraphEdge(nodes[3], nodes[4], 1);
|
|
180
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
180
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
181
181
|
expect(Level.equals(nodes[0].coords.level, 2)).true;
|
|
182
182
|
expect(Level.equals(nodes[1].coords.level, [1, 2])).true;
|
|
183
183
|
expect(Level.equals(nodes[2].coords.level, [1, 2])).true;
|
|
@@ -191,7 +191,7 @@ describe('GraphNode', () => {
|
|
|
191
191
|
new GraphEdge(nodes[2], nodes[3], [0, 1], 'e2');
|
|
192
192
|
new GraphEdge(nodes[3], nodes[4], [0, 1], 'e3');
|
|
193
193
|
new GraphEdge(nodes[4], nodes[5], 1, 'e4');
|
|
194
|
-
expect(GraphNode.generateNodesLevels(nodes)).
|
|
194
|
+
expect(() => GraphNode.generateNodesLevels(nodes)).not.throw(Error);
|
|
195
195
|
expect(Level.equals(nodes[1].coords.level, 0)).true;
|
|
196
196
|
expect(Level.equals(nodes[1].coords.level, 0)).true;
|
|
197
197
|
expect(Level.equals(nodes[2].coords.level, [0, 1])).true;
|
package/src/graph/Network.js
CHANGED
|
@@ -161,8 +161,15 @@ class Network {
|
|
|
161
161
|
|
|
162
162
|
const network = new Network();
|
|
163
163
|
|
|
164
|
-
const getOrCreateNode = coords =>
|
|
165
|
-
network.nodes.find(
|
|
164
|
+
const getOrCreateNode = coords => {
|
|
165
|
+
const node = network.nodes.find(otherNode => otherNode.coords.equals(coords));
|
|
166
|
+
if (node) {
|
|
167
|
+
return node;
|
|
168
|
+
}
|
|
169
|
+
const newNode = new GraphNode(coords);
|
|
170
|
+
network.nodes.push(newNode);
|
|
171
|
+
return newNode;
|
|
172
|
+
};
|
|
166
173
|
|
|
167
174
|
|
|
168
175
|
const createEdgeFromNodes = (node1, node2) =>
|
|
@@ -179,7 +186,6 @@ class Network {
|
|
|
179
186
|
network.edges.push(edge);
|
|
180
187
|
}
|
|
181
188
|
|
|
182
|
-
network.nodes.push(currentNode);
|
|
183
189
|
previousNode = currentNode;
|
|
184
190
|
}
|
|
185
191
|
}
|
|
@@ -187,6 +187,30 @@ class Attitude {
|
|
|
187
187
|
clone() {
|
|
188
188
|
return new Attitude(this.quaternion.slice(0), this.time, this.accuracy);
|
|
189
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Calculate the relative attitude between two given attitudes
|
|
193
|
+
* @param {Attitude} attitudeStart
|
|
194
|
+
* @param {Attitude} attitudeEnd
|
|
195
|
+
* @returns {Attitude}
|
|
196
|
+
*/
|
|
197
|
+
static diff(attitudeStart, attitudeEnd) {
|
|
198
|
+
|
|
199
|
+
const quaternionDiff = Quaternion.multiply(
|
|
200
|
+
Quaternion.inverse(attitudeStart.quaternion),
|
|
201
|
+
attitudeEnd.quaternion
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
const timeDiff = attitudeEnd.time - attitudeStart.time;
|
|
205
|
+
|
|
206
|
+
let accuracyDiff = null;
|
|
207
|
+
if (attitudeStart.accuracy !== null && attitudeEnd.accuracy !== null) {
|
|
208
|
+
// Approximation
|
|
209
|
+
accuracyDiff = Math.max(attitudeEnd.accuracy - attitudeStart.accuracy);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return new Attitude(quaternionDiff, timeDiff, accuracyDiff);
|
|
213
|
+
}
|
|
190
214
|
}
|
|
191
215
|
|
|
192
216
|
export default Attitude;
|
|
@@ -230,19 +230,19 @@ describe('Attitude', () => {
|
|
|
230
230
|
expect(attitude.equals(Attitude.fromJson(attitude.toJson()))).true;
|
|
231
231
|
|
|
232
232
|
attitude = new Attitude([1, 0, 0, 0], 2);
|
|
233
|
-
expect(attitude.toJson()).deep.equals({q: [1, 0, 0, 0], time: 2});
|
|
233
|
+
expect(attitude.toJson()).deep.equals({ q: [1, 0, 0, 0], time: 2 });
|
|
234
234
|
attitudeBis = Attitude.fromJson(attitude.toJson());
|
|
235
235
|
expect(attitude.equals(attitudeBis)).true;
|
|
236
236
|
expect(attitudeBis.time).equals(2);
|
|
237
237
|
|
|
238
238
|
attitude = new Attitude([1, 0, 0, 0], null, 3);
|
|
239
|
-
expect(attitude.toJson()).deep.equals({q: [1, 0, 0, 0], accuracy: 3});
|
|
239
|
+
expect(attitude.toJson()).deep.equals({ q: [1, 0, 0, 0], accuracy: 3 });
|
|
240
240
|
attitudeBis = Attitude.fromJson(attitude.toJson());
|
|
241
241
|
expect(attitude.equals(attitudeBis)).true;
|
|
242
242
|
expect(attitudeBis.accuracy).equals(3);
|
|
243
243
|
|
|
244
244
|
attitude = new Attitude([1, 0, 0, 0], 2, 3);
|
|
245
|
-
expect(attitude.toJson()).deep.equals({q: [1, 0, 0, 0], time: 2, accuracy: 3});
|
|
245
|
+
expect(attitude.toJson()).deep.equals({ q: [1, 0, 0, 0], time: 2, accuracy: 3 });
|
|
246
246
|
attitudeBis = Attitude.fromJson(attitude.toJson());
|
|
247
247
|
expect(attitude.equals(attitudeBis)).true;
|
|
248
248
|
expect(attitudeBis.time).equals(2);
|
|
@@ -250,4 +250,34 @@ describe('Attitude', () => {
|
|
|
250
250
|
|
|
251
251
|
});
|
|
252
252
|
|
|
253
|
+
it('diff', () => {
|
|
254
|
+
|
|
255
|
+
let startAttitude, endAttitude, diffAttitude;
|
|
256
|
+
|
|
257
|
+
startAttitude = new Attitude(LAYED_PORTRAIT_NORTH, 0, 0);
|
|
258
|
+
endAttitude = new Attitude(LAYED_PORTRAIT_EAST, 2, Math.PI / 4);
|
|
259
|
+
diffAttitude = Attitude.diff(startAttitude, endAttitude);
|
|
260
|
+
checkAngles(diffAttitude.heading, Math.PI / 2);
|
|
261
|
+
expect(Quaternion.equals(diffAttitude.quaternion, Quaternion.fromAxisAngle([0, 0, 1], -Math.PI / 2))).true;
|
|
262
|
+
expect(diffAttitude.time).equals(2);
|
|
263
|
+
expect(diffAttitude.accuracy).equals(Math.PI / 4);
|
|
264
|
+
|
|
265
|
+
endAttitude = new Attitude(LAYED_PORTRAIT_SOUTH);
|
|
266
|
+
diffAttitude = Attitude.diff(startAttitude, endAttitude);
|
|
267
|
+
checkAngles(diffAttitude.heading, Math.PI);
|
|
268
|
+
expect(Quaternion.equals(diffAttitude.quaternion, Quaternion.fromAxisAngle([0, 0, 1], Math.PI))).true;
|
|
269
|
+
|
|
270
|
+
endAttitude = new Attitude(STAND_PORTRAIT_NORTH);
|
|
271
|
+
diffAttitude = Attitude.diff(startAttitude, endAttitude);
|
|
272
|
+
checkAngles(diffAttitude.heading, 0);
|
|
273
|
+
expect(Quaternion.equals(diffAttitude.quaternion, Quaternion.fromAxisAngle([1, 0, 0], Math.PI / 2))).true;
|
|
274
|
+
|
|
275
|
+
startAttitude = new Attitude(STAND_PORTRAIT_SOUTH);
|
|
276
|
+
endAttitude = new Attitude(STAND_PORTRAIT_EAST);
|
|
277
|
+
diffAttitude = Attitude.diff(startAttitude, endAttitude);
|
|
278
|
+
checkAngles(diffAttitude.heading, -Math.PI / 2);
|
|
279
|
+
expect(Quaternion.equals(diffAttitude.quaternion, Quaternion.fromAxisAngle([0, 1, 0], Math.PI / 2))).true;
|
|
280
|
+
|
|
281
|
+
});
|
|
282
|
+
|
|
253
283
|
});
|