@wemap/providers 9.2.0 → 10.0.0-alpha.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.
- package/dist/wemap-providers.es.js +5284 -0
- package/dist/wemap-providers.es.js.map +1 -0
- package/index.d.ts +68 -9
- package/index.js +5 -5
- package/package.json +9 -9
- package/src/mapmatching/MapMatchingHandler.js +18 -149
- package/src/providers/position/absolute/AbsolutePosition.js +16 -68
- package/src/providers/position/absolute/PoleStar.js +1 -2
- package/src/providers/steps/StepDetector.js +2 -46
- package/src/providers/steps/StraightLineDetector.js +3 -14
- package/src/providers/vision/{ImageRelocalization.js → vps/ImageRelocalization.js} +15 -39
- package/src/providers/vision/{Vps.js → vps/Vps.js} +10 -64
- package/src/providers/vision/{VpsMetadata.js → vps/VpsMetadata.js} +16 -17
- package/src/providers/vision/vps/VpsRequest.js +29 -0
- package/src/providers/vision/vps/VpsResponse.js +23 -0
- package/src/mapmatching/MapMatchingHandler.spec.js +0 -136
- package/src/providers/steps/StepDetectionMinMaxPeaks3.js +0 -201
- package/src/providers/steps/StepDetectorLadetto.js +0 -108
- package/src/providers/steps/StepDetectorMinMaxPeaks.js +0 -108
- package/src/providers/steps/StepDetectorMinMaxPeaks2.js +0 -108
- package/src/providers/steps/StepDetectorMinMaxPeaks3.js +0 -108
- /package/src/providers/vision/{VpsSchema.json → vps/VpsSchema.json} +0 -0
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import UAParser from 'ua-parser-js';
|
|
2
|
+
|
|
1
3
|
import { CameraUtils } from '@wemap/camera';
|
|
2
4
|
import { Attitude, Coordinates, UserPosition } from '@wemap/geo';
|
|
3
5
|
import Logger from '@wemap/logger';
|
|
4
6
|
import { TimeUtils } from '@wemap/utils';
|
|
5
7
|
|
|
6
|
-
import
|
|
8
|
+
import VpsRequest from './VpsRequest.js';
|
|
9
|
+
import VpsResponse from './VpsResponse.js';
|
|
7
10
|
|
|
8
11
|
class ImageRelocalization {
|
|
9
12
|
|
|
@@ -11,49 +14,24 @@ class ImageRelocalization {
|
|
|
11
14
|
* @param {HTMLCanvasElement} imageCanvas
|
|
12
15
|
* @param {{intrinsic:number[], distortions:number[]}} calibration
|
|
13
16
|
* @param {{position: Coordinates, positionAccuracy: number}} coarsePose
|
|
14
|
-
* @returns {
|
|
17
|
+
* @returns {VpsRequest}
|
|
15
18
|
*/
|
|
16
19
|
static _prepareRequest(imageCanvas, calibration, coarsePose) {
|
|
17
|
-
const
|
|
20
|
+
const request = new VpsRequest();
|
|
21
|
+
const { metadata } = request;
|
|
22
|
+
|
|
23
|
+
metadata.time = TimeUtils.preciseTime() / 1e3;
|
|
18
24
|
|
|
19
25
|
CameraUtils.convertToGrayscale(imageCanvas);
|
|
20
26
|
const reducedImage = CameraUtils.reduceImageSize(imageCanvas, 1280);
|
|
21
|
-
|
|
27
|
+
request.image = reducedImage;
|
|
22
28
|
|
|
23
|
-
const metadata = new VpsMetadata();
|
|
24
|
-
metadata.time = requestTime;
|
|
25
29
|
metadata.size = { width: reducedImage.width, height: reducedImage.height };
|
|
26
30
|
metadata.calibration = calibration;
|
|
27
31
|
metadata.coarse = coarsePose;
|
|
32
|
+
metadata.userAgent = (new UAParser()).getResult();
|
|
28
33
|
|
|
29
|
-
return
|
|
30
|
-
image: base64Image,
|
|
31
|
-
...metadata.toJson()
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {object} json
|
|
37
|
-
* @returns {{userPosition: UserPosition, attitude: Attitude}}
|
|
38
|
-
*/
|
|
39
|
-
static _parseJsonResponse(json, requestTime = null) {
|
|
40
|
-
|
|
41
|
-
const attitude = new Attitude([
|
|
42
|
-
json.attitude.w, json.attitude.x,
|
|
43
|
-
json.attitude.y, json.attitude.z
|
|
44
|
-
], requestTime, 0);
|
|
45
|
-
|
|
46
|
-
const userPosition = new UserPosition(
|
|
47
|
-
json.coordinates.lat,
|
|
48
|
-
json.coordinates.lng,
|
|
49
|
-
json.coordinates.alt,
|
|
50
|
-
typeof json.coordinates.level === 'undefined' ? null : json.coordinates.level,
|
|
51
|
-
requestTime,
|
|
52
|
-
0,
|
|
53
|
-
attitude.heading
|
|
54
|
-
);
|
|
55
|
-
|
|
56
|
-
return { userPosition, attitude };
|
|
34
|
+
return request;
|
|
57
35
|
}
|
|
58
36
|
|
|
59
37
|
/**
|
|
@@ -66,14 +44,14 @@ class ImageRelocalization {
|
|
|
66
44
|
static async relocalize(endpointUrl, imageCanvas, calibration = null, coarsePose = null) {
|
|
67
45
|
|
|
68
46
|
// 1. Prepare the request
|
|
69
|
-
const
|
|
47
|
+
const vpsRequest = this._prepareRequest(imageCanvas, calibration, coarsePose);
|
|
70
48
|
|
|
71
49
|
// 2. Send the request
|
|
72
50
|
let serverResponse;
|
|
73
51
|
try {
|
|
74
52
|
serverResponse = await fetch(endpointUrl, {
|
|
75
53
|
method: 'POST',
|
|
76
|
-
body: JSON.stringify(
|
|
54
|
+
body: JSON.stringify(vpsRequest.toJson()),
|
|
77
55
|
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }
|
|
78
56
|
});
|
|
79
57
|
} catch (e) {
|
|
@@ -91,9 +69,7 @@ class ImageRelocalization {
|
|
|
91
69
|
}
|
|
92
70
|
|
|
93
71
|
// 3. Parse the response
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return { userPosition, attitude };
|
|
72
|
+
return VpsResponse.fromJson(json);
|
|
97
73
|
}
|
|
98
74
|
|
|
99
75
|
static getHeadingFromQuaternion(quaternion) {
|
|
@@ -5,20 +5,15 @@ import Logger from '@wemap/logger';
|
|
|
5
5
|
import { Quaternion, deg2rad } from '@wemap/maths';
|
|
6
6
|
import { TimeUtils } from '@wemap/utils';
|
|
7
7
|
|
|
8
|
-
import EventType from '
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import ProviderState from '../ProviderState.js';
|
|
8
|
+
import EventType from '../../../events/EventType.js';
|
|
9
|
+
import Provider from '../../Provider.js';
|
|
10
|
+
import ProviderState from '../../ProviderState.js';
|
|
12
11
|
import ImageRelocalization from './ImageRelocalization.js';
|
|
13
12
|
|
|
14
13
|
class Vps extends Provider {
|
|
15
14
|
|
|
16
15
|
static MIN_TIME_BETWEEN_TWO_REQUESTS = 1000;
|
|
17
16
|
|
|
18
|
-
static DEFAULT_MIN_INCLINATION_FOR_REQUEST = deg2rad(60);
|
|
19
|
-
|
|
20
|
-
static DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST = 200;
|
|
21
|
-
|
|
22
17
|
static CAMERA_TO_SMARTPHONE_ROT = Quaternion.fromAxisAngle([1, 0, 0], Math.PI);
|
|
23
18
|
|
|
24
19
|
/** @type {boolean} */
|
|
@@ -33,14 +28,6 @@ class Vps extends Provider {
|
|
|
33
28
|
/** @type {?string} */
|
|
34
29
|
_endpoint = null;
|
|
35
30
|
|
|
36
|
-
/** @type {?number} */
|
|
37
|
-
_inclinationProviderId = null;
|
|
38
|
-
|
|
39
|
-
/** @type {number} */
|
|
40
|
-
_minInclinationForRequest = Vps.DEFAULT_MIN_INCLINATION_FOR_REQUEST;
|
|
41
|
-
|
|
42
|
-
/** @type {number} */
|
|
43
|
-
_waitTimeMinInclinationForRequest = Vps.DEFAULT_WAIT_TIME_MIN_INCLINATION_FOR_REQUEST;
|
|
44
31
|
|
|
45
32
|
/**
|
|
46
33
|
* @override
|
|
@@ -80,9 +67,6 @@ class Vps extends Provider {
|
|
|
80
67
|
}
|
|
81
68
|
this._useCamera(SharedCameras.list[0].camera);
|
|
82
69
|
}
|
|
83
|
-
|
|
84
|
-
// 3. Inclination
|
|
85
|
-
this._inclinationProviderId = Inclination.addEventListener();
|
|
86
70
|
}
|
|
87
71
|
|
|
88
72
|
/**
|
|
@@ -93,8 +77,13 @@ class Vps extends Provider {
|
|
|
93
77
|
SharedCameras.off('removed', this._onCameraRemoved);
|
|
94
78
|
|
|
95
79
|
this._camera = null;
|
|
80
|
+
}
|
|
96
81
|
|
|
97
|
-
|
|
82
|
+
/**
|
|
83
|
+
* @param {string} endpoint
|
|
84
|
+
*/
|
|
85
|
+
setEndpoint(endpoint) {
|
|
86
|
+
this._endpoint = endpoint;
|
|
98
87
|
}
|
|
99
88
|
|
|
100
89
|
_onCameraDetected = ({ camera }) => {
|
|
@@ -153,14 +142,6 @@ class Vps extends Provider {
|
|
|
153
142
|
break;
|
|
154
143
|
}
|
|
155
144
|
|
|
156
|
-
// 2.a. Do not send an image if smartphone looks at the floor
|
|
157
|
-
const inclination = Inclination.lastEvent ? Inclination.lastEvent.data : null;
|
|
158
|
-
if (inclination !== null
|
|
159
|
-
&& inclination < this._minInclinationForRequest) {
|
|
160
|
-
await new Promise(resolve => setTimeout(resolve, this._waitTimeMinInclinationForRequest));
|
|
161
|
-
continue;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
145
|
// 3. Get current image from camera and relocalize it.
|
|
165
146
|
const image = await this._camera.currentImage;
|
|
166
147
|
const res = await ImageRelocalization.relocalize(this._endpoint, image);
|
|
@@ -182,14 +163,6 @@ class Vps extends Provider {
|
|
|
182
163
|
);
|
|
183
164
|
const attitude = new Attitude(deviceQuaternion, res.attitude.time, res.attitude.accuracy);
|
|
184
165
|
|
|
185
|
-
// [16/06/22] Force VPS accuracy to 5m if the information does not exist
|
|
186
|
-
// this allows to correctly fuse positions from different providers (VPS,
|
|
187
|
-
// GnssWifi, Pole Star...)
|
|
188
|
-
const devicePosition = res.userPosition.clone();
|
|
189
|
-
if (devicePosition.accuracy === null) {
|
|
190
|
-
devicePosition.accuracy = 5;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
166
|
// 5. Finally, notify the listeners if the VPS is not stopped
|
|
194
167
|
if (this.state === ProviderState.STOPPED) {
|
|
195
168
|
break;
|
|
@@ -197,7 +170,7 @@ class Vps extends Provider {
|
|
|
197
170
|
|
|
198
171
|
this.notify(
|
|
199
172
|
this.createEvent(EventType.AbsoluteAttitude, attitude),
|
|
200
|
-
this.createEvent(EventType.AbsolutePosition,
|
|
173
|
+
this.createEvent(EventType.AbsolutePosition, res.userPosition)
|
|
201
174
|
);
|
|
202
175
|
|
|
203
176
|
}
|
|
@@ -206,33 +179,6 @@ class Vps extends Provider {
|
|
|
206
179
|
_internalStop = () => {
|
|
207
180
|
// do nothing
|
|
208
181
|
}
|
|
209
|
-
|
|
210
|
-
get endpoint() {
|
|
211
|
-
return this._endpoint;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* @param {string} endpoint
|
|
216
|
-
*/
|
|
217
|
-
set endpoint(endpoint) {
|
|
218
|
-
this._endpoint = endpoint;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
get minInclinationForRequest() {
|
|
222
|
-
return this._minInclinationForRequest;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
set minInclinationForRequest(minInclinationForRequest) {
|
|
226
|
-
this._minInclinationForRequest = minInclinationForRequest;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
get waitTimeMinInclinationForRequest() {
|
|
230
|
-
return this._waitTimeMinInclinationForRequest;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
set waitTimeMinInclinationForRequest(waitTimeMinInclinationForRequest) {
|
|
234
|
-
this._waitTimeMinInclinationForRequest = waitTimeMinInclinationForRequest;
|
|
235
|
-
}
|
|
236
182
|
}
|
|
237
183
|
|
|
238
184
|
export default new Vps();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Attitude, UserPosition } from '@wemap/geo';
|
|
2
2
|
|
|
3
3
|
class VpsMetadata {
|
|
4
4
|
|
|
@@ -11,11 +11,14 @@ class VpsMetadata {
|
|
|
11
11
|
/** @type {?number} */
|
|
12
12
|
time;
|
|
13
13
|
|
|
14
|
-
/** @type {?{position
|
|
14
|
+
/** @type {?{position?: UserPosition, attitude?: Attitude}} */
|
|
15
15
|
coarse;
|
|
16
16
|
|
|
17
|
+
/** @type {object} */
|
|
18
|
+
userAgent;
|
|
19
|
+
|
|
17
20
|
/**
|
|
18
|
-
* @returns {
|
|
21
|
+
* @returns {VpsMetadata}
|
|
19
22
|
*/
|
|
20
23
|
toJson() {
|
|
21
24
|
const output = { size: [this.size.width, this.size.height] };
|
|
@@ -27,18 +30,16 @@ class VpsMetadata {
|
|
|
27
30
|
}
|
|
28
31
|
if (this.coarse) {
|
|
29
32
|
output.coarse = {};
|
|
30
|
-
|
|
31
33
|
if (this.coarse.attitude) {
|
|
32
|
-
output.coarse.attitude = this.coarse.attitude;
|
|
34
|
+
output.coarse.attitude = this.coarse.attitude.toJson();
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
if (this.coarse.position) {
|
|
36
38
|
output.coarse.position = this.coarse.position.toJson();
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
40
|
+
}
|
|
41
|
+
if (typeof this.userAgent === 'object') {
|
|
42
|
+
output.userAgent = this.userAgent;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
return output;
|
|
@@ -46,7 +47,7 @@ class VpsMetadata {
|
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
49
|
* @param {object} json
|
|
49
|
-
* @returns {
|
|
50
|
+
* @returns {VpsMetadata}
|
|
50
51
|
*/
|
|
51
52
|
static fromJson(json) {
|
|
52
53
|
const output = new VpsMetadata();
|
|
@@ -62,18 +63,16 @@ class VpsMetadata {
|
|
|
62
63
|
}
|
|
63
64
|
if (json.coarse) {
|
|
64
65
|
output.coarse = {};
|
|
65
|
-
|
|
66
66
|
if (json.coarse.attitude) {
|
|
67
|
-
output.coarse.attitude = json.coarse.attitude;
|
|
67
|
+
output.coarse.attitude = Attitude.fromJson(json.coarse.attitude);
|
|
68
68
|
}
|
|
69
|
-
|
|
70
69
|
if (json.coarse.position) {
|
|
71
|
-
output.coarse.position =
|
|
72
|
-
}
|
|
73
|
-
if (json.coarse.positionAccuracy) {
|
|
74
|
-
output.coarse.positionAccuracy = json.coarse.positionAccuracy;
|
|
70
|
+
output.coarse.position = UserPosition.fromJson(json.coarse.position);
|
|
75
71
|
}
|
|
76
72
|
}
|
|
73
|
+
if (typeof json.userAgent === 'object') {
|
|
74
|
+
output.userAgent = json.userAgent;
|
|
75
|
+
}
|
|
77
76
|
return output;
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { CameraUtils } from '@wemap/camera';
|
|
2
|
+
|
|
3
|
+
import VpsMetadata from './VpsMetadata.js';
|
|
4
|
+
|
|
5
|
+
class VpsRequest {
|
|
6
|
+
|
|
7
|
+
/** @type {VpsMetadata} */
|
|
8
|
+
metadata = new VpsMetadata();
|
|
9
|
+
|
|
10
|
+
/** @type {HTMLCanvasElement} */
|
|
11
|
+
image;
|
|
12
|
+
|
|
13
|
+
toJson() {
|
|
14
|
+
const base64Image = CameraUtils.canvasToBase64(this.image);
|
|
15
|
+
return {
|
|
16
|
+
image: base64Image,
|
|
17
|
+
...this.metadata.toJson()
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
static fromJson(json) {
|
|
22
|
+
const vpsRequest = new VpsRequest();
|
|
23
|
+
vpsRequest.metadata = VpsMetadata.fromJson(json);
|
|
24
|
+
vpsRequest.image = CameraUtils.base64ToCanvas(json.image);
|
|
25
|
+
return vpsRequest;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default VpsRequest;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Attitude, UserPosition } from '@wemap/geo';
|
|
2
|
+
|
|
3
|
+
class VpsResponse {
|
|
4
|
+
|
|
5
|
+
/** @type {Attitude} */
|
|
6
|
+
attitude;
|
|
7
|
+
|
|
8
|
+
/** @type {UserPosition} */
|
|
9
|
+
position;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {object} json
|
|
13
|
+
* @returns {VpsResponse}
|
|
14
|
+
*/
|
|
15
|
+
fromJson(json) {
|
|
16
|
+
const response = new VpsResponse();
|
|
17
|
+
response.attitude = Attitude.fromJson(json.attitude);
|
|
18
|
+
response.userPosition = UserPosition.fromJson(json.userPosition);
|
|
19
|
+
return response;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default VpsResponse;
|
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
/* eslint-disable max-statements */
|
|
2
|
-
import chai from 'chai';
|
|
3
|
-
import { Coordinates, Network } from '@wemap/geo';
|
|
4
|
-
import { deg2rad } from '@wemap/maths';
|
|
5
|
-
import { Itinerary } from '@wemap/routers';
|
|
6
|
-
import MMH from './MapMatchingHandler.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const { expect } = chai;
|
|
10
|
-
|
|
11
|
-
describe('MapMatchingHandler', () => {
|
|
12
|
-
|
|
13
|
-
const p0 = new Coordinates(0, 0, null, 0);
|
|
14
|
-
const p1 = p0.destinationPoint(5, 0);
|
|
15
|
-
const p2 = p1.destinationPoint(5, Math.PI / 2);
|
|
16
|
-
const p3 = p1.destinationPoint(10, 0);
|
|
17
|
-
const p4 = p0.destinationPoint(2, deg2rad(10));
|
|
18
|
-
|
|
19
|
-
const pos1 = p0.clone();
|
|
20
|
-
const pos2 = pos1.destinationPoint(3, 0);
|
|
21
|
-
const pos3 = pos2.destinationPoint(10, 0);
|
|
22
|
-
|
|
23
|
-
it('_hasTurnInCircle - itinerary', () => {
|
|
24
|
-
|
|
25
|
-
expect(MMH._hasTurnInCircle(pos1, Number.MAX_VALUE)).is.false;
|
|
26
|
-
|
|
27
|
-
// p4 -> p1 -> p2 is a turn
|
|
28
|
-
MMH.itinerary = Itinerary.fromOrderedCoordinates([p0, p4, p1, p2]);
|
|
29
|
-
|
|
30
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p0))).is.false;
|
|
31
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p1))).is.true;
|
|
32
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p2))).is.false;
|
|
33
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p4))).is.false;
|
|
34
|
-
|
|
35
|
-
expect(MMH._hasTurnInCircle(pos1, 1)).is.false;
|
|
36
|
-
expect(MMH._hasTurnInCircle(pos1, 3)).is.false;
|
|
37
|
-
expect(MMH._hasTurnInCircle(pos1, 10)).is.true;
|
|
38
|
-
expect(MMH._hasTurnInCircle(pos2, 1)).is.false;
|
|
39
|
-
expect(MMH._hasTurnInCircle(pos2, 3)).is.true;
|
|
40
|
-
expect(MMH._hasTurnInCircle(pos2, 10)).is.true;
|
|
41
|
-
expect(MMH._hasTurnInCircle(pos3, 1)).is.false;
|
|
42
|
-
expect(MMH._hasTurnInCircle(pos3, 3)).is.false;
|
|
43
|
-
expect(MMH._hasTurnInCircle(pos3, 10)).is.true;
|
|
44
|
-
|
|
45
|
-
// Straight line
|
|
46
|
-
MMH.itinerary = Itinerary.fromOrderedCoordinates([p0, p4, p1, p3]);
|
|
47
|
-
|
|
48
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p1))).is.false;
|
|
49
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p4))).is.false;
|
|
50
|
-
|
|
51
|
-
expect(MMH._hasTurnInCircle(pos1, 10)).is.false;
|
|
52
|
-
expect(MMH._hasTurnInCircle(pos2, 10)).is.false;
|
|
53
|
-
expect(MMH._hasTurnInCircle(pos3, 10)).is.false;
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
it('_hasTurnInCircle - network', () => {
|
|
59
|
-
|
|
60
|
-
// p1 has turns
|
|
61
|
-
MMH.network = Network.fromCoordinates([[p0, p4, p1], [p1, p2], [p3, p1]]);
|
|
62
|
-
|
|
63
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p1))).is.true;
|
|
64
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p4))).is.false;
|
|
65
|
-
|
|
66
|
-
expect(MMH._hasTurnInCircle(pos1, 1)).is.false;
|
|
67
|
-
expect(MMH._hasTurnInCircle(pos1, 3)).is.false;
|
|
68
|
-
expect(MMH._hasTurnInCircle(pos1, 10)).is.true;
|
|
69
|
-
expect(MMH._hasTurnInCircle(pos2, 1)).is.false;
|
|
70
|
-
expect(MMH._hasTurnInCircle(pos2, 3)).is.true;
|
|
71
|
-
expect(MMH._hasTurnInCircle(pos2, 10)).is.true;
|
|
72
|
-
expect(MMH._hasTurnInCircle(pos3, 1)).is.false;
|
|
73
|
-
expect(MMH._hasTurnInCircle(pos3, 3)).is.false;
|
|
74
|
-
expect(MMH._hasTurnInCircle(pos3, 10)).is.true;
|
|
75
|
-
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
const p10 = new Coordinates(0, 0, null, 1);
|
|
79
|
-
const p11 = p10.destinationPoint(5, 0);
|
|
80
|
-
const p12 = p11.destinationPoint(5, Math.PI / 2);
|
|
81
|
-
const p13 = p11.destinationPoint(10, 0);
|
|
82
|
-
|
|
83
|
-
const pos12 = p10.clone().destinationPoint(3, 0);
|
|
84
|
-
const pos012 = new Coordinates(0, 0, null, [0, 1]).destinationPoint(3, 0);
|
|
85
|
-
|
|
86
|
-
it('_hasTurnInCircle - multi-levels', () => {
|
|
87
|
-
|
|
88
|
-
// level 1 is a straight line
|
|
89
|
-
MMH.network = Network.fromCoordinates([
|
|
90
|
-
[p0, p4, p1], [p1, p2], [p3, p1],
|
|
91
|
-
[p10, p11, p13]
|
|
92
|
-
]);
|
|
93
|
-
|
|
94
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p1))).is.true;
|
|
95
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p11))).is.false;
|
|
96
|
-
|
|
97
|
-
expect(MMH._hasTurnInCircle(pos2, 1)).is.false;
|
|
98
|
-
expect(MMH._hasTurnInCircle(pos2, 3)).is.true;
|
|
99
|
-
expect(MMH._hasTurnInCircle(pos2, 10)).is.true;
|
|
100
|
-
expect(MMH._hasTurnInCircle(pos12, 1)).is.false;
|
|
101
|
-
expect(MMH._hasTurnInCircle(pos12, 3)).is.false;
|
|
102
|
-
expect(MMH._hasTurnInCircle(pos12, 10)).is.false;
|
|
103
|
-
expect(MMH._hasTurnInCircle(pos012, 1)).is.false;
|
|
104
|
-
expect(MMH._hasTurnInCircle(pos012, 3)).is.true;
|
|
105
|
-
expect(MMH._hasTurnInCircle(pos012, 10)).is.true;
|
|
106
|
-
|
|
107
|
-
// Changing level
|
|
108
|
-
// straight line
|
|
109
|
-
MMH.network = Network.fromCoordinates([
|
|
110
|
-
[p0, p4, p11], [p11, p13]
|
|
111
|
-
]);
|
|
112
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p4))).is.false;
|
|
113
|
-
expect(MMH._hasTurnInCircle(pos2, Number.MAX_VALUE)).is.false;
|
|
114
|
-
expect(MMH._hasTurnInCircle(pos12, Number.MAX_VALUE)).is.false;
|
|
115
|
-
expect(MMH._hasTurnInCircle(pos012, Number.MAX_VALUE)).is.false;
|
|
116
|
-
|
|
117
|
-
// Changing level
|
|
118
|
-
// turn in p11
|
|
119
|
-
MMH.network = Network.fromCoordinates([
|
|
120
|
-
[p0, p4, p11], [p11, p12], [p11, p13]
|
|
121
|
-
]);
|
|
122
|
-
|
|
123
|
-
expect(MMH._nodeHasTurn(MMH.network.getNodeByCoords(p11))).is.true;
|
|
124
|
-
expect(MMH._hasTurnInCircle(pos2, 1)).is.false;
|
|
125
|
-
expect(MMH._hasTurnInCircle(pos2, 3)).is.false;
|
|
126
|
-
expect(MMH._hasTurnInCircle(pos2, 10)).is.false;
|
|
127
|
-
expect(MMH._hasTurnInCircle(pos12, 1)).is.false;
|
|
128
|
-
expect(MMH._hasTurnInCircle(pos12, 3)).is.true;
|
|
129
|
-
expect(MMH._hasTurnInCircle(pos12, 10)).is.true;
|
|
130
|
-
expect(MMH._hasTurnInCircle(pos012, 1)).is.false;
|
|
131
|
-
expect(MMH._hasTurnInCircle(pos012, 3)).is.true;
|
|
132
|
-
expect(MMH._hasTurnInCircle(pos012, 10)).is.true;
|
|
133
|
-
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
});
|