@furkot/directions 2.1.1 → 2.1.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/Readme.md +1 -1
- package/lib/directions.js +38 -33
- package/lib/model.js +20 -16
- package/lib/profile/index.js +15 -0
- package/lib/profile/rv/dimensions.js +24 -0
- package/lib/profile/rv/index.js +71 -0
- package/lib/service/graphhopper/index.js +44 -28
- package/lib/service/index.js +4 -5
- package/lib/service/mapquest/index.js +25 -15
- package/lib/service/openroute/index.js +47 -38
- package/lib/service/osrm/index.js +7 -17
- package/lib/service/partition.js +1 -1
- package/lib/service/simplify.js +7 -5
- package/lib/service/util.js +20 -22
- package/lib/service/valhalla/index.js +43 -38
- package/package.json +8 -8
package/Readme.md
CHANGED
|
@@ -28,7 +28,7 @@ MIT © [Damian Krzeminski](https://pirxpilot.me)
|
|
|
28
28
|
[npm-url]: https://npmjs.org/package/@furkot/directions
|
|
29
29
|
|
|
30
30
|
[build-url]: https://github.com/furkot/directions/actions/workflows/check.yaml
|
|
31
|
-
[build-image]: https://img.shields.io/github/workflow/status/furkot/directions/check
|
|
31
|
+
[build-image]: https://img.shields.io/github/actions/workflow/status/furkot/directions/check.yaml?branch=main
|
|
32
32
|
|
|
33
33
|
[deps-image]: https://img.shields.io/librariesio/release/npm/@furkot/directions
|
|
34
34
|
[deps-url]: https://libraries.io/npm/@furkot%2Fdirections
|
package/lib/directions.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const travelMode = require('./model').travelMode;
|
|
2
|
-
const { defaults
|
|
2
|
+
const { defaults, withTimeout } = require('./service/util');
|
|
3
|
+
const prepareQuery = require('./profile');
|
|
3
4
|
|
|
4
5
|
module.exports = furkotDirections;
|
|
5
6
|
|
|
@@ -41,40 +42,41 @@ const services = {
|
|
|
41
42
|
const defaultTimeout = 20 * 1000;
|
|
42
43
|
|
|
43
44
|
function furkotDirections(options) {
|
|
44
|
-
|
|
45
45
|
options = {
|
|
46
46
|
timeout: defaultTimeout,
|
|
47
47
|
order: ['osrm', 'mapquest', 'valhalla', 'graphhopper', 'openroute'],
|
|
48
48
|
...options
|
|
49
49
|
};
|
|
50
50
|
if (!options.services) {
|
|
51
|
-
options.services = options.order
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
limiter: options[`${name}_limiter`],
|
|
64
|
-
enable,
|
|
65
|
-
skip: service.skip
|
|
66
|
-
};
|
|
67
|
-
if (options[name]) {
|
|
68
|
-
Object.keys(options).reduce(mapOptions, {
|
|
69
|
-
options,
|
|
51
|
+
options.services = options.order
|
|
52
|
+
.map(name => {
|
|
53
|
+
const service = services[options[name] || name];
|
|
54
|
+
if (!service) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const enable = options[`${name}_enable`];
|
|
58
|
+
if (!enable) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// object representing actual parameters for a service
|
|
62
|
+
const serviceOptions = {
|
|
70
63
|
name,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
64
|
+
limiter: options[`${name}_limiter`],
|
|
65
|
+
enable,
|
|
66
|
+
skip: service.skip
|
|
67
|
+
};
|
|
68
|
+
if (options[name]) {
|
|
69
|
+
Object.keys(options).reduce(mapOptions, {
|
|
70
|
+
options,
|
|
71
|
+
name,
|
|
72
|
+
optName: options[name],
|
|
73
|
+
serviceOptions
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// we are adding options that has not been copied to serviceOptions yet
|
|
77
|
+
return service.service(defaults(serviceOptions, options));
|
|
78
|
+
})
|
|
79
|
+
.filter(Boolean);
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
directions.options = options;
|
|
@@ -86,7 +88,7 @@ function furkotDirections(options) {
|
|
|
86
88
|
*/
|
|
87
89
|
function directions(query, { signal } = {}) {
|
|
88
90
|
if (query?.points?.length > 1) {
|
|
89
|
-
return requestDirections(query, options.timeout);
|
|
91
|
+
return requestDirections(prepareQuery(query), options.timeout);
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
async function requestDirections(query, timeout) {
|
|
@@ -111,10 +113,13 @@ function furkotDirections(options) {
|
|
|
111
113
|
break;
|
|
112
114
|
}
|
|
113
115
|
if (query.points.length > 2) {
|
|
114
|
-
return requestDirections(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
return requestDirections(
|
|
117
|
+
{
|
|
118
|
+
...query,
|
|
119
|
+
points: query.points.slice(0, 2)
|
|
120
|
+
},
|
|
121
|
+
timeout
|
|
122
|
+
);
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
return {
|
package/lib/model.js
CHANGED
|
@@ -22,9 +22,7 @@ const directionsQuery = {
|
|
|
22
22
|
avoidHighways: false, // true to avoid highways
|
|
23
23
|
avoidTolls: false, // true to avoid toll roads
|
|
24
24
|
units: 'm', // m - miles, km - kilometers
|
|
25
|
-
points: [
|
|
26
|
-
[0, 0]
|
|
27
|
-
], // array of consecutive series of points; each point is [lon, lat]
|
|
25
|
+
points: [[0, 0]], // array of consecutive series of points; each point is [lon, lat]
|
|
28
26
|
isInChina: false, // points are in China (some services need this information)
|
|
29
27
|
begin: '', // date/time for the begin of route as 'YYYY-MM-DDThh:mm'
|
|
30
28
|
turnbyturn: false, // provide detailed turn-by-turn instructions (segments in directionsResult)
|
|
@@ -39,19 +37,25 @@ const directionsResult = {
|
|
|
39
37
|
query: directionsQuery, // query parameters
|
|
40
38
|
places: [], // addresses or place names corresponding to points (if directions service performs reverse geocoding)
|
|
41
39
|
name: '', // human-readable name of directions (if available)
|
|
42
|
-
routes: [
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
40
|
+
routes: [
|
|
41
|
+
{
|
|
42
|
+
// routes; one for each point with a successor in the query.points
|
|
43
|
+
duration: 0, // route duration in seconds
|
|
44
|
+
distance: 0, // route distance in meters
|
|
45
|
+
path: [], // simplified series of interim points; each point is [lon, lat]
|
|
46
|
+
seasonal: false, // indicates a road that is seasonally closed
|
|
47
|
+
segmentIndex: 0 // index of the turn-by-turn directions segment
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
segments: [
|
|
51
|
+
{
|
|
52
|
+
// turn-by-turn directions
|
|
53
|
+
duration: 0, // segment duration in seconds
|
|
54
|
+
distance: 0, // segment distance in meters
|
|
55
|
+
path: [], // series of interim points; each point is [lon, lat]
|
|
56
|
+
instructions: '' // textual instructions for this segment
|
|
57
|
+
}
|
|
58
|
+
],
|
|
55
59
|
stats: [], // list of providers that requests have been sent to to obtain directions
|
|
56
60
|
provider: '' // identifies service providing the directions
|
|
57
61
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
const profiles = {
|
|
2
|
+
5: require('./rv')
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
module.exports = prepareQuery;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Prepares query depending on the mode.
|
|
9
|
+
* @param {Object} query - The query object.
|
|
10
|
+
* @returns {Object} The prepared query.
|
|
11
|
+
*/
|
|
12
|
+
function prepareQuery(query) {
|
|
13
|
+
const { mode } = query;
|
|
14
|
+
return profiles[mode]?.(query) || query;
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default RV dimensions based on Valhalla defaults for truck:
|
|
3
|
+
* https://valhalla.github.io/valhalla/api/turn-by-turn/api-reference/#automobile-and-bus-costing-options
|
|
4
|
+
*/
|
|
5
|
+
const defaultRV = {
|
|
6
|
+
axle_load: 9.07,
|
|
7
|
+
hazmat: true,
|
|
8
|
+
height: 4.11,
|
|
9
|
+
length: 21.64,
|
|
10
|
+
weight: 21.77,
|
|
11
|
+
width: 2.6
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const passengerCar = {
|
|
15
|
+
height: 3.8,
|
|
16
|
+
length: 8,
|
|
17
|
+
weight: 6,
|
|
18
|
+
width: 2.5
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
module.exports = {
|
|
22
|
+
defaultRV,
|
|
23
|
+
passengerCar
|
|
24
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const { passengerCar, defaultRV } = require('./dimensions');
|
|
2
|
+
const passengerCarEntries = Object.entries(passengerCar);
|
|
3
|
+
|
|
4
|
+
module.exports = prepareQuery;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Treat RV as passenger car when it doesn't carry hazmat and all its dimensions
|
|
8
|
+
* that are present fall within the passenger car limits.
|
|
9
|
+
* @param {Object} vehicle - The vehicle object.
|
|
10
|
+
* @returns {boolean} Whether to treat RV as passenger car.
|
|
11
|
+
*/
|
|
12
|
+
function isPassengerCar(vehicle) {
|
|
13
|
+
return !vehicle.hazmat && passengerCarEntries.every(([k, v]) => vehicle[k] <= v);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Treat RV as non commercial truck when it doesn't carry hazmat and its
|
|
18
|
+
* weight and length are below truck limits.
|
|
19
|
+
* @param {Object} vehicle - The vehicle object.
|
|
20
|
+
* @returns {boolean} Whether to treat RV as non commercial truck.
|
|
21
|
+
*/
|
|
22
|
+
function isNonCommercialTruck(vehicle) {
|
|
23
|
+
return !vehicle.hazmat && vehicle.length < defaultRV.length && vehicle.weight < defaultRV.weight;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Prepares vehicle size for the query.
|
|
28
|
+
* @param {Object} query - The query object.
|
|
29
|
+
* @returns {Object} The prepared query with vehicle size.
|
|
30
|
+
*/
|
|
31
|
+
function prepareVehicle(vehicle) {
|
|
32
|
+
if (!vehicle) {
|
|
33
|
+
// treat as a standard truck
|
|
34
|
+
return {
|
|
35
|
+
vehicle: defaultRV
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (isPassengerCar(vehicle)) {
|
|
39
|
+
// treat as a regular passenger car
|
|
40
|
+
return {
|
|
41
|
+
mode: 0
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
vehicle = Object.assign({}, defaultRV, vehicle);
|
|
45
|
+
let proposedMode;
|
|
46
|
+
if (isNonCommercialTruck(vehicle)) {
|
|
47
|
+
// treat as a passenger car if at least height and width can be enforced
|
|
48
|
+
proposedMode = 0;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
proposedMode,
|
|
52
|
+
vehicle
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Prepares query.
|
|
58
|
+
* @param {Object} query - The query object.
|
|
59
|
+
* @returns {Object} The prepared query.
|
|
60
|
+
*/
|
|
61
|
+
function prepareQuery(query) {
|
|
62
|
+
const { mode: initialMode, vehicle: initialVehicle } = query;
|
|
63
|
+
return Object.assign(
|
|
64
|
+
{
|
|
65
|
+
initialMode,
|
|
66
|
+
initialVehicle
|
|
67
|
+
},
|
|
68
|
+
query,
|
|
69
|
+
prepareVehicle(query.vehicle)
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// https://docs.graphhopper.com/#tag/Routing-API
|
|
2
2
|
// https://github.com/boldtrn/kurviger-api-documentation
|
|
3
3
|
|
|
4
|
-
const { pathType, travelMode } = require(
|
|
4
|
+
const { pathType, travelMode } = require('../../model');
|
|
5
5
|
const status = require('../status');
|
|
6
6
|
const tagRoute = require('../tag-route');
|
|
7
7
|
const util = require('../util');
|
|
@@ -9,12 +9,11 @@ const util = require('../util');
|
|
|
9
9
|
module.exports = init;
|
|
10
10
|
|
|
11
11
|
const vehicle = {
|
|
12
|
-
'-1': 'car',
|
|
13
|
-
0: 'car',
|
|
14
12
|
1: 'bike',
|
|
15
13
|
2: 'foot',
|
|
16
14
|
5: 'truck'
|
|
17
15
|
};
|
|
16
|
+
const defaultVehicle = 'car';
|
|
18
17
|
|
|
19
18
|
const weighting = {
|
|
20
19
|
true: 'curvature',
|
|
@@ -40,7 +39,10 @@ const tollTypes = {
|
|
|
40
39
|
};
|
|
41
40
|
|
|
42
41
|
function extractSegment(result, { distance, interval, text, time }) {
|
|
43
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
directions: { segments },
|
|
44
|
+
path
|
|
45
|
+
} = result;
|
|
44
46
|
const [from, to] = interval;
|
|
45
47
|
segments.push({
|
|
46
48
|
duration: Math.round((time || 0) / 1000),
|
|
@@ -64,7 +66,10 @@ function setTolls(seg) {
|
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
function extractDirections(result, { details, distance, instructions, points, time }) {
|
|
67
|
-
const {
|
|
69
|
+
const {
|
|
70
|
+
directions: { routes, segments },
|
|
71
|
+
fullPath
|
|
72
|
+
} = result;
|
|
68
73
|
result.path = util.decode(points);
|
|
69
74
|
const route = {
|
|
70
75
|
duration: Math.round((time || 0) / 1000),
|
|
@@ -111,7 +116,7 @@ function extractDirections(result, { details, distance, instructions, points, ti
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
function getStatus(st, response) {
|
|
114
|
-
st = st
|
|
119
|
+
st = st?.status;
|
|
115
120
|
if (!(st || response)) {
|
|
116
121
|
return;
|
|
117
122
|
}
|
|
@@ -130,9 +135,14 @@ function getStatus(st, response) {
|
|
|
130
135
|
}
|
|
131
136
|
}
|
|
132
137
|
|
|
138
|
+
function vehicleType(query) {
|
|
139
|
+
const { mode, proposedMode } = query;
|
|
140
|
+
return vehicle[proposedMode ?? mode] || defaultVehicle;
|
|
141
|
+
}
|
|
142
|
+
|
|
133
143
|
function vehicleSize(query, options) {
|
|
134
|
-
const { mode, vehicle } = query;
|
|
135
|
-
if (!(vehicle && mode === travelMode.rv)) {
|
|
144
|
+
const { initialMode, mode, vehicle } = query;
|
|
145
|
+
if (!(vehicle && (initialMode ?? mode) === travelMode.rv)) {
|
|
136
146
|
return;
|
|
137
147
|
}
|
|
138
148
|
const { hazmat } = vehicle;
|
|
@@ -142,7 +152,7 @@ function vehicleSize(query, options) {
|
|
|
142
152
|
multiply_by: '0.0'
|
|
143
153
|
});
|
|
144
154
|
}
|
|
145
|
-
['height', 'width', 'length', 'weight'
|
|
155
|
+
['height', 'width', 'length', 'weight'].forEach(p => {
|
|
146
156
|
if (vehicle[p]) {
|
|
147
157
|
options.push({
|
|
148
158
|
if: `max_${p} < ${vehicle[p]}`,
|
|
@@ -153,19 +163,23 @@ function vehicleSize(query, options) {
|
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
function init(options) {
|
|
156
|
-
|
|
157
166
|
function prepareUrl(url) {
|
|
158
167
|
return `${url}?key=${options.graphhopper_key}`;
|
|
159
168
|
}
|
|
160
169
|
|
|
161
170
|
function prepareRequest(query) {
|
|
162
171
|
const { avoidFerry, avoidHighways, avoidTolls, avoidUnpaved, curvy, mode, path, points, turnbyturn } = query;
|
|
163
|
-
if (
|
|
164
|
-
|
|
172
|
+
if (
|
|
173
|
+
options.parameters.max_curvy_distance &&
|
|
174
|
+
curvy &&
|
|
175
|
+
mode === -1 &&
|
|
176
|
+
points.length === 2 &&
|
|
177
|
+
util.distance(points[0], points[1]) > options.parameters.max_curvy_distance
|
|
178
|
+
) {
|
|
165
179
|
return;
|
|
166
180
|
}
|
|
167
|
-
|
|
168
|
-
vehicle:
|
|
181
|
+
const req = {
|
|
182
|
+
vehicle: vehicleType(query),
|
|
169
183
|
points,
|
|
170
184
|
details: ['road_environment', 'toll']
|
|
171
185
|
};
|
|
@@ -190,21 +204,24 @@ function init(options) {
|
|
|
190
204
|
if (avoidUnpaved) {
|
|
191
205
|
req.avoid_unpaved_roads = true;
|
|
192
206
|
}
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
207
|
+
} else {
|
|
195
208
|
req.details.push('surface');
|
|
196
209
|
req['ch.disable'] = true;
|
|
197
210
|
req.custom_model = {
|
|
198
|
-
priority: [
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
211
|
+
priority: [
|
|
212
|
+
{
|
|
213
|
+
if: 'road_class == MOTORWAY',
|
|
214
|
+
multiply_by: avoidHighways ? '0.1' : '1.0'
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
if: 'toll == ALL',
|
|
218
|
+
multiply_by: avoidTolls ? '0.1' : '1.0'
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
if: 'road_environment == FERRY',
|
|
222
|
+
multiply_by: avoidFerry ? '0.1' : '1.0'
|
|
223
|
+
}
|
|
224
|
+
]
|
|
208
225
|
};
|
|
209
226
|
if (avoidUnpaved) {
|
|
210
227
|
req.custom_model.priority.push({
|
|
@@ -219,7 +236,6 @@ function init(options) {
|
|
|
219
236
|
}
|
|
220
237
|
|
|
221
238
|
function processResponse(response, query) {
|
|
222
|
-
|
|
223
239
|
if (response && response.status >= 400) {
|
|
224
240
|
// let it cascade to the next service
|
|
225
241
|
return;
|
|
@@ -229,7 +245,7 @@ function init(options) {
|
|
|
229
245
|
query,
|
|
230
246
|
provider: options.name
|
|
231
247
|
};
|
|
232
|
-
const paths = response
|
|
248
|
+
const paths = response?.paths;
|
|
233
249
|
if (paths) {
|
|
234
250
|
directions.routes = [];
|
|
235
251
|
if (query.turnbyturn || query.path === pathType.smooth || query.path === pathType.coarse) {
|
package/lib/service/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const fetchagent = require('fetchagent');
|
|
2
|
-
const { pathType } = require(
|
|
2
|
+
const { pathType } = require('../model');
|
|
3
3
|
const makeLimiter = require('limiter-component');
|
|
4
4
|
const status = require('./status');
|
|
5
5
|
const makeSimplify = require('./simplify');
|
|
@@ -89,15 +89,14 @@ function init(options) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
async function request(url, req) {
|
|
92
|
-
const options = this;
|
|
93
92
|
let fa = fetchagent;
|
|
94
|
-
if (
|
|
93
|
+
if (this.post) {
|
|
95
94
|
fa = fa.post(url).send(req);
|
|
96
95
|
} else {
|
|
97
96
|
fa = fa.get(url).query(req);
|
|
98
97
|
}
|
|
99
|
-
if (
|
|
100
|
-
fa.set('authorization',
|
|
98
|
+
if (this.authorization) {
|
|
99
|
+
fa.set('authorization', this.authorization);
|
|
101
100
|
}
|
|
102
101
|
const res = await fa.set('accept', 'application/json').end();
|
|
103
102
|
let status;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { pathType } = require(
|
|
1
|
+
const { pathType } = require('../../model');
|
|
2
2
|
const status = require('../status');
|
|
3
3
|
const util = require('../util');
|
|
4
4
|
|
|
@@ -39,7 +39,12 @@ function addPoint(result, p, i, points) {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function extractSegment(result, { distance, index, narrative, time }) {
|
|
42
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
directions: { segments },
|
|
44
|
+
maneuverIndexes: indexes,
|
|
45
|
+
path,
|
|
46
|
+
unitMultiplier
|
|
47
|
+
} = result;
|
|
43
48
|
segments.push({
|
|
44
49
|
duration: time,
|
|
45
50
|
distance: Math.round((distance || 0) * unitMultiplier),
|
|
@@ -50,7 +55,11 @@ function extractSegment(result, { distance, index, narrative, time }) {
|
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
function extractDirections(result, leg) {
|
|
53
|
-
const {
|
|
58
|
+
const {
|
|
59
|
+
directions: { routes, segments },
|
|
60
|
+
legIndexes: indexes,
|
|
61
|
+
path
|
|
62
|
+
} = result;
|
|
54
63
|
const route = {
|
|
55
64
|
duration: leg.time || 0,
|
|
56
65
|
distance: Math.round((leg.distance || 0) * result.unitMultiplier)
|
|
@@ -71,12 +80,12 @@ function extractDirections(result, leg) {
|
|
|
71
80
|
return result;
|
|
72
81
|
}
|
|
73
82
|
|
|
74
|
-
function getStatus(
|
|
83
|
+
function getStatus(_err, response) {
|
|
75
84
|
if (!response) {
|
|
76
85
|
return;
|
|
77
86
|
}
|
|
78
87
|
const { info, route } = response;
|
|
79
|
-
const st = info
|
|
88
|
+
const st = info?.statuscode;
|
|
80
89
|
if (st === 403 || st === 500) {
|
|
81
90
|
// assume its because we exceeded the limit
|
|
82
91
|
return status.failure;
|
|
@@ -94,7 +103,6 @@ function getStatus(err, response) {
|
|
|
94
103
|
}
|
|
95
104
|
|
|
96
105
|
function init(options) {
|
|
97
|
-
|
|
98
106
|
function getProvider(query) {
|
|
99
107
|
if (query.alternate) {
|
|
100
108
|
return options.name;
|
|
@@ -103,8 +111,11 @@ function init(options) {
|
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
function getUrl(query) {
|
|
106
|
-
return
|
|
107
|
-
(query
|
|
114
|
+
return (
|
|
115
|
+
options[getProvider(query) + '_url'] +
|
|
116
|
+
'/directions/v2/' +
|
|
117
|
+
(query.alternate && query.points.length <= 2 ? 'alternateroutes' : 'route')
|
|
118
|
+
);
|
|
108
119
|
}
|
|
109
120
|
|
|
110
121
|
function prepareRequest(query) {
|
|
@@ -146,8 +157,7 @@ function init(options) {
|
|
|
146
157
|
}
|
|
147
158
|
|
|
148
159
|
function processResponse(response, query) {
|
|
149
|
-
|
|
150
|
-
if (response && response.info) {
|
|
160
|
+
if (response?.info) {
|
|
151
161
|
const { statuscode: st } = response.info;
|
|
152
162
|
if (st === 402 || st > 600) {
|
|
153
163
|
// let it cascade to the next service
|
|
@@ -155,8 +165,8 @@ function init(options) {
|
|
|
155
165
|
}
|
|
156
166
|
}
|
|
157
167
|
|
|
158
|
-
const route = response
|
|
159
|
-
if (!
|
|
168
|
+
const route = response?.route;
|
|
169
|
+
if (!route?.legs?.length) {
|
|
160
170
|
// shouldn't happen
|
|
161
171
|
return;
|
|
162
172
|
}
|
|
@@ -175,9 +185,9 @@ function init(options) {
|
|
|
175
185
|
route.legs.reduce(extractDirections, {
|
|
176
186
|
directions,
|
|
177
187
|
unitMultiplier: query.units === 'km' ? util.metersInKm : util.metersInMile,
|
|
178
|
-
maneuverIndexes: route.shape
|
|
179
|
-
legIndexes: route.shape
|
|
180
|
-
path: route.shape
|
|
188
|
+
maneuverIndexes: route.shape?.maneuverIndexes,
|
|
189
|
+
legIndexes: route.shape?.legIndexes,
|
|
190
|
+
path: route.shape?.shapePoints.reduce(addPoint, []),
|
|
181
191
|
fullPath
|
|
182
192
|
});
|
|
183
193
|
if (fullPath) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// https://openrouteservice.org/dev/#/api-docs/directions
|
|
2
2
|
|
|
3
3
|
const LatLon = require('geodesy/latlon-spherical');
|
|
4
|
-
const { pathType, travelMode } = require(
|
|
4
|
+
const { pathType, travelMode } = require('../../model');
|
|
5
5
|
const status = require('../status');
|
|
6
6
|
const tagRoute = require('../tag-route');
|
|
7
7
|
const util = require('../util');
|
|
@@ -26,27 +26,29 @@ const avoidFeatures = {
|
|
|
26
26
|
avoidFerry: 'ferries'
|
|
27
27
|
};
|
|
28
28
|
const ferryTypes = {
|
|
29
|
-
|
|
29
|
+
9: true
|
|
30
30
|
};
|
|
31
31
|
const roughTypes = {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
2: true, // Unpaved
|
|
33
|
+
8: true, // Compacted Gravel
|
|
34
|
+
9: true, // Fine Gravel
|
|
35
|
+
10: true, // Gravel
|
|
36
|
+
11: true, // Dirt
|
|
37
|
+
12: true, // Ground
|
|
38
|
+
15: true, // Sand
|
|
39
|
+
17: true, // Grass
|
|
40
|
+
18: true // Grass Paver
|
|
41
41
|
};
|
|
42
42
|
const tollTypes = {
|
|
43
|
-
|
|
43
|
+
1: true
|
|
44
44
|
};
|
|
45
45
|
const maxRoundabout = 12 * 60 * 60; // 12 hours maximum for route that is 10 times longer than direct distance
|
|
46
46
|
|
|
47
|
-
|
|
48
47
|
function extractStep(result, { distance, duration, instruction, way_points }) {
|
|
49
|
-
const {
|
|
48
|
+
const {
|
|
49
|
+
directions: { segments },
|
|
50
|
+
path
|
|
51
|
+
} = result;
|
|
50
52
|
const seg = {
|
|
51
53
|
duration: Math.round(duration || 0),
|
|
52
54
|
distance: Math.round(distance || 0),
|
|
@@ -70,13 +72,20 @@ function setTolls(seg) {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
function extractDirections(result, { distance, duration, steps }, i) {
|
|
73
|
-
const {
|
|
75
|
+
const {
|
|
76
|
+
directions: { routes, segments },
|
|
77
|
+
path,
|
|
78
|
+
surface,
|
|
79
|
+
waypoints,
|
|
80
|
+
waytypes,
|
|
81
|
+
tollways
|
|
82
|
+
} = result;
|
|
74
83
|
const route = {
|
|
75
84
|
duration: Math.round(duration || 0),
|
|
76
85
|
distance: Math.round(distance || 0),
|
|
77
86
|
path: path?.slice(waypoints[i], waypoints[i + 1] + 1)
|
|
78
87
|
};
|
|
79
|
-
if (!(route.duration || route.distance ||
|
|
88
|
+
if (!(route.duration || route.distance || route.path?.length > 1)) {
|
|
80
89
|
route.path = [];
|
|
81
90
|
}
|
|
82
91
|
if (segments) {
|
|
@@ -87,7 +96,7 @@ function extractDirections(result, { distance, duration, steps }, i) {
|
|
|
87
96
|
steps.reduce(extractStep, result);
|
|
88
97
|
if (segments.length === 1) {
|
|
89
98
|
const seg = segments[0];
|
|
90
|
-
if (!(seg.duration || seg.distance ||
|
|
99
|
+
if (!(seg.duration || seg.distance || seg.path?.length > 1)) {
|
|
91
100
|
seg.path = [];
|
|
92
101
|
}
|
|
93
102
|
}
|
|
@@ -127,24 +136,30 @@ function toLatLon(p) {
|
|
|
127
136
|
}
|
|
128
137
|
|
|
129
138
|
function directDistance(locations) {
|
|
130
|
-
return locations.reduce(
|
|
131
|
-
next
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
+
return locations.reduce(
|
|
140
|
+
(result, next) => {
|
|
141
|
+
next = toLatLon(next);
|
|
142
|
+
result.dist += result.ll.distanceTo(next);
|
|
143
|
+
result.ll = next;
|
|
144
|
+
return result;
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
dist: 0,
|
|
148
|
+
ll: toLatLon(locations[0])
|
|
149
|
+
}
|
|
150
|
+
).dist;
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
function getStatus(st, response) {
|
|
142
154
|
if (!st && response?.routes?.length) {
|
|
143
|
-
const { distance, duration } = response.routes.reduce(
|
|
144
|
-
result
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
const { distance, duration } = response.routes.reduce(
|
|
156
|
+
(result, { summary }) => {
|
|
157
|
+
result.distance += summary.distance;
|
|
158
|
+
result.duration += summary.duration;
|
|
159
|
+
return result;
|
|
160
|
+
},
|
|
161
|
+
{ distance: 0, duration: 0 }
|
|
162
|
+
);
|
|
148
163
|
const coordinates = response.metadata?.query?.coordinates;
|
|
149
164
|
const direct = coordinates ? directDistance(coordinates) : distance;
|
|
150
165
|
if (distance < 5 * direct || duration < maxRoundabout) {
|
|
@@ -169,13 +184,8 @@ function vehicleSize(query, restrictions) {
|
|
|
169
184
|
}
|
|
170
185
|
|
|
171
186
|
function init(options) {
|
|
172
|
-
|
|
173
187
|
function prepareUrl(query) {
|
|
174
|
-
return [
|
|
175
|
-
options.openroute_url,
|
|
176
|
-
profile[query.mode] || profile[0],
|
|
177
|
-
'json'
|
|
178
|
-
].join('/');
|
|
188
|
+
return [options.openroute_url, profile[query.mode] || profile[0], 'json'].join('/');
|
|
179
189
|
}
|
|
180
190
|
|
|
181
191
|
function avoidFeature(result, flag) {
|
|
@@ -219,7 +229,6 @@ function init(options) {
|
|
|
219
229
|
}
|
|
220
230
|
|
|
221
231
|
function processResponse(response, query) {
|
|
222
|
-
|
|
223
232
|
if (!response?.routes?.length) {
|
|
224
233
|
// let it cascade to the next service
|
|
225
234
|
return;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { pathType } = require(
|
|
1
|
+
const { pathType } = require('../../model');
|
|
2
2
|
const status = require('../status');
|
|
3
3
|
const util = require('../util');
|
|
4
4
|
|
|
@@ -45,8 +45,8 @@ function convertRoute({ legs }) {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// response codes: http://project-osrm.org/docs/v5.5.2/api/#responses
|
|
48
|
-
function getStatus(
|
|
49
|
-
const code = response
|
|
48
|
+
function getStatus(_err, response) {
|
|
49
|
+
const code = response?.code;
|
|
50
50
|
if (!response) {
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
@@ -75,26 +75,16 @@ const profile = {
|
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
function prepareUrl(baseUrl, query) {
|
|
78
|
-
|
|
79
78
|
function coords2string(c) {
|
|
80
79
|
return c[0].toFixed(5) + ',' + c[1].toFixed(5);
|
|
81
80
|
}
|
|
82
81
|
|
|
82
|
+
const path = query.points.map(coords2string).join(';');
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
.map(coords2string)
|
|
86
|
-
.join(';');
|
|
87
|
-
|
|
88
|
-
return [
|
|
89
|
-
baseUrl,
|
|
90
|
-
'route/v1',
|
|
91
|
-
profile[query.mode],
|
|
92
|
-
path
|
|
93
|
-
].join('/');
|
|
84
|
+
return [baseUrl, 'route/v1', profile[query.mode], path].join('/');
|
|
94
85
|
}
|
|
95
86
|
|
|
96
87
|
function init(options) {
|
|
97
|
-
|
|
98
88
|
function processResponse(response, query) {
|
|
99
89
|
const directions = {
|
|
100
90
|
query,
|
|
@@ -112,14 +102,14 @@ function init(options) {
|
|
|
112
102
|
if (query.turnbyturn || query.path === pathType.smooth || query.path === pathType.coarse) {
|
|
113
103
|
directions.segments = [];
|
|
114
104
|
// copy segments from route to its own table
|
|
115
|
-
directions.routes.forEach(
|
|
105
|
+
directions.routes.forEach(route => {
|
|
116
106
|
route.segmentIndex = directions.segments.length;
|
|
117
107
|
directions.segments = directions.segments.concat(route.segments);
|
|
118
108
|
delete route.segments;
|
|
119
109
|
});
|
|
120
110
|
} else {
|
|
121
111
|
// delete segments
|
|
122
|
-
directions.routes.forEach(
|
|
112
|
+
directions.routes.forEach(route => {
|
|
123
113
|
delete route.segments;
|
|
124
114
|
});
|
|
125
115
|
}
|
package/lib/service/partition.js
CHANGED
|
@@ -3,7 +3,7 @@ const util = require('./util');
|
|
|
3
3
|
module.exports = partition;
|
|
4
4
|
|
|
5
5
|
function distanceSquare(p1, p2) {
|
|
6
|
-
return
|
|
6
|
+
return (p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
function pointOnLine(point, p1, p2) {
|
package/lib/service/simplify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const pathType = require(
|
|
1
|
+
const pathType = require('../model').pathType;
|
|
2
2
|
const util = require('./util');
|
|
3
3
|
|
|
4
4
|
module.exports = init;
|
|
@@ -6,7 +6,7 @@ module.exports = init;
|
|
|
6
6
|
function init(options) {
|
|
7
7
|
options = options || {};
|
|
8
8
|
|
|
9
|
-
const algorithm = options.algorithm || require(
|
|
9
|
+
const algorithm = options.algorithm || require('vis-why');
|
|
10
10
|
const endPoints = options.endPoints || 25; // how many points keep at ends
|
|
11
11
|
const maxPoints = options.pathPoints || 100; // maximum number of points kept per path
|
|
12
12
|
const ed = maxPoints / endPoints;
|
|
@@ -53,8 +53,10 @@ function init(options) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
if (first.split) {
|
|
56
|
-
util.concat(
|
|
57
|
-
|
|
56
|
+
util.concat(
|
|
57
|
+
path,
|
|
58
|
+
segments[i].path.slice(first.split, i === result.segmentIndex - 1 && last.split ? last.split : undefined)
|
|
59
|
+
);
|
|
58
60
|
i += 1;
|
|
59
61
|
}
|
|
60
62
|
for (; i < (last.split ? result.segmentIndex - 1 : result.segmentIndex); i += 1) {
|
|
@@ -64,7 +66,7 @@ function init(options) {
|
|
|
64
66
|
util.concat(path, segments[i].path.slice(0, last.split));
|
|
65
67
|
}
|
|
66
68
|
result.segmentIndex = route.segmentIndex;
|
|
67
|
-
if (type === pathType.full ||
|
|
69
|
+
if (type === pathType.full || first.length + path.length + last.length <= maxPoints) {
|
|
68
70
|
if (endDistance) {
|
|
69
71
|
route.path = util.concat(util.concat(first, path), last);
|
|
70
72
|
} else {
|
package/lib/service/util.js
CHANGED
|
@@ -64,7 +64,7 @@ function isFuture(time) {
|
|
|
64
64
|
|
|
65
65
|
// like normal join but with optional filter fn
|
|
66
66
|
function join(arr, conn, fn) {
|
|
67
|
-
fn = fn ||
|
|
67
|
+
fn = fn || (it => it);
|
|
68
68
|
return arr.filter(fn).join(conn);
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -73,24 +73,27 @@ function last(arr) {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function split2object(str, conn, obj) {
|
|
76
|
-
return str.split(conn || '-').reduce(
|
|
76
|
+
return str.split(conn || '-').reduce((result, word) => {
|
|
77
77
|
result[word] = word;
|
|
78
78
|
return result;
|
|
79
79
|
}, obj || {});
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
function collateResults(results, query) {
|
|
83
|
-
return results.reduce(
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
result.name
|
|
83
|
+
return results.reduce(
|
|
84
|
+
(result, r) => {
|
|
85
|
+
concatArrayProp(result, r, 'segments');
|
|
86
|
+
concatArrayProp(result, r, 'places');
|
|
87
|
+
concatArrayProp(result, r, 'routes');
|
|
88
|
+
if (!result.name && r?.name) {
|
|
89
|
+
result.name = r.name;
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
query
|
|
89
95
|
}
|
|
90
|
-
|
|
91
|
-
}, {
|
|
92
|
-
query
|
|
93
|
-
});
|
|
96
|
+
);
|
|
94
97
|
|
|
95
98
|
function concatArrayProp(to, from, prop) {
|
|
96
99
|
if (!from[prop]) {
|
|
@@ -110,12 +113,10 @@ function withTimeout(promise, millis, signal) {
|
|
|
110
113
|
let reject;
|
|
111
114
|
|
|
112
115
|
signal?.addEventListener('abort', onabort);
|
|
113
|
-
return Promise
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
clearTimeout(id);
|
|
118
|
-
});
|
|
116
|
+
return Promise.race([promise, new Promise(timeoutPromise)]).finally(() => {
|
|
117
|
+
signal?.removeEventListener('abort', onabort);
|
|
118
|
+
clearTimeout(id);
|
|
119
|
+
});
|
|
119
120
|
|
|
120
121
|
function onabort() {
|
|
121
122
|
reject(signal.reason);
|
|
@@ -124,10 +125,7 @@ function withTimeout(promise, millis, signal) {
|
|
|
124
125
|
function timeoutPromise(_resolve, _reject) {
|
|
125
126
|
resolve = _resolve;
|
|
126
127
|
reject = _reject;
|
|
127
|
-
id = setTimeout(
|
|
128
|
-
() => resolve(),
|
|
129
|
-
millis
|
|
130
|
-
);
|
|
128
|
+
id = setTimeout(() => resolve(), millis);
|
|
131
129
|
}
|
|
132
130
|
}
|
|
133
131
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// https://github.com/valhalla/valhalla-docs
|
|
2
2
|
|
|
3
3
|
const LatLon = require('geodesy/latlon-spherical');
|
|
4
|
-
const { pathType, travelMode } = require(
|
|
4
|
+
const { pathType, travelMode } = require('../../model');
|
|
5
5
|
const status = require('../status');
|
|
6
6
|
const util = require('../util');
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ const costingOptions = {
|
|
|
23
23
|
hazmat: true
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
|
-
const minSpeed = 15 * 1000 / 3600; // bump speed when it is absurdly low
|
|
26
|
+
const minSpeed = (15 * 1000) / 3600; // bump speed when it is absurdly low
|
|
27
27
|
const turnDistance = 100; // don't adjust speed of turns
|
|
28
28
|
const maxRoundabout = 12 * 60 * 60; // 12 hours maximum for route that is 10 times longer than direct distance
|
|
29
29
|
|
|
@@ -41,18 +41,15 @@ function prepareWaypoint(p) {
|
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
function extractSegment(
|
|
45
|
-
|
|
46
|
-
begin_shape_index,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
travel_mode
|
|
54
|
-
}) {
|
|
55
|
-
const { directions: { segments, routes }, unitMultiplier, path } = result;
|
|
44
|
+
function extractSegment(
|
|
45
|
+
result,
|
|
46
|
+
{ type, begin_shape_index, end_shape_index, instruction, length, time, rough, toll, travel_mode }
|
|
47
|
+
) {
|
|
48
|
+
const {
|
|
49
|
+
directions: { segments, routes },
|
|
50
|
+
unitMultiplier,
|
|
51
|
+
path
|
|
52
|
+
} = result;
|
|
56
53
|
const distance = Math.round((length || 0) * unitMultiplier);
|
|
57
54
|
let duration = time;
|
|
58
55
|
if (rough) {
|
|
@@ -69,7 +66,7 @@ function extractSegment(result, {
|
|
|
69
66
|
const seg = {
|
|
70
67
|
duration,
|
|
71
68
|
distance,
|
|
72
|
-
path: path
|
|
69
|
+
path: path?.slice(begin_shape_index, end_shape_index),
|
|
73
70
|
instructions: instruction
|
|
74
71
|
};
|
|
75
72
|
if (rough) {
|
|
@@ -98,8 +95,8 @@ function extractDirections(result, leg) {
|
|
|
98
95
|
const { directions } = result;
|
|
99
96
|
result.path = util.decode(leg.shape, { factor: 1e6 });
|
|
100
97
|
const route = {
|
|
101
|
-
duration:
|
|
102
|
-
distance: Math.round((
|
|
98
|
+
duration: leg.summary?.time || 0,
|
|
99
|
+
distance: Math.round((leg.summary?.length || 0) * result.unitMultiplier)
|
|
103
100
|
};
|
|
104
101
|
if (result.fullPath) {
|
|
105
102
|
route.path = result.path;
|
|
@@ -125,19 +122,24 @@ function toLatLon(p) {
|
|
|
125
122
|
|
|
126
123
|
function directDistance(locations, units) {
|
|
127
124
|
units = units === 'miles' ? util.metersInMile : util.metersInKm;
|
|
128
|
-
return
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
125
|
+
return (
|
|
126
|
+
locations.reduce(
|
|
127
|
+
(result, next) => {
|
|
128
|
+
next = toLatLon(next);
|
|
129
|
+
result.dist += result.ll.distanceTo(next);
|
|
130
|
+
result.ll = next;
|
|
131
|
+
return result;
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
dist: 0,
|
|
135
|
+
ll: toLatLon(locations[0])
|
|
136
|
+
}
|
|
137
|
+
).dist / units
|
|
138
|
+
);
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
function getStatus(
|
|
140
|
-
let st = response
|
|
141
|
+
function getStatus(_err, response) {
|
|
142
|
+
let st = response?.status_code;
|
|
141
143
|
if (!response) {
|
|
142
144
|
return;
|
|
143
145
|
}
|
|
@@ -150,14 +152,13 @@ function getStatus(err, response) {
|
|
|
150
152
|
// no route
|
|
151
153
|
return status.empty;
|
|
152
154
|
}
|
|
153
|
-
st = response.trip
|
|
155
|
+
st = response.trip?.status;
|
|
154
156
|
if (st === 0) {
|
|
155
|
-
if (response.trip.legs
|
|
157
|
+
if (response.trip.legs?.length) {
|
|
156
158
|
const { length, time } = response.trip.summary;
|
|
157
159
|
const distance = directDistance(response.trip.locations, response.trip.units);
|
|
158
160
|
// make sure points are not too far from roads
|
|
159
|
-
if (length > 0.9 * distance &&
|
|
160
|
-
(length < 10 * distance || time < maxRoundabout)) {
|
|
161
|
+
if (length > 0.9 * distance && (length < 10 * distance || time < maxRoundabout)) {
|
|
161
162
|
return status.success;
|
|
162
163
|
}
|
|
163
164
|
}
|
|
@@ -166,20 +167,24 @@ function getStatus(err, response) {
|
|
|
166
167
|
}
|
|
167
168
|
}
|
|
168
169
|
|
|
170
|
+
function costingType(query) {
|
|
171
|
+
const { mode, proposedMode } = query;
|
|
172
|
+
return costing[proposedMode ?? mode] || defaultCosting;
|
|
173
|
+
}
|
|
174
|
+
|
|
169
175
|
function vehicleSize(query, options) {
|
|
170
|
-
const { mode, vehicle } = query;
|
|
171
|
-
if (!(vehicle && mode === travelMode.rv)) {
|
|
176
|
+
const { initialMode, mode, vehicle } = query;
|
|
177
|
+
if (!(vehicle && (initialMode ?? mode) === travelMode.rv)) {
|
|
172
178
|
return;
|
|
173
179
|
}
|
|
174
180
|
Object.assign(options, vehicle);
|
|
175
181
|
}
|
|
176
182
|
|
|
177
183
|
function init(options) {
|
|
178
|
-
|
|
179
184
|
function prepareRequest(query) {
|
|
180
185
|
let req = {
|
|
181
186
|
locations: query.points.map(prepareWaypoint),
|
|
182
|
-
costing:
|
|
187
|
+
costing: costingType(query),
|
|
183
188
|
costing_options: {},
|
|
184
189
|
directions_options: {
|
|
185
190
|
units: units[query.units] || units.m
|
|
@@ -224,8 +229,8 @@ function init(options) {
|
|
|
224
229
|
}
|
|
225
230
|
|
|
226
231
|
function processResponse(response, query) {
|
|
227
|
-
const trip = response
|
|
228
|
-
if (trip
|
|
232
|
+
const trip = response?.trip;
|
|
233
|
+
if (trip?.legs?.length) {
|
|
229
234
|
const directions = {
|
|
230
235
|
query,
|
|
231
236
|
provider: options.name,
|
package/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@furkot/directions",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "Directions service for Furkot",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Damian Krzeminski",
|
|
7
7
|
"email": "pirxpilot@furkot.com",
|
|
8
8
|
"url": "https://pirxpilot.me"
|
|
9
9
|
},
|
|
10
|
-
"repository":
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/furkot/directions.git"
|
|
13
|
+
},
|
|
11
14
|
"license": "MIT",
|
|
12
15
|
"keywords": [
|
|
13
16
|
"furkot-directions",
|
|
@@ -20,13 +23,10 @@
|
|
|
20
23
|
"fetchagent": "~2.1.0",
|
|
21
24
|
"geodesy": "^1.1.1",
|
|
22
25
|
"limiter-component": "^1.2.0",
|
|
23
|
-
"vis-why": "
|
|
26
|
+
"vis-why": "~2"
|
|
24
27
|
},
|
|
25
28
|
"devDependencies": {
|
|
26
|
-
"
|
|
27
|
-
"mocha": "~10",
|
|
28
|
-
"should": "~13",
|
|
29
|
-
"sinon": "~14"
|
|
29
|
+
"@biomejs/biome": "^1.9.4"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"test": "make check"
|
|
@@ -35,4 +35,4 @@
|
|
|
35
35
|
"index.js",
|
|
36
36
|
"lib"
|
|
37
37
|
]
|
|
38
|
-
}
|
|
38
|
+
}
|