roadgraph-router-v2 0.1.0 → 0.3.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/CHANGELOG.md +348 -1
- package/README.md +729 -18
- package/dist/chunk-QSIKDM4A.js +2690 -0
- package/dist/index.d.ts +966 -89
- package/dist/index.js +624 -82
- package/dist/worker.js +2 -2
- package/package.json +2 -2
- package/scripts/roadgraph-compile.mjs +307 -76
- package/dist/chunk-4FIOQAFG.js +0 -1333
package/dist/index.d.ts
CHANGED
|
@@ -38,6 +38,37 @@ interface RoadGraph {
|
|
|
38
38
|
edgeDistanceScale?: number;
|
|
39
39
|
/** Edge duration values are multiplied by this scale. Omitted means seconds. */
|
|
40
40
|
edgeDurationScale?: number;
|
|
41
|
+
/**
|
|
42
|
+
* The routing profile this graph was compiled for, as a `ProfileId`. Absent
|
|
43
|
+
* means the graph predates profile metadata, and every such graph is a car
|
|
44
|
+
* graph. A graph only answers for the vehicle it was compiled for: a car
|
|
45
|
+
* graph has no footpaths in it to walk along.
|
|
46
|
+
*/
|
|
47
|
+
profileId?: number;
|
|
48
|
+
/**
|
|
49
|
+
* The profile's speed ceiling in km/h, carried so a reader can bound its A*
|
|
50
|
+
* heuristic and its tile budget without knowing the profile's rules. Absent
|
|
51
|
+
* falls back to the profile's own ceiling.
|
|
52
|
+
*/
|
|
53
|
+
maxSpeedKph?: number;
|
|
54
|
+
/**
|
|
55
|
+
* One bit per edge saying whether this profile may use it, present only on a
|
|
56
|
+
* graph assembled from a shared topology that several profiles share. Absent
|
|
57
|
+
* means every edge is usable. See `./access`.
|
|
58
|
+
*/
|
|
59
|
+
edgeAccess?: Uint8Array;
|
|
60
|
+
/**
|
|
61
|
+
* The physical limits in force on the few edges that state any. Present only
|
|
62
|
+
* for a profile whose routes depend on the vehicle's size. See `./limits`.
|
|
63
|
+
*/
|
|
64
|
+
edgeLimits?: EdgeLimits;
|
|
65
|
+
/** Conditional restrictions for the edges that carry one; absent when none do. */
|
|
66
|
+
edgeConditions?: EdgeConditions;
|
|
67
|
+
/**
|
|
68
|
+
* One bit per turn restriction, saying whether this vehicle obeys it. The
|
|
69
|
+
* pairs come first, then the sequences. Absent means all of them apply.
|
|
70
|
+
*/
|
|
71
|
+
restrictionMask?: Uint8Array;
|
|
41
72
|
/** Optional intermediate vertices per directed edge, stored using coordinateScale. */
|
|
42
73
|
edgeShapeOffsets?: Uint32Array;
|
|
43
74
|
edgeShapeLatitudes?: Int32Array;
|
|
@@ -71,6 +102,14 @@ interface RouteSnap {
|
|
|
71
102
|
point: Coordinate;
|
|
72
103
|
/** How far the requested coordinate was from that road. */
|
|
73
104
|
distanceMeters: number;
|
|
105
|
+
/**
|
|
106
|
+
* How far the route actually travels along that road, for an end that
|
|
107
|
+
* begins or finishes part-way along one. Zero where the end sits on a
|
|
108
|
+
* junction, and zero at the destination of a route that never leaves a
|
|
109
|
+
* single road, whose whole length is reported at the origin instead so
|
|
110
|
+
* that adding the two up gives the route and not twice the route.
|
|
111
|
+
*/
|
|
112
|
+
travelledMeters?: number;
|
|
74
113
|
}
|
|
75
114
|
interface RouteResult {
|
|
76
115
|
geometry: GeoJsonLineString;
|
|
@@ -92,6 +131,71 @@ declare class RouterError extends Error {
|
|
|
92
131
|
readonly code: RouterErrorCode;
|
|
93
132
|
constructor(code: RouterErrorCode, message: string);
|
|
94
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* Signed height, width, length and weight limits, for the edges that have them.
|
|
136
|
+
*
|
|
137
|
+
* A side table rather than four columns over every edge: the overwhelming
|
|
138
|
+
* majority of roads state no limit at all, so columns would spend four bytes
|
|
139
|
+
* per edge saying nothing nearly everywhere. `edges` is sorted, and the four
|
|
140
|
+
* arrays run alongside it. A zero means the limit is not stated, which is not
|
|
141
|
+
* the same as a limit of zero.
|
|
142
|
+
*/
|
|
143
|
+
interface EdgeLimits {
|
|
144
|
+
edges: Uint32Array;
|
|
145
|
+
/** Tenths of a metre. */
|
|
146
|
+
heightDecimetres: Uint8Array;
|
|
147
|
+
widthDecimetres: Uint8Array;
|
|
148
|
+
lengthDecimetres: Uint8Array;
|
|
149
|
+
/** Half-tonnes. */
|
|
150
|
+
weightHalfTonnes: Uint8Array;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Conditional restrictions for the few edges carrying one: the raw
|
|
154
|
+
* `value @ condition` text, kept as written and parsed when a bundle opens.
|
|
155
|
+
*
|
|
156
|
+
* A side table for the same reason the limits are one — a country has a few
|
|
157
|
+
* thousand of these among millions of edges. The text is deduplicated into
|
|
158
|
+
* `values`, because the same working-hours ban is repeated along every segment
|
|
159
|
+
* of the street it applies to. One edge may have several rows: a lorry ban and
|
|
160
|
+
* a night speed limit are both conditional and both apply.
|
|
161
|
+
*/
|
|
162
|
+
interface EdgeConditions {
|
|
163
|
+
/** Sorted by edge, then by kind; an edge may appear more than once. */
|
|
164
|
+
edges: Uint32Array;
|
|
165
|
+
/** What the value means: 0 is access, 1 is a speed limit in km/h. */
|
|
166
|
+
kinds: Uint8Array;
|
|
167
|
+
/** Index into `values`. */
|
|
168
|
+
rules: Uint16Array;
|
|
169
|
+
/** The deduplicated conditional values, as tagged. */
|
|
170
|
+
values: string[];
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* A tile's vehicle-independent half: everything a v7 `shared` chunk holds.
|
|
174
|
+
* It is not routable on its own — a profile supplies the durations.
|
|
175
|
+
*/
|
|
176
|
+
type SharedRoadGraph = Omit<RoadGraph, "edgeDurationsSeconds" | "edgeDurationScale" | "profileId" | "maxSpeedKph" | "edgeAccess">;
|
|
177
|
+
/** A tile's vehicle-dependent half: what a v7 `profile` chunk holds. */
|
|
178
|
+
interface ProfileChunk {
|
|
179
|
+
profileId: number;
|
|
180
|
+
maxSpeedKph: number;
|
|
181
|
+
edgeDurationScale: number;
|
|
182
|
+
edgeDurationsSeconds: Uint16Array;
|
|
183
|
+
/** One bit per edge; absent means this profile may use every road in the tile. */
|
|
184
|
+
edgeAccess?: Uint8Array;
|
|
185
|
+
/** Signed limits for the few edges that state any; absent for vehicles whose size does not matter. */
|
|
186
|
+
edgeLimits?: EdgeLimits;
|
|
187
|
+
/** Conditional restrictions for the edges that carry one; absent when none do. */
|
|
188
|
+
edgeConditions?: EdgeConditions;
|
|
189
|
+
/**
|
|
190
|
+
* One bit per turn restriction the shared chunk holds, saying whether this
|
|
191
|
+
* vehicle obeys it. `except=hgv` lifts a restriction for lorries and not for
|
|
192
|
+
* cars, so a shared restriction list needs a per-vehicle answer. Absent
|
|
193
|
+
* means every restriction applies.
|
|
194
|
+
*/
|
|
195
|
+
restrictionMask?: Uint8Array;
|
|
196
|
+
/** How many restrictions that mask covers: the pairs, then the sequences. */
|
|
197
|
+
restrictionCount?: number;
|
|
198
|
+
}
|
|
95
199
|
|
|
96
200
|
declare function encodeGraph(graph: RoadGraph): ArrayBuffer;
|
|
97
201
|
declare function decodeGraph(buffer: ArrayBuffer): RoadGraph;
|
|
@@ -110,6 +214,27 @@ type CompactEncodeOptions = {
|
|
|
110
214
|
layout?: "packed" | "legacy";
|
|
111
215
|
};
|
|
112
216
|
declare function encodeCompactGraph(graph: RoadGraph, options?: CompactEncodeOptions): ArrayBuffer;
|
|
217
|
+
/**
|
|
218
|
+
* The parts of a tile that do not depend on the vehicle. Identical to the v6
|
|
219
|
+
* layout except that the duration column is left out, because that is the one
|
|
220
|
+
* per-edge value a profile changes.
|
|
221
|
+
*/
|
|
222
|
+
declare function encodeSharedGraph(graph: RoadGraph): ArrayBuffer;
|
|
223
|
+
/**
|
|
224
|
+
* The vehicle-dependent half of a tile: the duration of every edge for this
|
|
225
|
+
* profile, and which edges it may use at all. An access mask that lets
|
|
226
|
+
* everything through is left out, which is the usual case for the profile a
|
|
227
|
+
* tile's topology was built around.
|
|
228
|
+
*/
|
|
229
|
+
declare function encodeProfileChunk(chunk: ProfileChunk): ArrayBuffer;
|
|
230
|
+
declare function decodeProfileChunk(buffer: ArrayBuffer): ProfileChunk;
|
|
231
|
+
/**
|
|
232
|
+
* The vehicle-independent half of a tile. Not routable on its own: every
|
|
233
|
+
* duration is zero until a profile chunk supplies them.
|
|
234
|
+
*/
|
|
235
|
+
declare function decodeSharedGraph(buffer: ArrayBuffer): SharedRoadGraph;
|
|
236
|
+
/** Joins a tile's two halves into the routable graph the rest of the library uses. */
|
|
237
|
+
declare function combineProfiledGraph(shared: SharedRoadGraph, profile: ProfileChunk): RoadGraph;
|
|
113
238
|
|
|
114
239
|
/**
|
|
115
240
|
* LEB128 variable-length integers, with zigzag for signed values.
|
|
@@ -155,6 +280,529 @@ type CompactGraphOptions = {
|
|
|
155
280
|
*/
|
|
156
281
|
declare function compactGraph(graph: RoadGraph, options?: CompactGraphOptions): RoadGraph;
|
|
157
282
|
|
|
283
|
+
/**
|
|
284
|
+
* Which edges a profile may use, as one bit per edge.
|
|
285
|
+
*
|
|
286
|
+
* A multi-profile bundle stores the road network once and the vehicle-specific
|
|
287
|
+
* parts separately, so the shared topology holds every road any of its
|
|
288
|
+
* profiles can drive. A profile that cannot use a road marks its bit clear
|
|
289
|
+
* rather than having the edge removed: edge numbers are what turn restrictions
|
|
290
|
+
* and shape references are written against, so they have to stay put.
|
|
291
|
+
*/
|
|
292
|
+
declare function accessMaskFor(edges: number, allowed: (edge: number) => boolean): Uint8Array<ArrayBuffer>;
|
|
293
|
+
/** An absent mask means every edge is usable, which is what a single-profile graph holds. */
|
|
294
|
+
declare function edgeAllowed(mask: Uint8Array | undefined, edge: number): boolean;
|
|
295
|
+
/** True when the mask lets every edge through, in which case it need not be stored. */
|
|
296
|
+
declare function allowsEverything(mask: Uint8Array, edges: number): boolean;
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* The two constants an A* search needs from a graph, measured once per graph
|
|
300
|
+
* rather than assumed.
|
|
301
|
+
*
|
|
302
|
+
* Both exist to keep the heuristic admissible — never larger than the true
|
|
303
|
+
* remaining cost — while making it as cheap and as tight as the data allows.
|
|
304
|
+
* An inadmissible heuristic does not merely slow a search down; it lets A*
|
|
305
|
+
* settle for a route that is not the best one.
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
type SearchBounds = {
|
|
309
|
+
/**
|
|
310
|
+
* The fastest any edge in this graph is actually travelled. Quantising a
|
|
311
|
+
* short edge's duration downwards can imply a speed above the profile's
|
|
312
|
+
* own ceiling, and dividing by the lower number would overestimate what
|
|
313
|
+
* remains, so the measured value is used rather than the declared one.
|
|
314
|
+
*/
|
|
315
|
+
maxSpeedMps: number;
|
|
316
|
+
/**
|
|
317
|
+
* Scales a longitude difference into metres using the highest latitude in
|
|
318
|
+
* the graph, where a degree of longitude is shortest. Under-estimating that
|
|
319
|
+
* everywhere keeps the straight-line estimate below the true distance.
|
|
320
|
+
*/
|
|
321
|
+
longitudeMetresPerDegree: number;
|
|
322
|
+
};
|
|
323
|
+
declare function searchBoundsFor(graph: RoadGraph): SearchBounds;
|
|
324
|
+
/**
|
|
325
|
+
* A lower bound on the great-circle distance between two points, without the
|
|
326
|
+
* four trigonometric calls a haversine needs. The heuristic asks for this once
|
|
327
|
+
* per relaxation — millions of times on a long route — and only ever needs a
|
|
328
|
+
* number that cannot exceed the truth.
|
|
329
|
+
*/
|
|
330
|
+
declare function straightLineAtMost(latitudeA: number, longitudeA: number, latitudeB: number, longitudeB: number, longitudeMetresPerDegree: number): number;
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Which parts of a graph are joined to which.
|
|
334
|
+
*
|
|
335
|
+
* A road network is not one piece. Service roads inside a compound, a path
|
|
336
|
+
* fragment behind a fence, a stretch clipped by the edge of a tile — all sit
|
|
337
|
+
* apart from the rest, and a point a couple of metres from one of them snaps
|
|
338
|
+
* to it rather than to the road just beyond. The route then fails although a
|
|
339
|
+
* perfectly good road was in reach.
|
|
340
|
+
*
|
|
341
|
+
* Labels are weak: an edge joins its two nodes whichever way it points. That
|
|
342
|
+
* is deliberately the cheap question. Two nodes in different pieces certainly
|
|
343
|
+
* cannot reach each other, which is what the snapper needs to know; two in the
|
|
344
|
+
* same piece usually can, and where a one-way trap says otherwise the search
|
|
345
|
+
* finds out for itself.
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
/** One label per node. Nodes sharing a label are joined, ignoring direction. */
|
|
349
|
+
declare function componentsFor(graph: RoadGraph): Int32Array;
|
|
350
|
+
/** How many nodes carry each label, so the smaller piece can be recognised. */
|
|
351
|
+
declare function componentSizes(labels: Int32Array): Map<number, number>;
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Roads the caller knows are shut.
|
|
355
|
+
*
|
|
356
|
+
* A compiled bundle is as current as the extract it came from: roadworks, a
|
|
357
|
+
* burst main, a festival closing the square are all things that happened
|
|
358
|
+
* after it was built, and nothing inside it can know about them. What it can
|
|
359
|
+
* do is let whoever does know say so at the time of asking.
|
|
360
|
+
*
|
|
361
|
+
* An area rather than a road, because a caller reading an incident feed has a
|
|
362
|
+
* place and a radius, not an edge number. Anything the circle touches is
|
|
363
|
+
* closed to the search and to snapping, exactly as a tagged restriction would
|
|
364
|
+
* be, so a route neither drives through a closure nor starts in the middle of
|
|
365
|
+
* one.
|
|
366
|
+
*/
|
|
367
|
+
|
|
368
|
+
/** A circle of road that cannot be driven, whatever the map says. */
|
|
369
|
+
type AvoidArea = {
|
|
370
|
+
lat: number;
|
|
371
|
+
lng: number;
|
|
372
|
+
/** How far the closure reaches from that point. */
|
|
373
|
+
radiusMeters: number;
|
|
374
|
+
};
|
|
375
|
+
/**
|
|
376
|
+
* Whether any part of this edge lies inside the circle.
|
|
377
|
+
*
|
|
378
|
+
* The whole of each segment counts, not only its ends: a motorway crossing a
|
|
379
|
+
* closed junction may have no shape point anywhere near it, and testing the
|
|
380
|
+
* ends alone would drive a route straight through.
|
|
381
|
+
*/
|
|
382
|
+
declare function touchesArea(graph: RoadGraph, edge: number, area: AvoidArea, centre?: Coordinate): boolean;
|
|
383
|
+
/**
|
|
384
|
+
* The access mask with every road the caller has closed cleared as well.
|
|
385
|
+
*
|
|
386
|
+
* Only the roads near each circle are looked at, so closing a junction costs
|
|
387
|
+
* the same whether the graph holds a town or a country.
|
|
388
|
+
*/
|
|
389
|
+
declare function accessAvoiding(graph: RoadGraph, areas: AvoidArea[] | undefined, base?: Uint8Array): Uint8Array | undefined;
|
|
390
|
+
/** How many roads these closures take away, for reporting rather than routing. */
|
|
391
|
+
declare function countAvoided(graph: RoadGraph, areas: AvoidArea[] | undefined): number;
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Reading a speed off an OSM tag.
|
|
395
|
+
*
|
|
396
|
+
* It lives on its own because both the profiles and the conditional
|
|
397
|
+
* restrictions need it, and a conditional limit is written in the same units
|
|
398
|
+
* as a plain one: `maxspeed:conditional = 30 mph @ (Mo-Fr 07:00-19:00)` means
|
|
399
|
+
* 30 mph, not 30 km/h.
|
|
400
|
+
*/
|
|
401
|
+
/** Kilometres per hour, or null when the value is not a speed this reads. */
|
|
402
|
+
declare function parseMaxSpeedKph(value: string | undefined): number | null;
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Routing profiles turn raw OSM tags into routable facts: may a vehicle use
|
|
406
|
+
* this way, in which directions, and how fast. Keeping the rules behind one
|
|
407
|
+
* interface lets the compiler stay generic — it never inspects a tag itself —
|
|
408
|
+
* and lets the rules be unit-tested without a PBF file.
|
|
409
|
+
*/
|
|
410
|
+
|
|
411
|
+
type OsmTags = Record<string, string | undefined>;
|
|
412
|
+
/** How a profile may traverse one OSM way. */
|
|
413
|
+
type WayTraversal = {
|
|
414
|
+
/**
|
|
415
|
+
* Conditional restrictions tagged on the way, kept as written for the
|
|
416
|
+
* router to evaluate against a departure time. They apply to both
|
|
417
|
+
* directions: OSM states these per vehicle class, not per direction.
|
|
418
|
+
*/
|
|
419
|
+
conditions?: {
|
|
420
|
+
kind: number;
|
|
421
|
+
value: string;
|
|
422
|
+
}[];
|
|
423
|
+
/** Travel from the first node reference towards the last is allowed. */
|
|
424
|
+
forward: boolean;
|
|
425
|
+
/** Travel from the last node reference towards the first is allowed. */
|
|
426
|
+
backward: boolean;
|
|
427
|
+
/** Travel speed in km/h in each direction; both are clamped to the profile range. */
|
|
428
|
+
forwardSpeedKph: number;
|
|
429
|
+
backwardSpeedKph: number;
|
|
430
|
+
/** Physical limits in force along this way, where the data states any. */
|
|
431
|
+
forwardLimits?: VehicleLimits;
|
|
432
|
+
backwardLimits?: VehicleLimits;
|
|
433
|
+
};
|
|
434
|
+
/** A turn restriction relation reduced to the only two cases routing cares about. */
|
|
435
|
+
type TurnRestrictionKind = "no" | "only";
|
|
436
|
+
/**
|
|
437
|
+
* A physical limit OSM states for a way. Every field is optional because an
|
|
438
|
+
* untagged limit is unknown, not absent: most bridges carry no `maxheight` at
|
|
439
|
+
* all, and treating silence as "no limit" is the assumption this library makes
|
|
440
|
+
* and says so, rather than inventing a number.
|
|
441
|
+
*/
|
|
442
|
+
type VehicleLimits = {
|
|
443
|
+
heightMeters?: number;
|
|
444
|
+
widthMeters?: number;
|
|
445
|
+
lengthMeters?: number;
|
|
446
|
+
weightTonnes?: number;
|
|
447
|
+
};
|
|
448
|
+
type ParsedTurnRestriction = {
|
|
449
|
+
kind: TurnRestrictionKind;
|
|
450
|
+
/** The raw OSM value, kept for diagnostics only. */
|
|
451
|
+
value: string;
|
|
452
|
+
};
|
|
453
|
+
/**
|
|
454
|
+
* Stable numeric ids written into compiled graphs. They are part of the file
|
|
455
|
+
* format, so a value is never reused for a different profile; 0 is reserved
|
|
456
|
+
* for graphs compiled before profiles were recorded, which were all cars.
|
|
457
|
+
*/
|
|
458
|
+
declare const ProfileId: {
|
|
459
|
+
readonly unspecified: 0;
|
|
460
|
+
readonly car: 1;
|
|
461
|
+
readonly truck: 2;
|
|
462
|
+
readonly motorcycle: 3;
|
|
463
|
+
readonly bicycle: 4;
|
|
464
|
+
readonly pedestrian: 5;
|
|
465
|
+
};
|
|
466
|
+
type ProfileId = (typeof ProfileId)[keyof typeof ProfileId];
|
|
467
|
+
interface RoutingProfile {
|
|
468
|
+
readonly name: string;
|
|
469
|
+
/** The id this profile is stored under. See `ProfileId`. */
|
|
470
|
+
readonly id: ProfileId;
|
|
471
|
+
/** Way tag keys the compiler must request from the PBF reader. */
|
|
472
|
+
readonly wayTagKeys: readonly string[];
|
|
473
|
+
/** Relation tag keys the compiler must request from the PBF reader. */
|
|
474
|
+
readonly relationTagKeys: readonly string[];
|
|
475
|
+
/** The fastest speed the profile can ever return, used for admissible A* heuristics. */
|
|
476
|
+
readonly maxSpeedKph: number;
|
|
477
|
+
/** Returns null when the way is not usable by this profile at all. */
|
|
478
|
+
evaluateWay(tags: OsmTags): WayTraversal | null;
|
|
479
|
+
/** Returns null when the relation is not a turn restriction this profile obeys. */
|
|
480
|
+
evaluateTurnRestriction(tags: OsmTags): ParsedTurnRestriction | null;
|
|
481
|
+
/**
|
|
482
|
+
* Whether this profile's routes depend on the vehicle's physical size, which
|
|
483
|
+
* tells the compiler to keep the limits `evaluateWay` reports.
|
|
484
|
+
*/
|
|
485
|
+
readonly usesPhysicalLimits?: boolean;
|
|
486
|
+
/** Node tag keys the compiler must request, for barriers. */
|
|
487
|
+
readonly nodeTagKeys?: readonly string[];
|
|
488
|
+
/**
|
|
489
|
+
* Whether this traveller gets past a barrier on the road. Returns true when
|
|
490
|
+
* the node is not a barrier at all, so an absent answer means "carry on".
|
|
491
|
+
*/
|
|
492
|
+
evaluateBarrier?(tags: OsmTags): boolean;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Reads a `maxheight`-style value in metres. Feet and inches are accepted
|
|
496
|
+
* because they are how the limit is written wherever it is signed that way;
|
|
497
|
+
* anything that is not a measurement reads as unknown rather than as zero,
|
|
498
|
+
* which would close the road to everything.
|
|
499
|
+
*/
|
|
500
|
+
declare function parseLengthMeters(value: string | undefined): number | null;
|
|
501
|
+
/** Reads a `maxweight`-style value in tonnes. A bare number is tonnes, as OSM defines it. */
|
|
502
|
+
declare function parseWeightTonnes(value: string | undefined): number | null;
|
|
503
|
+
declare const carRoutingProfile: RoutingProfile;
|
|
504
|
+
/**
|
|
505
|
+
* Motorcycles use the same roads and the same speed limits as cars almost
|
|
506
|
+
* everywhere, so the difference is which tags apply to them: `motorcycle=no`
|
|
507
|
+
* closes a road a car may still use, `oneway:motorcycle=no` opens one, and
|
|
508
|
+
* `except=motorcar` on a turn restriction does not let a motorcycle through.
|
|
509
|
+
*/
|
|
510
|
+
declare const motorcycleRoutingProfile: RoutingProfile;
|
|
511
|
+
/**
|
|
512
|
+
* Heavy goods vehicles. `hgv` is the OSM key for them, and it sits below
|
|
513
|
+
* `motor_vehicle` in the same ladder every motor vehicle uses.
|
|
514
|
+
*
|
|
515
|
+
* Two things set a lorry apart. It is slower: a heavy vehicle is capped below
|
|
516
|
+
* the posted limit almost everywhere, so a truck graph that reused car
|
|
517
|
+
* durations would give wrong arrival times on roads it is perfectly entitled
|
|
518
|
+
* to use. And it is large: height, width, length and weight limits decide
|
|
519
|
+
* whether a road is usable at all, which depends on the lorry rather than on
|
|
520
|
+
* the map, so those limits are carried through to be applied at routing time.
|
|
521
|
+
*/
|
|
522
|
+
declare const truckRoutingProfile: RoutingProfile;
|
|
523
|
+
declare const routingProfiles: Record<string, RoutingProfile>;
|
|
524
|
+
declare function getRoutingProfile(name: string): RoutingProfile;
|
|
525
|
+
/** The profile a stored id refers to, or null when this build does not know it. */
|
|
526
|
+
declare function getRoutingProfileById(id: number): RoutingProfile | null;
|
|
527
|
+
/**
|
|
528
|
+
* A graph compiled before profiles were recorded is a car graph, which is what
|
|
529
|
+
* every bundle published up to v0.1.0 holds.
|
|
530
|
+
*/
|
|
531
|
+
declare function profileOf(graph: {
|
|
532
|
+
profileId?: number;
|
|
533
|
+
}): RoutingProfile;
|
|
534
|
+
/**
|
|
535
|
+
* The speed ceiling a search may assume, in metres per second. The value
|
|
536
|
+
* stored in the graph wins over this build's table, so a bundle compiled by a
|
|
537
|
+
* newer version still bounds an older reader's heuristic correctly.
|
|
538
|
+
*/
|
|
539
|
+
declare function maxSpeedMpsFor(graph: {
|
|
540
|
+
profileId?: number;
|
|
541
|
+
maxSpeedKph?: number;
|
|
542
|
+
}): number;
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* The lorry a truck route iscalculated for.
|
|
546
|
+
*
|
|
547
|
+
* A caller who says nothing still gets a vehicle, because refusing to route
|
|
548
|
+
* until a form is filled in is worse than routing for a stated default. The
|
|
549
|
+
* danger is not having a default, it is a default nobody can see, so the
|
|
550
|
+
* resolved dimensions ride on every truck route.
|
|
551
|
+
*
|
|
552
|
+
* There is no globally neutral lorry. EU general circulation is 2.55m wide,
|
|
553
|
+
* 16.5m long articulated and 40t on a five-axle vehicle no taller than 4m;
|
|
554
|
+
* a US semi is wider and taller at 2.59m and about 4.11m but lighter at
|
|
555
|
+
* 36.3t, and Nordic combinations run longer and heavier still. Guessing large
|
|
556
|
+
* on every axis is not safe either: `maxheight=4.0` and `maxweight=40` are
|
|
557
|
+
* among the commonly tagged limits in Europe, so a 4.2m default would refuse
|
|
558
|
+
* bridges an ordinary lorry crosses daily. The presets below are therefore
|
|
559
|
+
* vehicle classes a caller picks, not a guess about where they are.
|
|
560
|
+
*/
|
|
561
|
+
|
|
562
|
+
type VehicleDimensions = {
|
|
563
|
+
heightMeters: number;
|
|
564
|
+
widthMeters: number;
|
|
565
|
+
lengthMeters: number;
|
|
566
|
+
weightTonnes: number;
|
|
567
|
+
};
|
|
568
|
+
/**
|
|
569
|
+
* Stable ids, so a bundle can name its default vehicle in one byte. They are
|
|
570
|
+
* part of the file format: a value is never reused for a different class, and
|
|
571
|
+
* 0 means the bundle states no default, which falls back to the library's.
|
|
572
|
+
*/
|
|
573
|
+
declare const VehiclePresetId: Record<string, number>;
|
|
574
|
+
declare function vehiclePresetName(id: number): string | null;
|
|
575
|
+
declare const VEHICLE_PRESETS: Record<string, VehicleDimensions>;
|
|
576
|
+
/**
|
|
577
|
+
* What a truck route uses when nothing else says otherwise. An articulated
|
|
578
|
+
* lorry is what most people mean by "truck" for freight, and it matches the
|
|
579
|
+
* envelope European road data is implicitly tagged against.
|
|
580
|
+
*/
|
|
581
|
+
declare const DEFAULT_VEHICLE_PRESET = "articulated";
|
|
582
|
+
/** A preset name, a full set of dimensions, or a preset with fields overridden. */
|
|
583
|
+
type VehicleInput = string | Partial<VehicleDimensions> & {
|
|
584
|
+
preset?: string;
|
|
585
|
+
};
|
|
586
|
+
declare function vehiclePreset(name: string): VehicleDimensions;
|
|
587
|
+
/**
|
|
588
|
+
* Resolves what a caller asked for against a preset, so `{ preset:
|
|
589
|
+
* "articulated", heightMeters: 4.3 }` is a standard lorry with a taller load
|
|
590
|
+
* rather than a vehicle with three dimensions missing.
|
|
591
|
+
*/
|
|
592
|
+
declare function resolveVehicle(input: VehicleInput | undefined, fallbackPreset?: string): VehicleDimensions;
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Turning signed limits into the handful of bytes a bundle stores, and back
|
|
596
|
+
* into a yes or no for one lorry.
|
|
597
|
+
*
|
|
598
|
+
* Quantisation always rounds a limit *down*, so a stored value never permits
|
|
599
|
+
* what the sign forbids. A limit too large to store is stored as "not stated"
|
|
600
|
+
* rather than clamped, because a clamped value would forbid what the sign
|
|
601
|
+
* permits, and a limit that high restricts nothing any lorry cares about.
|
|
602
|
+
*/
|
|
603
|
+
|
|
604
|
+
/** Zero means "not stated"; a limit above what fits is treated the same way. */
|
|
605
|
+
declare function toDecimetres(metres: number | undefined): number;
|
|
606
|
+
declare function toHalfTonnes(tonnes: number | undefined): number;
|
|
607
|
+
declare const fromDecimetres: (value: number) => number;
|
|
608
|
+
declare const fromHalfTonnes: (value: number) => number;
|
|
609
|
+
/** Collects the per-edge limits a compiler gathered into the stored side table. */
|
|
610
|
+
declare function packEdgeLimits(entries: {
|
|
611
|
+
edge: number;
|
|
612
|
+
limits: VehicleLimits;
|
|
613
|
+
}[]): EdgeLimits | undefined;
|
|
614
|
+
/**
|
|
615
|
+
* The access mask a search should use for one lorry: the profile's own mask
|
|
616
|
+
* with the roads this vehicle is too big or too heavy for cleared as well.
|
|
617
|
+
* Roads stating no limit stay open, which is the assumption this library makes
|
|
618
|
+
* and documents: an untagged bridge is not a measured one.
|
|
619
|
+
*/
|
|
620
|
+
declare function accessForVehicle(graph: RoadGraph, vehicle: VehicleDimensions | undefined): Uint8Array | undefined;
|
|
621
|
+
/** How many edges this vehicle may not use, for reporting rather than routing. */
|
|
622
|
+
declare function countBlocked(graph: RoadGraph, vehicle: VehicleDimensions): number;
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Conditional restrictions: `hgv:conditional = no @ (Mo-Fr 07:00-19:00)`.
|
|
626
|
+
*
|
|
627
|
+
* A road can be closed overnight, a square pedestrianised on Sundays, a bridge
|
|
628
|
+
* limited to 7.5 tonnes only for vehicles over a certain length. Until now
|
|
629
|
+
* every one of those read as permanently open, which is the limitation most
|
|
630
|
+
* likely to make a route wrong rather than merely longer.
|
|
631
|
+
*
|
|
632
|
+
* The value is a list of `value @ condition` pairs separated by semicolons,
|
|
633
|
+
* and where several match, OpenStreetMap says the **last** one wins — the
|
|
634
|
+
* convention being to write the general rule first and the specific one last.
|
|
635
|
+
*
|
|
636
|
+
* Not every condition can be answered. Weather, a driver's occupation and a
|
|
637
|
+
* stay duration are not things a compiled graph knows, and a rule resting on
|
|
638
|
+
* one is kept but marked, so a caller can count what was not understood
|
|
639
|
+
* instead of being told silently that a road is open.
|
|
640
|
+
*/
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* How many distinct conditional values one table can hold. The stored index
|
|
644
|
+
* is sixteen bits wide, so the values are numbered 0 to 65535.
|
|
645
|
+
*/
|
|
646
|
+
declare const MAX_STORED_VALUES = 65536;
|
|
647
|
+
/** When a journey passes, in the local time of the road it passes on. */
|
|
648
|
+
type TravelTime = {
|
|
649
|
+
/** 0 is Monday, 6 is Sunday. */
|
|
650
|
+
weekday: number;
|
|
651
|
+
/** Minutes since midnight, 0 to 1439. */
|
|
652
|
+
minutes: number;
|
|
653
|
+
/** 1 to 12, for a seasonal rule. */
|
|
654
|
+
month: number;
|
|
655
|
+
/**
|
|
656
|
+
* The day of the month, 1 to 31. Only a span running past midnight needs
|
|
657
|
+
* it, to know whether the morning it ends on began in the month before.
|
|
658
|
+
* Leaving it out treats such a morning as belonging to the current month,
|
|
659
|
+
* which is right on every day but the first.
|
|
660
|
+
*/
|
|
661
|
+
dayOfMonth?: number;
|
|
662
|
+
/** Whether it is a public holiday there, which only a caller can know. */
|
|
663
|
+
publicHoliday?: boolean;
|
|
664
|
+
};
|
|
665
|
+
/** A span of minutes within a day, which may run past midnight. */
|
|
666
|
+
type MinuteSpan = {
|
|
667
|
+
from: number;
|
|
668
|
+
to: number;
|
|
669
|
+
};
|
|
670
|
+
/** An inclusive range of weekdays, months, or anything else counted in order. */
|
|
671
|
+
type Range = {
|
|
672
|
+
from: number;
|
|
673
|
+
to: number;
|
|
674
|
+
};
|
|
675
|
+
/** A measurement of the vehicle compared against a number, as `weight>7.5`. */
|
|
676
|
+
type VehicleComparison = {
|
|
677
|
+
property: "weight" | "height" | "width" | "length";
|
|
678
|
+
operator: "<" | "<=" | ">" | ">=" | "=";
|
|
679
|
+
amount: number;
|
|
680
|
+
};
|
|
681
|
+
/** One `(...)` group: every part present must hold for the group to match. */
|
|
682
|
+
type Condition = {
|
|
683
|
+
days?: Range[];
|
|
684
|
+
times?: MinuteSpan[];
|
|
685
|
+
months?: Range[];
|
|
686
|
+
publicHoliday?: boolean;
|
|
687
|
+
vehicle?: VehicleComparison[];
|
|
688
|
+
/**
|
|
689
|
+
* Circumstances this library cannot know by itself: the weather, who is
|
|
690
|
+
* driving, what for. They are read from the tag and answered only by a
|
|
691
|
+
* caller who says so; unanswered, the condition does not hold.
|
|
692
|
+
*/
|
|
693
|
+
circumstances?: string[];
|
|
694
|
+
/**
|
|
695
|
+
* The part of the condition this parser could not read at all — a stay
|
|
696
|
+
* duration, a form of words nobody has taught it. A condition carrying one
|
|
697
|
+
* is never matched, and is counted so it can be reported rather than
|
|
698
|
+
* quietly ignored.
|
|
699
|
+
*/
|
|
700
|
+
unreadable?: string;
|
|
701
|
+
};
|
|
702
|
+
/**
|
|
703
|
+
* What the caller knows that the map does not: whether it is raining, who is
|
|
704
|
+
* at the wheel, what the journey is for. A conditional rule resting on one of
|
|
705
|
+
* these is ignored unless the answer is given here.
|
|
706
|
+
*/
|
|
707
|
+
type Circumstances = {
|
|
708
|
+
/** Named states of the road or sky, such as `wet`, `snow`, `ice`. */
|
|
709
|
+
conditions?: string[];
|
|
710
|
+
/** Who is driving, such as `disabled`, `resident`, `emergency`. */
|
|
711
|
+
userGroups?: string[];
|
|
712
|
+
/** Why, such as `delivery`, `destination`, `agricultural`. */
|
|
713
|
+
purposes?: string[];
|
|
714
|
+
};
|
|
715
|
+
type ConditionalRule = {
|
|
716
|
+
/** What applies when the condition holds: `no`, `destination`, `30`, `7.5`. */
|
|
717
|
+
value: string;
|
|
718
|
+
/** Any of these matching makes the rule apply, as `Mo-Fr 07:00-19:00, Sa 08:00-12:00`. */
|
|
719
|
+
conditions: Condition[];
|
|
720
|
+
};
|
|
721
|
+
/**
|
|
722
|
+
* Reads a `*:conditional` value into its rules. An empty list means the value
|
|
723
|
+
* was not a conditional expression at all.
|
|
724
|
+
*/
|
|
725
|
+
declare function parseConditional(value: string | undefined): ConditionalRule[];
|
|
726
|
+
/** Whether one condition group holds at this moment, for this vehicle. */
|
|
727
|
+
declare function conditionHolds(condition: Condition, when: TravelTime, vehicle?: VehicleDimensions, circumstances?: Circumstances): boolean;
|
|
728
|
+
/**
|
|
729
|
+
* What a conditional value comes to at this moment, or null when none of its
|
|
730
|
+
* rules applies. Where several match, the last wins, which is what
|
|
731
|
+
* OpenStreetMap says and why the convention is general first, specific last.
|
|
732
|
+
*/
|
|
733
|
+
declare function conditionalValue(rules: ConditionalRule[], when: TravelTime, vehicle?: VehicleDimensions, circumstances?: Circumstances): string | null;
|
|
734
|
+
/**
|
|
735
|
+
* How many of these rules rest on something this parser cannot read at all.
|
|
736
|
+
* A rule resting on the weather or on who is driving is readable and is not
|
|
737
|
+
* counted here; it simply needs a caller to answer it.
|
|
738
|
+
*/
|
|
739
|
+
declare function unreadableConditions(rules: ConditionalRule[]): number;
|
|
740
|
+
/**
|
|
741
|
+
* The moment a journey is travelled.
|
|
742
|
+
*
|
|
743
|
+
* Without a time zone the date is read as the machine reads it, which is
|
|
744
|
+
* right when the roads and the reader are in the same place and wrong by
|
|
745
|
+
* however many hours when they are not. Naming the zone the roads are in —
|
|
746
|
+
* `"Europe/Lisbon"` — reads the date there instead, which is what a
|
|
747
|
+
* restriction written in local time means.
|
|
748
|
+
*
|
|
749
|
+
* The zone names are the IANA ones the platform already knows; nothing is
|
|
750
|
+
* bundled for this.
|
|
751
|
+
*/
|
|
752
|
+
declare function travelTimeFrom(date: Date, publicHoliday?: boolean, timeZone?: string): TravelTime;
|
|
753
|
+
/** What a stored conditional row says: an access rule or a speed limit. */
|
|
754
|
+
declare const ConditionKind: {
|
|
755
|
+
readonly access: 0;
|
|
756
|
+
readonly maxspeed: 1;
|
|
757
|
+
};
|
|
758
|
+
/** Collects what a compiler found into the stored side table. */
|
|
759
|
+
declare function packEdgeConditions(entries: {
|
|
760
|
+
edge: number;
|
|
761
|
+
kind: number;
|
|
762
|
+
value: string;
|
|
763
|
+
}[]): EdgeConditions | undefined;
|
|
764
|
+
/** A bundle's conditional values parsed once, rather than per edge per search. */
|
|
765
|
+
type ParsedConditions = {
|
|
766
|
+
table: EdgeConditions;
|
|
767
|
+
parsed: ConditionalRule[][];
|
|
768
|
+
};
|
|
769
|
+
declare function parseEdgeConditions(table: EdgeConditions | undefined): ParsedConditions | undefined;
|
|
770
|
+
/**
|
|
771
|
+
* What the conditional rules say about one edge at one moment: whether it is
|
|
772
|
+
* closed, and any speed limit that applies.
|
|
773
|
+
*
|
|
774
|
+
* `destination` and the permit-style values count as closed because this
|
|
775
|
+
* library has no notion of a journey's purpose, and treating "only if you live
|
|
776
|
+
* here" as open would route strangers down a residents' street.
|
|
777
|
+
*/
|
|
778
|
+
declare function conditionsOnEdge(conditions: ParsedConditions, edge: number, when: TravelTime, vehicle?: VehicleDimensions, circumstances?: Circumstances): {
|
|
779
|
+
closed: boolean;
|
|
780
|
+
speedKph: number | undefined;
|
|
781
|
+
};
|
|
782
|
+
/**
|
|
783
|
+
* The access mask for a departure time: the graph's own with the roads shut at
|
|
784
|
+
* that moment cleared as well.
|
|
785
|
+
*
|
|
786
|
+
* Only closures are applied. A road whose plain tags already forbid it stays
|
|
787
|
+
* forbidden even where a conditional value would open it, because the stored
|
|
788
|
+
* mask has already dropped it and reopening one would need the compiler to
|
|
789
|
+
* keep roads it currently discards. That errs towards refusing a road that is
|
|
790
|
+
* in fact usable, which is the direction this library errs in everywhere else.
|
|
791
|
+
*/
|
|
792
|
+
declare function accessAtTime(graph: Pick<RoadGraph, "edgeTargets" | "edgeAccess">, conditions: ParsedConditions | undefined, when: TravelTime | undefined, vehicle?: VehicleDimensions, base?: Uint8Array, circumstances?: Circumstances): Uint8Array | undefined;
|
|
793
|
+
/** How many edges this moment closes, for reporting rather than routing. */
|
|
794
|
+
declare function countClosedAt(graph: Pick<RoadGraph, "edgeTargets" | "edgeAccess">, conditions: ParsedConditions | undefined, when: TravelTime, vehicle?: VehicleDimensions): number;
|
|
795
|
+
declare function conditionsOf(graph: Pick<RoadGraph, "edgeConditions">): ParsedConditions | undefined;
|
|
796
|
+
/**
|
|
797
|
+
* The edges a conditional speed limit slows at this moment, as whole seconds.
|
|
798
|
+
*
|
|
799
|
+
* A conditional limit may only slow an edge, never speed it up. A faster
|
|
800
|
+
* stored duration is left alone, because the A* bound is built from the
|
|
801
|
+
* profile's ceiling and an edge quicker than the graph says would break the
|
|
802
|
+
* guarantee that the route found is the best one.
|
|
803
|
+
*/
|
|
804
|
+
declare function conditionalDurations(graph: Pick<RoadGraph, "edgeTargets" | "edgeDistancesMeters" | "edgeDistanceScale" | "edgeDurationsSeconds" | "edgeDurationScale">, conditions: ParsedConditions | undefined, when: TravelTime, vehicle?: VehicleDimensions, circumstances?: Circumstances): Map<number, number> | undefined;
|
|
805
|
+
|
|
158
806
|
/**
|
|
159
807
|
* The nearest routing node to a coordinate. After topology simplification a
|
|
160
808
|
* node is a junction rather than an arbitrary point on a road, so on a long
|
|
@@ -170,9 +818,235 @@ declare function findNearestNode(graph: RoadGraph, coordinate: Coordinate, maxDi
|
|
|
170
818
|
*/
|
|
171
819
|
type RouteOptions = {
|
|
172
820
|
costBound?: number;
|
|
821
|
+
/**
|
|
822
|
+
* The lorry being routed, where the graph states physical limits. Roads it
|
|
823
|
+
* is too large or too heavy for are closed to the search and to snapping.
|
|
824
|
+
*/
|
|
825
|
+
vehicle?: VehicleDimensions;
|
|
826
|
+
/**
|
|
827
|
+
* When the journey starts, in the local time of the roads being travelled.
|
|
828
|
+
*
|
|
829
|
+
* Leaving it out ignores every conditional restriction, which is what this
|
|
830
|
+
* library did before it could read them: a road closed only at certain hours
|
|
831
|
+
* counts as open. Supplying it closes the roads shut at that moment and
|
|
832
|
+
* slows the ones a conditional speed limit slows.
|
|
833
|
+
*
|
|
834
|
+
* One moment is used for the whole route rather than an arrival time per
|
|
835
|
+
* edge. A route crossing a boundary as a restriction begins is therefore
|
|
836
|
+
* judged by where it set out, which is the honest limit of a departure time.
|
|
837
|
+
*/
|
|
838
|
+
departAt?: Date | TravelTime;
|
|
839
|
+
/** Whether that day is a public holiday, which only a caller can know. */
|
|
840
|
+
publicHoliday?: boolean;
|
|
841
|
+
/**
|
|
842
|
+
* The time zone the roads are in, as an IANA name such as
|
|
843
|
+
* `"Europe/Lisbon"`. A restriction is written in the local time of the road
|
|
844
|
+
* it is on, so a caller routing somewhere other than where it is running
|
|
845
|
+
* should say where. Left out, a `Date` is read as this machine reads it.
|
|
846
|
+
*/
|
|
847
|
+
timeZone?: string;
|
|
848
|
+
/**
|
|
849
|
+
* What the map cannot know: whether it is raining, who is driving, what the
|
|
850
|
+
* journey is for. A conditional rule resting on one of these is ignored
|
|
851
|
+
* unless it is answered here, so a road shut `@ (wet)` stays open until a
|
|
852
|
+
* caller says it is wet.
|
|
853
|
+
*/
|
|
854
|
+
circumstances?: Circumstances;
|
|
855
|
+
/**
|
|
856
|
+
* Roads the caller knows are shut — roadworks, an incident, an event. A
|
|
857
|
+
* compiled bundle cannot know about any of them; whoever is reading a feed
|
|
858
|
+
* of them can say so here, and the search will neither drive through a
|
|
859
|
+
* closure nor begin in the middle of one.
|
|
860
|
+
*/
|
|
861
|
+
avoid?: AvoidArea[];
|
|
862
|
+
/**
|
|
863
|
+
* Multipliers making certain edges dearer to the search than they really
|
|
864
|
+
* are, used to push a search away from a route already found. The route
|
|
865
|
+
* reported back is always priced at the graph's own cost, so a penalty
|
|
866
|
+
* changes which roads are chosen and never what they are said to cost.
|
|
867
|
+
*/
|
|
868
|
+
costPenalties?: ReadonlyMap<number, number>;
|
|
869
|
+
/**
|
|
870
|
+
* Whether a route that cannot reach the road nearest its destination may
|
|
871
|
+
* finish on one a little further away. On by default, because the nearest
|
|
872
|
+
* road is sometimes one the network cannot legally enter — a pocket of
|
|
873
|
+
* one-way streets behind banned turns, an island of service roads — and
|
|
874
|
+
* refusing to route at all is a worse answer than finishing nearby.
|
|
875
|
+
*
|
|
876
|
+
* Turn it off to be told plainly that the point asked for cannot be
|
|
877
|
+
* reached. `RouteResult.destinationSnap.distanceMeters` reports how far
|
|
878
|
+
* short a route finished either way.
|
|
879
|
+
*/
|
|
880
|
+
finishOnANearbyRoad?: boolean;
|
|
173
881
|
};
|
|
174
882
|
declare function route(graph: RoadGraph, from: Coordinate, to: Coordinate, preference?: RoutePreference, options?: RouteOptions): RouteResult;
|
|
175
883
|
|
|
884
|
+
/**
|
|
885
|
+
* Several ways to get there, not just the best one.
|
|
886
|
+
*
|
|
887
|
+
* A second route is only worth offering if it is genuinely different and not
|
|
888
|
+
* much worse. The method here is the simple one: find the best route, make the
|
|
889
|
+
* roads it used dearer to the search than they really are, and search again.
|
|
890
|
+
* A road that is the only sensible way through survives the penalty and is
|
|
891
|
+
* used again; one that was merely convenient gives way to its neighbour.
|
|
892
|
+
*
|
|
893
|
+
* The penalty never reaches the answer. A route is always reported at the
|
|
894
|
+
* graph's own cost, so an alternative's distance and duration are what it
|
|
895
|
+
* would really take, not what the search was told to believe.
|
|
896
|
+
*
|
|
897
|
+
* Candidates are then filtered rather than trusted: one that reuses most of a
|
|
898
|
+
* route already offered, or that is far worse than the best, is not an
|
|
899
|
+
* alternative anybody wants. What comes back is in order, best first.
|
|
900
|
+
*/
|
|
901
|
+
|
|
902
|
+
type AlternativeRoutesOptions = Omit<RouteOptions, "costPenalties" | "costBound"> & {
|
|
903
|
+
/** How many routes to return at most, the best one included. Default 3. */
|
|
904
|
+
count?: number;
|
|
905
|
+
/**
|
|
906
|
+
* How much worse than the best route an alternative may be. 1.4 allows one
|
|
907
|
+
* taking 40% longer; raising it offers more routes and worse ones.
|
|
908
|
+
*/
|
|
909
|
+
maxStretch?: number;
|
|
910
|
+
/**
|
|
911
|
+
* How much of the routes already offered an alternative may reuse, measured
|
|
912
|
+
* by distance. 0.75 rejects one that is three-quarters the same road.
|
|
913
|
+
*/
|
|
914
|
+
maxSharing?: number;
|
|
915
|
+
/**
|
|
916
|
+
* How much dearer a road already used is made to look. Too small and the
|
|
917
|
+
* search returns the same route again; too large and it flees onto
|
|
918
|
+
* absurdities. Default 2.
|
|
919
|
+
*/
|
|
920
|
+
penaltyFactor?: number;
|
|
921
|
+
/**
|
|
922
|
+
* Whether to download the wider corridor an alternative might lie in.
|
|
923
|
+
*
|
|
924
|
+
* On by default, because an alternative is allowed to be worse than the
|
|
925
|
+
* best by `maxStretch` and the tiles holding one therefore reach further
|
|
926
|
+
* than the tiles that proved the best route. On a long journey that is
|
|
927
|
+
* about three megabytes more map. Turning it off keeps the download to
|
|
928
|
+
* what one route needed and offers only the alternatives already inside
|
|
929
|
+
* it, which on a dense network is usually most of them.
|
|
930
|
+
*/
|
|
931
|
+
searchWiderCorridor?: boolean;
|
|
932
|
+
};
|
|
933
|
+
/**
|
|
934
|
+
* Rejects options that would make the search unbounded or meaningless.
|
|
935
|
+
*
|
|
936
|
+
* Exported so the public entry point can refuse them before it downloads
|
|
937
|
+
* anything: a caller who passed `count: NaN` should be told so, not billed
|
|
938
|
+
* for a corridor first.
|
|
939
|
+
*/
|
|
940
|
+
declare function checkAlternativeOptions(options: AlternativeRoutesOptions): void;
|
|
941
|
+
/**
|
|
942
|
+
* Routes from one point to another, best first, with up to `count - 1`
|
|
943
|
+
* genuinely different alternatives after it.
|
|
944
|
+
*
|
|
945
|
+
* Returns at least the best route; fewer than `count` means the graph held
|
|
946
|
+
* nothing else worth offering, which is the usual answer on a road network
|
|
947
|
+
* with one obvious way through.
|
|
948
|
+
*/
|
|
949
|
+
declare function routeAlternatives(graph: RoadGraph, from: Coordinate, to: Coordinate, preference?: RoutePreference, options?: AlternativeRoutesOptions): RouteResult[];
|
|
950
|
+
|
|
951
|
+
type FetchLike$2 = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
952
|
+
/**
|
|
953
|
+
* Caps how far off the straight line the confirmation pass will reach, as a
|
|
954
|
+
* multiple of the direct distance. `Infinity` leaves the search bounded only
|
|
955
|
+
* by the route already found, which makes the answer the best the compiled
|
|
956
|
+
* graph holds; a finite value trades that proof for a smaller download and
|
|
957
|
+
* still ignores tile size, since the limit is a ground distance.
|
|
958
|
+
*/
|
|
959
|
+
type RoadRouterOptions = {
|
|
960
|
+
maxDetourFactor?: number;
|
|
961
|
+
/** How many stitched corridors a bundle keeps; see `BundleOpenOptions`. */
|
|
962
|
+
mergedCacheSize?: number;
|
|
963
|
+
/**
|
|
964
|
+
* Which vehicle to route as. Only a multi-profile bundle offers a choice;
|
|
965
|
+
* leaving it out uses the vehicle the bundle was compiled around.
|
|
966
|
+
*/
|
|
967
|
+
profile?: string;
|
|
968
|
+
/**
|
|
969
|
+
* The lorry's size and weight, for a profile whose routes depend on them. A
|
|
970
|
+
* preset name, a set of dimensions, or a preset with fields overridden.
|
|
971
|
+
* `null` turns the filtering off, which is a decision to accept routes no
|
|
972
|
+
* real lorry may be able to drive.
|
|
973
|
+
*/
|
|
974
|
+
vehicle?: VehicleInput | null;
|
|
975
|
+
};
|
|
976
|
+
/**
|
|
977
|
+
* High-level route entry point. `open()` accepts an EFRB bundle, an EFRT
|
|
978
|
+
* manifest, or an already-decoded graph.
|
|
979
|
+
*/
|
|
980
|
+
/** When a journey starts, for the conditional restrictions that depend on it. */
|
|
981
|
+
type DepartureOptions = Pick<RouteOptions, "departAt" | "publicHoliday" | "timeZone" | "circumstances" | "avoid">;
|
|
982
|
+
declare class RoadRouter {
|
|
983
|
+
private readonly graph?;
|
|
984
|
+
private readonly loader?;
|
|
985
|
+
private readonly options;
|
|
986
|
+
private readonly profileId?;
|
|
987
|
+
private readonly bundleVehicle?;
|
|
988
|
+
private constructor();
|
|
989
|
+
/** The lorry these routes are for, where the profile depends on one. */
|
|
990
|
+
readonly vehicle?: VehicleDimensions;
|
|
991
|
+
static fromGraph(graph: RoadGraph): RoadRouter;
|
|
992
|
+
/**
|
|
993
|
+
* Asking for dimensions a profile cannot act on is a mistake worth saying
|
|
994
|
+
* out loud: accepting them silently would look like they had been applied.
|
|
995
|
+
* It is checked where the caller made the pairing, not when switching
|
|
996
|
+
* profiles, where carrying them over is deliberate.
|
|
997
|
+
*/
|
|
998
|
+
private static assertVehicleApplies;
|
|
999
|
+
static open(source: string | RoadGraph, fetcher?: FetchLike$2, options?: RoadRouterOptions): Promise<RoadRouter>;
|
|
1000
|
+
/** The vehicle this router is routing as, when the source names one. */
|
|
1001
|
+
get profile(): string | undefined;
|
|
1002
|
+
/**
|
|
1003
|
+
* Every vehicle this source can be read as, so a caller can offer a choice
|
|
1004
|
+
* without knowing how the bundle was compiled. A bundle holding one vehicle
|
|
1005
|
+
* reports that one, and a plain graph reports none.
|
|
1006
|
+
*/
|
|
1007
|
+
get profiles(): string[];
|
|
1008
|
+
/**
|
|
1009
|
+
* The same bundle read as another vehicle. The shared half of every tile is
|
|
1010
|
+
* already downloaded and stays so, which is the point of storing the road
|
|
1011
|
+
* network once: switching vehicle costs only the small per-vehicle chunks.
|
|
1012
|
+
*/
|
|
1013
|
+
withProfile(name: string): RoadRouter;
|
|
1014
|
+
/**
|
|
1015
|
+
* `when` says when the journey starts, so conditional restrictions apply.
|
|
1016
|
+
* Leaving it out ignores them, which is how this library behaved before it
|
|
1017
|
+
* could read them.
|
|
1018
|
+
*/
|
|
1019
|
+
route(from: Coordinate, to: Coordinate, preference?: RoutePreference, when?: DepartureOptions): Promise<RouteResult>;
|
|
1020
|
+
/**
|
|
1021
|
+
* Downloads a corridor, routes, then asks whether any tile left out could
|
|
1022
|
+
* still hold something better. A route through a tile costs at least the
|
|
1023
|
+
* detour to reach it, so the answer is a geometric test against the route
|
|
1024
|
+
* already found: tiles that fail it are provably useless and stay
|
|
1025
|
+
* undownloaded, and when none passes, the route is the best the compiled
|
|
1026
|
+
* graph contains. Because the test measures ground distance rather than
|
|
1027
|
+
* counting neighbours, the answer does not depend on the tile size.
|
|
1028
|
+
*/
|
|
1029
|
+
/**
|
|
1030
|
+
* Several ways there, best first, with up to `count - 1` alternatives after
|
|
1031
|
+
* it. Fewer than asked for means the network held nothing else worth
|
|
1032
|
+
* offering, which is the usual answer where there is one obvious way.
|
|
1033
|
+
*
|
|
1034
|
+
* Over a bundle this downloads a wider corridor than a single route needs:
|
|
1035
|
+
* an alternative may be worse than the best by as much as `maxStretch`, and
|
|
1036
|
+
* the tiles holding it lie outside the corridor that proved the best route.
|
|
1037
|
+
*/
|
|
1038
|
+
routeAlternatives(from: Coordinate, to: Coordinate, preference?: RoutePreference, options?: AlternativeRoutesOptions): Promise<RouteResult[]>;
|
|
1039
|
+
private routeOverBundle;
|
|
1040
|
+
/**
|
|
1041
|
+
* The same corridor walk, stopping with the graph it settled on as well as
|
|
1042
|
+
* the route. Alternatives need the graph, and need to be able to widen it
|
|
1043
|
+
* once more: a second route may be worse than the best by more than the
|
|
1044
|
+
* corridor was ever sized to hold.
|
|
1045
|
+
*/
|
|
1046
|
+
private bestOverBundle;
|
|
1047
|
+
private routeOverLoader;
|
|
1048
|
+
}
|
|
1049
|
+
|
|
176
1050
|
/** Where a coordinate lands on one directed edge. */
|
|
177
1051
|
type EdgeProjection = {
|
|
178
1052
|
edge: number;
|
|
@@ -210,7 +1084,7 @@ type GraphSnap = {
|
|
|
210
1084
|
* lies within `maxDistanceMeters` of the coordinate — measured to the road
|
|
211
1085
|
* surface, not to the nearest junction.
|
|
212
1086
|
*/
|
|
213
|
-
declare function snapToGraph(graph: RoadGraph, coordinate: Coordinate, maxDistanceMeters?: number): GraphSnap | null;
|
|
1087
|
+
declare function snapToGraph(graph: RoadGraph, coordinate: Coordinate, maxDistanceMeters?: number, access?: Uint8Array | undefined, accept?: (node: number) => boolean, everyNearbyRoad?: boolean): GraphSnap | null;
|
|
214
1088
|
|
|
215
1089
|
/**
|
|
216
1090
|
* A uniform-grid index over directed edges. Snapping needs the nearest *road*,
|
|
@@ -239,42 +1113,6 @@ declare function nearbyEdgeIds(index: EdgeSpatialIndex, coordinate: Coordinate,
|
|
|
239
1113
|
declare function createSpatialIndex(graph: RoadGraph, cellSizeDegrees?: number): NodeSpatialIndex;
|
|
240
1114
|
declare function withSpatialIndex(graph: RoadGraph, cellSizeDegrees?: number): RoadGraph;
|
|
241
1115
|
|
|
242
|
-
type FetchLike$2 = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
243
|
-
/**
|
|
244
|
-
* Caps how far off the straight line the confirmation pass will reach, as a
|
|
245
|
-
* multiple of the direct distance. `Infinity` leaves the search bounded only
|
|
246
|
-
* by the route already found, which makes the answer the best the compiled
|
|
247
|
-
* graph holds; a finite value trades that proof for a smaller download and
|
|
248
|
-
* still ignores tile size, since the limit is a ground distance.
|
|
249
|
-
*/
|
|
250
|
-
type RoadRouterOptions = {
|
|
251
|
-
maxDetourFactor?: number;
|
|
252
|
-
};
|
|
253
|
-
/**
|
|
254
|
-
* High-level route entry point. `open()` accepts an EFRB bundle, an EFRT
|
|
255
|
-
* manifest, or an already-decoded graph.
|
|
256
|
-
*/
|
|
257
|
-
declare class RoadRouter {
|
|
258
|
-
private readonly graph?;
|
|
259
|
-
private readonly loader?;
|
|
260
|
-
private readonly options;
|
|
261
|
-
private constructor();
|
|
262
|
-
static fromGraph(graph: RoadGraph): RoadRouter;
|
|
263
|
-
static open(source: string | RoadGraph, fetcher?: FetchLike$2, options?: RoadRouterOptions): Promise<RoadRouter>;
|
|
264
|
-
route(from: Coordinate, to: Coordinate, preference?: RoutePreference): Promise<RouteResult>;
|
|
265
|
-
/**
|
|
266
|
-
* Downloads a corridor, routes, then asks whether any tile left out could
|
|
267
|
-
* still hold something better. A route through a tile costs at least the
|
|
268
|
-
* detour to reach it, so the answer is a geometric test against the route
|
|
269
|
-
* already found: tiles that fail it are provably useless and stay
|
|
270
|
-
* undownloaded, and when none passes, the route is the best the compiled
|
|
271
|
-
* graph contains. Because the test measures ground distance rather than
|
|
272
|
-
* counting neighbours, the answer does not depend on the tile size.
|
|
273
|
-
*/
|
|
274
|
-
private routeOverBundle;
|
|
275
|
-
private routeOverLoader;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
1116
|
declare const BundleCompression: {
|
|
279
1117
|
readonly none: 0;
|
|
280
1118
|
readonly gzip: 1;
|
|
@@ -287,17 +1125,42 @@ type BundleBounds = {
|
|
|
287
1125
|
maxLat: number;
|
|
288
1126
|
maxLng: number;
|
|
289
1127
|
};
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
bounds: BundleBounds;
|
|
1128
|
+
/** Where one chunk sits in the file. */
|
|
1129
|
+
type BundleChunkRef = {
|
|
293
1130
|
offset: number;
|
|
294
1131
|
byteLength: number;
|
|
295
1132
|
rawByteLength: number;
|
|
296
1133
|
compression: BundleCompression;
|
|
297
1134
|
};
|
|
1135
|
+
/**
|
|
1136
|
+
* A tile. The flat chunk fields address its graph in a v1 bundle and its
|
|
1137
|
+
* shared chunk in a v2 one; `profileChunks` is present only in v2 and holds
|
|
1138
|
+
* the per-vehicle half, keyed by profile id.
|
|
1139
|
+
*/
|
|
1140
|
+
type BundleTile = BundleChunkRef & {
|
|
1141
|
+
id: number;
|
|
1142
|
+
bounds: BundleBounds;
|
|
1143
|
+
profileChunks?: Map<number, BundleChunkRef>;
|
|
1144
|
+
};
|
|
298
1145
|
type RoadGraphBundle = {
|
|
299
1146
|
url: string;
|
|
300
1147
|
tiles: BundleTile[];
|
|
1148
|
+
/**
|
|
1149
|
+
* The profile every tile in this bundle was compiled for, read from the
|
|
1150
|
+
* header so a caller knows the vehicle before downloading a single tile.
|
|
1151
|
+
* `0` means a bundle written before profiles were recorded: a car bundle.
|
|
1152
|
+
*/
|
|
1153
|
+
profileId: number;
|
|
1154
|
+
/** The profile's speed ceiling in km/h, or 0 when the bundle predates it. */
|
|
1155
|
+
maxSpeedKph: number;
|
|
1156
|
+
/** Every profile this bundle can route, by id. A v1 bundle lists its one. */
|
|
1157
|
+
profiles: number[];
|
|
1158
|
+
/**
|
|
1159
|
+
* The vehicle class this bundle was compiled to suggest, where it names one.
|
|
1160
|
+
* Whoever compiled the extract chose it knowingly; a caller's own `vehicle`
|
|
1161
|
+
* still wins, and the library's default applies when neither says anything.
|
|
1162
|
+
*/
|
|
1163
|
+
defaultVehicle?: string;
|
|
301
1164
|
loadForRoute(origin: Coordinate, destination: Coordinate): Promise<RoadGraph>;
|
|
302
1165
|
loadExpandedForRoute(origin: Coordinate, destination: Coordinate): Promise<RoadGraph>;
|
|
303
1166
|
/**
|
|
@@ -308,14 +1171,43 @@ type RoadGraphBundle = {
|
|
|
308
1171
|
* distance, which is what makes it independent of how the bundle was tiled.
|
|
309
1172
|
*/
|
|
310
1173
|
tilesWithinBudget(origin: Coordinate, destination: Coordinate, budgetMeters: number): BundleTile[];
|
|
311
|
-
/**
|
|
312
|
-
|
|
1174
|
+
/**
|
|
1175
|
+
* Merges the given tiles, reusing any chunk already downloaded. `profileId`
|
|
1176
|
+
* picks the vehicle in a multi-profile bundle; the bundle's own default is
|
|
1177
|
+
* used when it is left out.
|
|
1178
|
+
*/
|
|
1179
|
+
loadTiles(tiles: BundleTile[], profileId?: number): Promise<RoadGraph>;
|
|
313
1180
|
};
|
|
314
1181
|
type BundleGraphTile = {
|
|
315
1182
|
id: number;
|
|
316
1183
|
bounds: BundleBounds;
|
|
317
1184
|
graph: RoadGraph;
|
|
318
1185
|
};
|
|
1186
|
+
/**
|
|
1187
|
+
* One tile of a multi-profile bundle: the road network once, and the
|
|
1188
|
+
* vehicle-dependent columns once per vehicle.
|
|
1189
|
+
*/
|
|
1190
|
+
type BundleProfiledTile = {
|
|
1191
|
+
id: number;
|
|
1192
|
+
bounds: BundleBounds;
|
|
1193
|
+
graph: RoadGraph;
|
|
1194
|
+
profiles: ProfileChunk[];
|
|
1195
|
+
};
|
|
1196
|
+
/**
|
|
1197
|
+
* `mergedCacheSize` is how many stitched corridors to keep. Stitching is the
|
|
1198
|
+
* most expensive part of answering a route, and consecutive routes usually ask
|
|
1199
|
+
* for the same tiles, so one is worth holding. Each entry is a whole merged
|
|
1200
|
+
* corridor, so raising this trades memory for repeat speed; `0` keeps none and
|
|
1201
|
+
* restores the behaviour of releasing a corridor as soon as the route is done.
|
|
1202
|
+
*/
|
|
1203
|
+
type BundleOpenOptions = {
|
|
1204
|
+
mergedCacheSize?: number;
|
|
1205
|
+
/**
|
|
1206
|
+
* Which vehicle to route as, by profile name. Only a multi-profile bundle
|
|
1207
|
+
* offers a choice; leaving it out uses the bundle's own default.
|
|
1208
|
+
*/
|
|
1209
|
+
profile?: string;
|
|
1210
|
+
};
|
|
319
1211
|
type BundleEncodeOptions = {
|
|
320
1212
|
compression?: "none" | "gzip";
|
|
321
1213
|
};
|
|
@@ -325,7 +1217,14 @@ declare function distanceToBounds(coordinate: Coordinate, bounds: BundleBounds):
|
|
|
325
1217
|
declare function encodeRoadGraphBundle(tiles: BundleGraphTile[]): ArrayBuffer;
|
|
326
1218
|
/** Creates a bundle with independently gzip-compressed EFR2 chunks. */
|
|
327
1219
|
declare function encodeCompressedRoadGraphBundle(tiles: BundleGraphTile[], options?: BundleEncodeOptions): Promise<ArrayBuffer>;
|
|
328
|
-
|
|
1220
|
+
/**
|
|
1221
|
+
* Creates a bundle serving several vehicles from one copy of the road network.
|
|
1222
|
+
* Each tile contributes its shared chunk once and a small chunk per vehicle,
|
|
1223
|
+
* and the directory lists them separately so a reader downloads only the
|
|
1224
|
+
* vehicle it asked for.
|
|
1225
|
+
*/
|
|
1226
|
+
declare function encodeProfiledRoadGraphBundle(tiles: BundleProfiledTile[], options?: BundleEncodeOptions): Promise<ArrayBuffer>;
|
|
1227
|
+
declare function openRoadGraphBundle(url: string, fetcher?: FetchLike$1, options?: BundleOpenOptions): Promise<RoadGraphBundle>;
|
|
329
1228
|
|
|
330
1229
|
type GraphBounds = {
|
|
331
1230
|
minLat: number;
|
|
@@ -426,53 +1325,31 @@ declare function packTurnSequences(sequences: number[][]): {
|
|
|
426
1325
|
turnRestrictionSequenceOffsets: Uint32Array<ArrayBuffer>;
|
|
427
1326
|
turnRestrictionSequenceEdges: Uint32Array<ArrayBuffer>;
|
|
428
1327
|
};
|
|
429
|
-
|
|
430
1328
|
/**
|
|
431
|
-
*
|
|
432
|
-
*
|
|
433
|
-
*
|
|
434
|
-
*
|
|
1329
|
+
* Which junctions a search has to remember its approach at.
|
|
1330
|
+
*
|
|
1331
|
+
* Obeying a banned turn means knowing which road you arrived on, and the only
|
|
1332
|
+
* state that can express that is "arrived at this node along that edge" — one
|
|
1333
|
+
* state per directed edge rather than one per node. Carrying that everywhere
|
|
1334
|
+
* doubles the search for the sake of the few junctions that need it: in a
|
|
1335
|
+
* Portugal corridor, 16,620 junctions of 1,244,262 carry a restriction, which
|
|
1336
|
+
* is 1.3%.
|
|
1337
|
+
*
|
|
1338
|
+
* So the approach is remembered only where it can change the answer. A node is
|
|
1339
|
+
* guarded when a banned pair turns on it, or when any edge of a banned run
|
|
1340
|
+
* ends there — a run spans several junctions, and the search has to know how
|
|
1341
|
+
* far along it has driven at each of them.
|
|
435
1342
|
*/
|
|
436
|
-
type
|
|
437
|
-
/**
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
|
|
445
|
-
backwardSpeedKph: number;
|
|
446
|
-
};
|
|
447
|
-
/** A turn restriction relation reduced to the only two cases routing cares about. */
|
|
448
|
-
type TurnRestrictionKind = "no" | "only";
|
|
449
|
-
type ParsedTurnRestriction = {
|
|
450
|
-
kind: TurnRestrictionKind;
|
|
451
|
-
/** The raw OSM value, kept for diagnostics only. */
|
|
452
|
-
value: string;
|
|
1343
|
+
type GuardedJunctions = {
|
|
1344
|
+
/** One byte per node: does arriving matter here? */
|
|
1345
|
+
guarded: Uint8Array;
|
|
1346
|
+
/** For an edge ending at a guarded node, its own state; -1 otherwise. */
|
|
1347
|
+
stateOfEdge: Int32Array;
|
|
1348
|
+
/** The edge each guarded state arrived along. */
|
|
1349
|
+
edgeOfState: Int32Array;
|
|
1350
|
+
/** How many states the guarded junctions take up. */
|
|
1351
|
+
count: number;
|
|
453
1352
|
};
|
|
454
|
-
|
|
455
|
-
readonly name: string;
|
|
456
|
-
/** Way tag keys the compiler must request from the PBF reader. */
|
|
457
|
-
readonly wayTagKeys: readonly string[];
|
|
458
|
-
/** Relation tag keys the compiler must request from the PBF reader. */
|
|
459
|
-
readonly relationTagKeys: readonly string[];
|
|
460
|
-
/** The fastest speed the profile can ever return, used for admissible A* heuristics. */
|
|
461
|
-
readonly maxSpeedKph: number;
|
|
462
|
-
/** Returns null when the way is not usable by this profile at all. */
|
|
463
|
-
evaluateWay(tags: OsmTags): WayTraversal | null;
|
|
464
|
-
/** Returns null when the relation is not a turn restriction this profile obeys. */
|
|
465
|
-
evaluateTurnRestriction(tags: OsmTags): ParsedTurnRestriction | null;
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Reads a `maxspeed`-style value. Returns null for every value that is not a
|
|
469
|
-
* plain number with an optional unit — country codes such as `PT:urban`,
|
|
470
|
-
* `none`, `signals` and `variable` included — so the caller can fall back to a
|
|
471
|
-
* class default instead of inventing a country-specific table.
|
|
472
|
-
*/
|
|
473
|
-
declare function parseMaxSpeedKph(value: string | undefined): number | null;
|
|
474
|
-
declare const carRoutingProfile: RoutingProfile;
|
|
475
|
-
declare const routingProfiles: Record<string, RoutingProfile>;
|
|
476
|
-
declare function getRoutingProfile(name: string): RoutingProfile;
|
|
1353
|
+
declare function guardedJunctionsFor(graph: RoadGraph, restrictions: TurnRestrictionIndex | null, sequences: TurnSequenceIndex | null): GuardedJunctions;
|
|
477
1354
|
|
|
478
|
-
export { type BundleBounds, BundleCompression, type BundleEncodeOptions, type BundleGraphTile, type BundleTile, type CompactEncodeOptions, type CompactGraphOptions, type Coordinate, type CoordinateStorage, type EdgeProjection, type EdgeSpatialIndex, type EdgeWeightStorage, type GeoJsonLineString, type GeoJsonPosition, type GraphBounds, type GraphSnap, type GraphTile, type NodeSpatialIndex, type OsmTags, type ParsedTurnRestriction, type RoadGraph, type RoadGraphBundle, RoadRouter, type RoadRouterOptions, type RouteGraphLoader, type RouteGraphManifest, type RouteOptions, type RoutePreference, type RouteResult, type RouteSnap, RouterError, type RouterErrorCode, type RoutingProfile, type TurnRestrictionIndex, type TurnRestrictionKind, type TurnSequenceIndex, VarintReader, VarintWriter, type WayTraversal, buildTurnRestrictionIndex, buildTurnSequenceIndex, carRoutingProfile, compactGraph, createEdgeSpatialIndex, createRouteGraphLoader, createSpatialIndex, decodeGraph, distanceToBounds, edgePolyline, edgeSource, edgeSpatialIndexFor, encodeCompactGraph, encodeCompressedRoadGraphBundle, encodeGraph, encodeRoadGraphBundle, findNearestNode, getRoutingProfile, isTurnBanned, mergeRoadGraphs, nearbyEdgeIds, openRoadGraphBundle, packTurnRestrictions, packTurnSequences, parseMaxSpeedKph, route, routingProfiles, snapToGraph, unzigzag, withSpatialIndex, zigzag };
|
|
1355
|
+
export { type AlternativeRoutesOptions, type AvoidArea, type BundleBounds, type BundleChunkRef, BundleCompression, type BundleEncodeOptions, type BundleGraphTile, type BundleOpenOptions, type BundleProfiledTile, type BundleTile, type Circumstances, type CompactEncodeOptions, type CompactGraphOptions, type Condition, ConditionKind, type ConditionalRule, type Coordinate, type CoordinateStorage, DEFAULT_VEHICLE_PRESET, type DepartureOptions, type EdgeConditions, type EdgeLimits, type EdgeProjection, type EdgeSpatialIndex, type EdgeWeightStorage, type GeoJsonLineString, type GeoJsonPosition, type GraphBounds, type GraphSnap, type GraphTile, type GuardedJunctions, MAX_STORED_VALUES, type MinuteSpan, type NodeSpatialIndex, type OsmTags, type ParsedConditions, type ParsedTurnRestriction, type ProfileChunk, ProfileId, type RoadGraph, type RoadGraphBundle, RoadRouter, type RoadRouterOptions, type RouteGraphLoader, type RouteGraphManifest, type RouteOptions, type RoutePreference, type RouteResult, type RouteSnap, RouterError, type RouterErrorCode, type RoutingProfile, type SearchBounds, type SharedRoadGraph, type TravelTime, type TurnRestrictionIndex, type TurnRestrictionKind, type TurnSequenceIndex, VEHICLE_PRESETS, VarintReader, VarintWriter, type VehicleComparison, type VehicleDimensions, type VehicleInput, type VehicleLimits, VehiclePresetId, type WayTraversal, accessAtTime, accessAvoiding, accessForVehicle, accessMaskFor, allowsEverything, buildTurnRestrictionIndex, buildTurnSequenceIndex, carRoutingProfile, checkAlternativeOptions, combineProfiledGraph, compactGraph, componentSizes, componentsFor, conditionHolds, conditionalDurations, conditionalValue, conditionsOf, conditionsOnEdge, countAvoided, countBlocked, countClosedAt, createEdgeSpatialIndex, createRouteGraphLoader, createSpatialIndex, decodeGraph, decodeProfileChunk, decodeSharedGraph, distanceToBounds, edgeAllowed, edgePolyline, edgeSource, edgeSpatialIndexFor, encodeCompactGraph, encodeCompressedRoadGraphBundle, encodeGraph, encodeProfileChunk, encodeProfiledRoadGraphBundle, encodeRoadGraphBundle, encodeSharedGraph, findNearestNode, fromDecimetres, fromHalfTonnes, getRoutingProfile, getRoutingProfileById, guardedJunctionsFor, isTurnBanned, maxSpeedMpsFor, mergeRoadGraphs, motorcycleRoutingProfile, nearbyEdgeIds, openRoadGraphBundle, packEdgeConditions, packEdgeLimits, packTurnRestrictions, packTurnSequences, parseConditional, parseEdgeConditions, parseLengthMeters, parseMaxSpeedKph, parseWeightTonnes, profileOf, resolveVehicle, route, routeAlternatives, routingProfiles, searchBoundsFor, snapToGraph, straightLineAtMost, toDecimetres, toHalfTonnes, touchesArea, travelTimeFrom, truckRoutingProfile, unreadableConditions, unzigzag, vehiclePreset, vehiclePresetName, withSpatialIndex, zigzag };
|