@furkot/directions 2.0.2 → 2.1.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/lib/model.js +1 -1
- package/lib/service/graphhopper/index.js +129 -32
- package/lib/service/openroute/index.js +87 -50
- package/lib/service/tag-route.js +54 -0
- package/lib/service/valhalla/index.js +25 -4
- package/package.json +1 -1
package/lib/model.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
// https://docs.graphhopper.com/#tag/Routing-API
|
|
2
|
+
// https://github.com/boldtrn/kurviger-api-documentation
|
|
3
|
+
|
|
4
|
+
const { pathType, travelMode } = require("../../model");
|
|
2
5
|
const status = require('../status');
|
|
6
|
+
const tagRoute = require('../tag-route');
|
|
3
7
|
const util = require('../util');
|
|
4
8
|
|
|
5
9
|
module.exports = init;
|
|
@@ -18,24 +22,48 @@ const weighting = {
|
|
|
18
22
|
2: 'curvaturefastest'
|
|
19
23
|
};
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const ferryTypes = {
|
|
26
|
+
ferry: true
|
|
27
|
+
};
|
|
28
|
+
const roughTypes = {
|
|
29
|
+
compacted: true,
|
|
30
|
+
dirt: true,
|
|
31
|
+
fine_gravel: true,
|
|
32
|
+
grass: true,
|
|
33
|
+
gravel: true,
|
|
34
|
+
ground: true,
|
|
35
|
+
sand: true,
|
|
36
|
+
unpaved: true
|
|
37
|
+
};
|
|
38
|
+
const tollTypes = {
|
|
39
|
+
all: true
|
|
40
|
+
};
|
|
26
41
|
|
|
27
42
|
function extractSegment(result, { distance, interval, text, time }) {
|
|
28
43
|
const { directions: { segments }, path } = result;
|
|
44
|
+
const [from, to] = interval;
|
|
29
45
|
segments.push({
|
|
30
46
|
duration: Math.round((time || 0) / 1000),
|
|
31
47
|
distance: Math.round(distance || 0),
|
|
32
|
-
path: path
|
|
48
|
+
path: path?.slice(from, to + 1),
|
|
33
49
|
instructions: text
|
|
34
50
|
});
|
|
35
51
|
return result;
|
|
36
52
|
}
|
|
37
53
|
|
|
38
|
-
function
|
|
54
|
+
function setFerryMode(seg) {
|
|
55
|
+
seg.mode = travelMode.ferry;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function setRough(seg) {
|
|
59
|
+
seg.rough = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function setTolls(seg) {
|
|
63
|
+
seg.tolls = true;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function extractDirections(result, { details, distance, instructions, points, time }) {
|
|
39
67
|
const { directions: { routes, segments }, fullPath } = result;
|
|
40
68
|
result.path = util.decode(points);
|
|
41
69
|
const route = {
|
|
@@ -54,6 +82,30 @@ function extractDirections(result, { distance, instructions, points, time }) {
|
|
|
54
82
|
if (segments.length) {
|
|
55
83
|
util.last(segments).path.push(util.last(result.path));
|
|
56
84
|
}
|
|
85
|
+
const ferry = tagRoute(details?.road_environment, {
|
|
86
|
+
segments,
|
|
87
|
+
types: ferryTypes,
|
|
88
|
+
updateSegment: setFerryMode
|
|
89
|
+
});
|
|
90
|
+
if (ferry?.foundType) {
|
|
91
|
+
route.ferry = true;
|
|
92
|
+
}
|
|
93
|
+
const rough = tagRoute(details?.surface, {
|
|
94
|
+
segments,
|
|
95
|
+
types: roughTypes,
|
|
96
|
+
updateSegment: setRough
|
|
97
|
+
});
|
|
98
|
+
if (rough?.foundType) {
|
|
99
|
+
route.rough = true;
|
|
100
|
+
}
|
|
101
|
+
const tolls = tagRoute(details?.toll, {
|
|
102
|
+
segments,
|
|
103
|
+
types: tollTypes,
|
|
104
|
+
updateSegment: setTolls
|
|
105
|
+
});
|
|
106
|
+
if (tolls?.foundType) {
|
|
107
|
+
route.tolls = true;
|
|
108
|
+
}
|
|
57
109
|
}
|
|
58
110
|
return result;
|
|
59
111
|
}
|
|
@@ -78,48 +130,92 @@ function getStatus(st, response) {
|
|
|
78
130
|
}
|
|
79
131
|
}
|
|
80
132
|
|
|
133
|
+
function vehicleSize(query, options) {
|
|
134
|
+
const { mode, vehicle } = query;
|
|
135
|
+
if (!(vehicle && mode === travelMode.rv)) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const { hazmat } = vehicle;
|
|
139
|
+
if (hazmat) {
|
|
140
|
+
options.push({
|
|
141
|
+
if: 'hazmat == NO',
|
|
142
|
+
multiply_by: '0.0'
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
['height', 'width', 'length', 'weight', 'axle_load'].forEach(p => {
|
|
146
|
+
if (vehicle[p]) {
|
|
147
|
+
options.push({
|
|
148
|
+
if: `max_${p} < ${vehicle[p]}`,
|
|
149
|
+
multiply_by: '0.0'
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
81
155
|
function init(options) {
|
|
82
156
|
|
|
83
|
-
function prepareUrl(url
|
|
157
|
+
function prepareUrl(url) {
|
|
158
|
+
return `${url}?key=${options.graphhopper_key}`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function prepareRequest(query) {
|
|
162
|
+
const { avoidFerry, avoidHighways, avoidTolls, avoidUnpaved, curvy, mode, path, points, turnbyturn } = query;
|
|
163
|
+
if (options.parameters.max_curvy_distance && curvy && mode === -1 && points.length === 2 &&
|
|
164
|
+
util.distance(points[0], points[1]) > options.parameters.max_curvy_distance) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
84
167
|
let req = {
|
|
85
168
|
vehicle: vehicle[mode] || vehicle[0],
|
|
86
|
-
|
|
169
|
+
points,
|
|
170
|
+
details: ['road_environment', 'toll']
|
|
87
171
|
};
|
|
172
|
+
if (!turnbyturn && path !== pathType.smooth && path !== pathType.coarse) {
|
|
173
|
+
req.instructions = false;
|
|
174
|
+
}
|
|
88
175
|
if (curvy && mode === -1) {
|
|
89
176
|
req.vehicle = 'motorcycle.kurviger.de';
|
|
90
177
|
req.weighting = weighting[curvy];
|
|
91
178
|
if (options.parameters.app_type) {
|
|
92
179
|
req['app.type'] = options.parameters.app_type;
|
|
93
180
|
}
|
|
181
|
+
if (avoidHighways) {
|
|
182
|
+
req.avoid_motorways = true;
|
|
183
|
+
}
|
|
184
|
+
if (avoidTolls) {
|
|
185
|
+
req.avoid_toll_roads = true;
|
|
186
|
+
}
|
|
187
|
+
if (avoidFerry) {
|
|
188
|
+
req.avoid_ferries = true;
|
|
189
|
+
}
|
|
94
190
|
if (avoidUnpaved) {
|
|
95
191
|
req.avoid_unpaved_roads = true;
|
|
96
192
|
}
|
|
97
193
|
}
|
|
98
|
-
|
|
99
|
-
req.
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
194
|
+
else {
|
|
195
|
+
req.details.push('surface');
|
|
196
|
+
req['ch.disable'] = true;
|
|
197
|
+
req.custom_model = {
|
|
198
|
+
priority: [{
|
|
199
|
+
if: 'road_class == MOTORWAY',
|
|
200
|
+
multiply_by: avoidHighways ? '0.1' : '1.0'
|
|
201
|
+
}, {
|
|
202
|
+
if: 'toll == ALL',
|
|
203
|
+
multiply_by: avoidTolls ? '0.1' : '1.0'
|
|
204
|
+
}, {
|
|
205
|
+
if: 'road_environment == FERRY',
|
|
206
|
+
multiply_by: avoidFerry ? '0.1' : '1.0'
|
|
207
|
+
}]
|
|
208
|
+
};
|
|
209
|
+
if (avoidUnpaved) {
|
|
210
|
+
req.custom_model.priority.push({
|
|
211
|
+
if: 'surface == UNPAVED',
|
|
212
|
+
multiply_by: '0.0'
|
|
213
|
+
});
|
|
110
214
|
}
|
|
215
|
+
vehicleSize(query, req.custom_model.priority);
|
|
111
216
|
}
|
|
112
217
|
|
|
113
|
-
|
|
114
|
-
return name + '=' + encodeURIComponent(req[name]);
|
|
115
|
-
}));
|
|
116
|
-
|
|
117
|
-
return url + '?' + req.join('&');
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
function prepareRequest({ mode, points, curvy }) {
|
|
121
|
-
return !(options.parameters.max_curvy_distance && curvy && mode === -1 && points.length === 2 &&
|
|
122
|
-
util.distance(points[0], points[1]) > options.parameters.max_curvy_distance);
|
|
218
|
+
return req;
|
|
123
219
|
}
|
|
124
220
|
|
|
125
221
|
function processResponse(response, query) {
|
|
@@ -154,6 +250,7 @@ function init(options) {
|
|
|
154
250
|
|
|
155
251
|
options = util.defaults(options, {
|
|
156
252
|
maxPoints: options.graphhopper_max_points || 5, // max 5 points for free and 30-150 for paid plan
|
|
253
|
+
post: true,
|
|
157
254
|
url: prepareUrl.bind(undefined, options.graphhopper_url),
|
|
158
255
|
status: getStatus,
|
|
159
256
|
prepareRequest,
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const LatLon = require('geodesy/latlon-spherical');
|
|
4
4
|
const { pathType, travelMode } = require("../../model");
|
|
5
5
|
const status = require('../status');
|
|
6
|
+
const tagRoute = require('../tag-route');
|
|
6
7
|
const util = require('../util');
|
|
7
8
|
|
|
8
9
|
module.exports = init;
|
|
@@ -19,55 +20,63 @@ const profileRestrictions = {
|
|
|
19
20
|
hazmat: true
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
|
-
const
|
|
23
|
+
const avoidFeatures = {
|
|
24
|
+
avoidHighways: 'highways',
|
|
25
|
+
avoidTolls: 'tollways',
|
|
26
|
+
avoidFerry: 'ferries'
|
|
27
|
+
};
|
|
28
|
+
const ferryTypes = {
|
|
29
|
+
'9': true
|
|
30
|
+
};
|
|
31
|
+
const roughTypes = {
|
|
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
|
+
};
|
|
42
|
+
const tollTypes = {
|
|
43
|
+
'1': true
|
|
44
|
+
};
|
|
23
45
|
const maxRoundabout = 12 * 60 * 60; // 12 hours maximum for route that is 10 times longer than direct distance
|
|
24
46
|
|
|
25
|
-
function nextFerry(result, points = [-1, -1]) {
|
|
26
|
-
let { waytypes } = result;
|
|
27
|
-
if (!waytypes) {
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
for (; result.way < waytypes.length; result.way += 1) {
|
|
31
|
-
const waytype = waytypes[result.way];
|
|
32
|
-
if (waytype[0] > points[1]) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
if (waytype[2] === ferryType && (
|
|
36
|
-
(waytype[0] <= points[0] && waytype[1] >= points[1]) ||
|
|
37
|
-
(waytype[0] > points[0] && waytype[1] < points[1]) ||
|
|
38
|
-
(waytype[0] >= points[0] && waytype[0] <= points[1]) ||
|
|
39
|
-
(waytype[1] >= points[0] && waytype[1] <= points[1])
|
|
40
|
-
)) {
|
|
41
|
-
return waytype;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
47
|
|
|
46
48
|
function extractStep(result, { distance, duration, instruction, way_points }) {
|
|
47
|
-
const { directions: { segments
|
|
49
|
+
const { directions: { segments }, path } = result;
|
|
48
50
|
const seg = {
|
|
49
51
|
duration: Math.round(duration || 0),
|
|
50
52
|
distance: Math.round(distance || 0),
|
|
51
|
-
path: path
|
|
53
|
+
path: path?.slice(way_points[0], way_points[1] + 1),
|
|
52
54
|
instructions: instruction
|
|
53
55
|
};
|
|
54
56
|
segments.push(seg);
|
|
55
|
-
const ferrySeg = nextFerry(result, way_points);
|
|
56
|
-
if (ferrySeg) {
|
|
57
|
-
seg.mode = travelMode.ferry;
|
|
58
|
-
util.last(routes).ferry = true;
|
|
59
|
-
}
|
|
60
57
|
return result;
|
|
61
58
|
}
|
|
62
59
|
|
|
60
|
+
function setFerryMode(seg) {
|
|
61
|
+
seg.mode = travelMode.ferry;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function setRough(seg) {
|
|
65
|
+
seg.rough = true;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function setTolls(seg) {
|
|
69
|
+
seg.tolls = true;
|
|
70
|
+
}
|
|
71
|
+
|
|
63
72
|
function extractDirections(result, { distance, duration, steps }, i) {
|
|
64
|
-
const { directions: { routes, segments }, path, waypoints } = result;
|
|
73
|
+
const { directions: { routes, segments }, path, surface, waypoints, waytypes, tollways } = result;
|
|
65
74
|
const route = {
|
|
66
75
|
duration: Math.round(duration || 0),
|
|
67
76
|
distance: Math.round(distance || 0),
|
|
68
|
-
path: path
|
|
77
|
+
path: path?.slice(waypoints[i], waypoints[i + 1] + 1)
|
|
69
78
|
};
|
|
70
|
-
if (!(route.duration || route.distance || (route.path
|
|
79
|
+
if (!(route.duration || route.distance || (route.path?.length > 1))) {
|
|
71
80
|
route.path = [];
|
|
72
81
|
}
|
|
73
82
|
if (segments) {
|
|
@@ -75,18 +84,40 @@ function extractDirections(result, { distance, duration, steps }, i) {
|
|
|
75
84
|
}
|
|
76
85
|
routes.push(route);
|
|
77
86
|
if (segments && steps) {
|
|
78
|
-
result.way = 0;
|
|
79
|
-
nextFerry(result);
|
|
80
87
|
steps.reduce(extractStep, result);
|
|
81
88
|
if (segments.length === 1) {
|
|
82
89
|
const seg = segments[0];
|
|
83
|
-
if (!(seg.duration || seg.distance || (seg.path
|
|
90
|
+
if (!(seg.duration || seg.distance || (seg.path?.length > 1))) {
|
|
84
91
|
seg.path = [];
|
|
85
92
|
}
|
|
86
93
|
}
|
|
87
94
|
if (segments.length && route.path.length) {
|
|
88
95
|
util.last(segments).path.push(util.last(route.path));
|
|
89
96
|
}
|
|
97
|
+
const ferry = tagRoute(waytypes, {
|
|
98
|
+
segments,
|
|
99
|
+
types: ferryTypes,
|
|
100
|
+
updateSegment: setFerryMode
|
|
101
|
+
});
|
|
102
|
+
if (ferry?.foundType) {
|
|
103
|
+
route.ferry = true;
|
|
104
|
+
}
|
|
105
|
+
const rough = tagRoute(surface, {
|
|
106
|
+
segments,
|
|
107
|
+
types: roughTypes,
|
|
108
|
+
updateSegment: setRough
|
|
109
|
+
});
|
|
110
|
+
if (rough?.foundType) {
|
|
111
|
+
route.rough = true;
|
|
112
|
+
}
|
|
113
|
+
const tolls = tagRoute(tollways, {
|
|
114
|
+
segments,
|
|
115
|
+
types: tollTypes,
|
|
116
|
+
updateSegment: setTolls
|
|
117
|
+
});
|
|
118
|
+
if (tolls?.foundType) {
|
|
119
|
+
route.tolls = true;
|
|
120
|
+
}
|
|
90
121
|
}
|
|
91
122
|
return result;
|
|
92
123
|
}
|
|
@@ -108,7 +139,7 @@ function directDistance(locations) {
|
|
|
108
139
|
}
|
|
109
140
|
|
|
110
141
|
function getStatus(st, response) {
|
|
111
|
-
if (!st && response
|
|
142
|
+
if (!st && response?.routes?.length) {
|
|
112
143
|
const { distance, duration } = response.routes.reduce((result, { summary}) => {
|
|
113
144
|
result.distance += summary.distance;
|
|
114
145
|
result.duration += summary.duration;
|
|
@@ -126,7 +157,7 @@ function getStatus(st, response) {
|
|
|
126
157
|
|
|
127
158
|
function vehicleSize(query, restrictions) {
|
|
128
159
|
const { mode, vehicle } = query;
|
|
129
|
-
if (!(vehicle && mode ===
|
|
160
|
+
if (!(vehicle && mode === travelMode.rv)) {
|
|
130
161
|
return restrictions;
|
|
131
162
|
}
|
|
132
163
|
restrictions = Object.assign({}, restrictions, vehicle);
|
|
@@ -147,14 +178,25 @@ function init(options) {
|
|
|
147
178
|
].join('/');
|
|
148
179
|
}
|
|
149
180
|
|
|
181
|
+
function avoidFeature(result, flag) {
|
|
182
|
+
const { query, req } = result;
|
|
183
|
+
if (query[flag]) {
|
|
184
|
+
req.options = req.options || {};
|
|
185
|
+
req.options.avoid_features = req.options.avoid_features || [];
|
|
186
|
+
req.options.avoid_features.push(avoidFeatures[flag]);
|
|
187
|
+
}
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
|
|
150
191
|
function prepareRequest(query) {
|
|
151
192
|
const req = {
|
|
152
|
-
coordinates: query.points
|
|
193
|
+
coordinates: query.points,
|
|
194
|
+
extra_info: ['surface', 'tollways']
|
|
153
195
|
};
|
|
154
196
|
if (!query.turnbyturn && query.path !== pathType.smooth && query.path !== pathType.coarse) {
|
|
155
197
|
req.instructions = false;
|
|
156
198
|
} else {
|
|
157
|
-
req.extra_info
|
|
199
|
+
req.extra_info.push('waytype');
|
|
158
200
|
}
|
|
159
201
|
const restrictions = vehicleSize(query, profileRestrictions[query.mode]);
|
|
160
202
|
if (restrictions) {
|
|
@@ -164,25 +206,18 @@ function init(options) {
|
|
|
164
206
|
}
|
|
165
207
|
};
|
|
166
208
|
}
|
|
209
|
+
const param = { query, req };
|
|
167
210
|
if ((profile[query.mode] || profile[0]) === 'driving-car') {
|
|
168
|
-
|
|
169
|
-
req.options = req.options || {
|
|
170
|
-
avoid_features: ['highways']
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (query.avoidTolls) {
|
|
174
|
-
req.options = req.options || {};
|
|
175
|
-
req.options.avoid_features = req.options.avoid_features || [];
|
|
176
|
-
req.options.avoid_features.push('tollways');
|
|
177
|
-
}
|
|
211
|
+
['avoidHighways', 'avoidTolls'].reduce(avoidFeature, param);
|
|
178
212
|
}
|
|
213
|
+
avoidFeature(param, 'avoidFerry');
|
|
179
214
|
|
|
180
215
|
return req;
|
|
181
216
|
}
|
|
182
217
|
|
|
183
218
|
function processResponse(response, query) {
|
|
184
219
|
|
|
185
|
-
if (!
|
|
220
|
+
if (!response?.routes?.length) {
|
|
186
221
|
// let it cascade to the next service
|
|
187
222
|
return;
|
|
188
223
|
}
|
|
@@ -203,8 +238,10 @@ function init(options) {
|
|
|
203
238
|
paths.reduce(extractDirections, {
|
|
204
239
|
directions,
|
|
205
240
|
path: util.decode(geometry),
|
|
241
|
+
surface: extras?.surface?.values,
|
|
242
|
+
tollways: extras?.tollways?.values,
|
|
206
243
|
waypoints,
|
|
207
|
-
waytypes: extras
|
|
244
|
+
waytypes: extras?.waytypes?.values
|
|
208
245
|
});
|
|
209
246
|
if (fullPath) {
|
|
210
247
|
// path is already prepared - no need to do it again from segments
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module.exports = tagRoute;
|
|
2
|
+
|
|
3
|
+
function splitSegment(result, length) {
|
|
4
|
+
const { segments, seg } = result;
|
|
5
|
+
const { distance, duration, path } = segments[seg];
|
|
6
|
+
if (length <= 0 || length + 1 >= path.length) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
const factor = length / path.length;
|
|
10
|
+
segments.splice(seg, 0, {
|
|
11
|
+
distance: distance * factor,
|
|
12
|
+
duration: duration * factor,
|
|
13
|
+
path: path?.slice(0, length + 1)
|
|
14
|
+
});
|
|
15
|
+
segments[seg + 1].distance -= segments[seg].distance;
|
|
16
|
+
segments[seg + 1].duration -= segments[seg].duration;
|
|
17
|
+
segments[seg + 1].path = path?.slice(length);
|
|
18
|
+
result.running += length;
|
|
19
|
+
result.seg += 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function extractRouteType(result, [from, to, type]) {
|
|
23
|
+
const { segments, types, updateSegment } = result;
|
|
24
|
+
if (!types[type]) {
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
while (result.running + segments[result.seg].path.length - 1 <= from) {
|
|
28
|
+
result.running += segments[result.seg].path.length - 1;
|
|
29
|
+
result.seg += 1;
|
|
30
|
+
}
|
|
31
|
+
const { running } = result;
|
|
32
|
+
splitSegment(result, from - running);
|
|
33
|
+
let { seg } = result;
|
|
34
|
+
splitSegment(result, to - from);
|
|
35
|
+
updateSegment(segments[seg]);
|
|
36
|
+
result.foundType = true;
|
|
37
|
+
if (result.seg === seg) {
|
|
38
|
+
while (result.running + segments[seg].path.length < to) {
|
|
39
|
+
const { length } = segments[seg].path;
|
|
40
|
+
from += length - 1;
|
|
41
|
+
result.running += length - 1;
|
|
42
|
+
result.seg += 1;
|
|
43
|
+
seg = result.seg;
|
|
44
|
+
splitSegment(result, to - from);
|
|
45
|
+
updateSegment(segments[seg]);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function tagRoute(tagSegments, params) {
|
|
52
|
+
params.seg = params.running = 0;
|
|
53
|
+
return tagSegments?.reduce(extractRouteType, params);
|
|
54
|
+
}
|
|
@@ -49,14 +49,21 @@ function extractSegment(result, {
|
|
|
49
49
|
length,
|
|
50
50
|
time,
|
|
51
51
|
rough,
|
|
52
|
+
toll,
|
|
52
53
|
travel_mode
|
|
53
54
|
}) {
|
|
54
55
|
const { directions: { segments, routes }, unitMultiplier, path } = result;
|
|
55
56
|
const distance = Math.round((length || 0) * unitMultiplier);
|
|
56
57
|
let duration = time;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
if (rough) {
|
|
59
|
+
util.last(routes).rough = true;
|
|
60
|
+
// for some reason Valhalla calculates absurdly low speed on some dirt roads
|
|
61
|
+
if (duration && travel_mode === 'drive' && distance > turnDistance && distance / duration < minSpeed) {
|
|
62
|
+
duration = Math.round(distance / minSpeed);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (toll) {
|
|
66
|
+
util.last(routes).tolls = true;
|
|
60
67
|
}
|
|
61
68
|
result.legDuration += duration;
|
|
62
69
|
const seg = {
|
|
@@ -65,6 +72,12 @@ function extractSegment(result, {
|
|
|
65
72
|
path: path && path.slice(begin_shape_index, end_shape_index),
|
|
66
73
|
instructions: instruction
|
|
67
74
|
};
|
|
75
|
+
if (rough) {
|
|
76
|
+
seg.rough = true;
|
|
77
|
+
}
|
|
78
|
+
if (toll) {
|
|
79
|
+
seg.tolls = true;
|
|
80
|
+
}
|
|
68
81
|
if (type === maneuver.ferryExit || result.ferry) {
|
|
69
82
|
if (result.ferry) {
|
|
70
83
|
delete result.ferry;
|
|
@@ -155,7 +168,7 @@ function getStatus(err, response) {
|
|
|
155
168
|
|
|
156
169
|
function vehicleSize(query, options) {
|
|
157
170
|
const { mode, vehicle } = query;
|
|
158
|
-
if (!(vehicle && mode ===
|
|
171
|
+
if (!(vehicle && mode === travelMode.rv)) {
|
|
159
172
|
return;
|
|
160
173
|
}
|
|
161
174
|
Object.assign(options, vehicle);
|
|
@@ -184,6 +197,14 @@ function init(options) {
|
|
|
184
197
|
} else {
|
|
185
198
|
req.costing_options[req.costing].use_highways = 1.1;
|
|
186
199
|
}
|
|
200
|
+
if (query.avoidFerry) {
|
|
201
|
+
req.costing_options[req.costing].use_ferry = 0;
|
|
202
|
+
} else {
|
|
203
|
+
req.costing_options[req.costing].use_ferry = 1;
|
|
204
|
+
}
|
|
205
|
+
if (query.avoidUnpaved) {
|
|
206
|
+
req.costing_options[req.costing].exclude_unpaved = true;
|
|
207
|
+
}
|
|
187
208
|
vehicleSize(query, req.costing_options[req.costing]);
|
|
188
209
|
|
|
189
210
|
if (query.begin) {
|