You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+21-17Lines changed: 21 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -17,9 +17,10 @@ Check the live example at [https://abelvm.github.io/omt-router/example](https://
17
17
18
18
-**Zero backend, zero-provider** — No need for a routing backend or relying on a 3rd party API provider, `omt-router` builds the routing graph on-the-fly from **OpenMapTiles** formatted vector tiles
-**Automatic best engine selection** — using modelization based on real-world data
20
+
-**Automatic best engine selection** — runtime engine chooser uses benchmark-derived models and a generated selector module in `src/tuning/tuning.js`
21
21
-**Three transport modes** — `car`, `pedestrian`, `bicycle`; respects OpenMapTiles access tags and road class hierarchy
22
-
-**Two optimizacion strategies** — route length or travel time
22
+
-**Two optimization strategies** — route length or travel time
23
+
-**Endpoint snapping with quality guard** — nearest-node lookup plus segment-projection snap, with `maxAcceptableSnapDistanceM` limiting distant off-road snaps
23
24
-**Seamless tile stitching** — [Liang-Barsky](https://en.wikipedia.org/wiki/Liang%E2%80%93Barsky_algorithm) clipping ensures road segments share bit-identical boundary nodes across neighbouring tiles with no proximity snapping
24
25
-**Worker pool + tile cache** — Using [performance-helpers](https://abelvm.github.io/performance-helpers) to get the best performance always: parallel tile parsing and parallel engines execution via **PowerPool**, parsed tiles are cached with **PowerCache** so repeated queries can reuse tiles until TTL/LRU eviction
25
26
@@ -43,29 +44,30 @@ Notes:
43
44
44
45
## ML-based engine selector
45
46
46
-
Engine selection is data-driven. The file `src/tuning.js` is generated from benchmark data by `benchmark/cluster_engine_selector.py`.
47
+
Engine selection is data-driven and can be regenerated from benchmark results. `src/tuning/tuning.js` is built from the benchmark pipeline, and `src/tuning/model.js` is the compact runtime model artifact produced by `benchmark/train_engine_selector_ml.py`.
47
48
48
-
At runtime, the selector computes route/graph features such as:
49
+
At runtime, the selector evaluates route and graph features such as:
49
50
50
51
- edge count (`E`) and node count (`N`)
51
52
- beeline distance between endpoints
52
53
- derived density/branch indicators (`edgesPerKm`, average out-degree)
1. Build the route/graph feature vector from the corridor graph and query endpoints.
59
+
2. Detect runtime capability (`SharedArrayBuffer`, Worker, cross-origin isolation) to choose `sabOn` vs `sabOff` rules.
60
+
3.Evaluate the generated selector in `src/tuning/tuning.js`, which uses the compact `src/tuning/model.js` artifact when available.
61
+
4.Select the recommended engine and apply per-engine parallelization/correctness fallback logic.
61
62
62
63
Why this exists:
63
64
64
-
- No single engine wins every route shape.
65
-
- The selector minimizes regret using offline benchmark-trained rules.
66
-
- Tuning can be regenerated as your benchmark corpus grows.
65
+
- No single engine is best for every route graph shape.
66
+
- The selector minimizes runtime regret using offline benchmark-trained models.
67
+
- The training workflow supports both serial (`sabOff`) and parallel (`sabOn`) profiles.
68
+
- The model pipeline includes `runtime-linear`, `xgboost`, and a compact 2-layer `mlp` option.
67
69
68
-
See [benchmark/README.md](benchmark/README.md) for full benchmark, analysis, and sweep workflow.
70
+
See [benchmark/README.md](benchmark/README.md) for the current benchmarkand selector training workflow.
69
71
70
72
---
71
73
@@ -105,9 +107,9 @@ You can also use other OpenMapTiles-compatible providers (for example MapTiler)
105
107
106
108
Route quality depends on source data quality. The better [OpenStreetMap](https://www.openstreetmap.org/) coverage and tagging are in your area, the better the result. If you find inaccuracies, consider [contributing](https://wiki.openstreetmap.org/wiki/How_to_contribute) to improve OSM data.
107
109
108
-
Endpoints must snap to routable nodes. If origin or destination is too far from a valid road/path for the chosen mode, routing can fail with `no_node` or `poor_snap`. For example, avoid starting a car route in pedestrian-only areas.
110
+
Endpoints must snap to routable graph edges. The routing code first looks for the nearest graph node, then it may use a segment-projection snap when that improves route validity. Snapping is guarded by `maxAcceptableSnapDistanceM` (default `60` m), so points that are too far from a usable road/path will fail with `no_node` or `poor_snap` rather than producing a misleading route.
109
111
110
-
For bidirectional streets, the side of the road you pick might change the proposed route considerably.
112
+
For bidirectional streets, the side of the road you click can still affect the computed route, especially when one-way restrictions are present.
111
113
112
114
Tile requests are performed in-browser from a Worker. Your tile server must include CORS headers (for example `Access-Control-Allow-Origin`) for uncached cross-origin requests. If that is not possible, route tile URLs through a same-origin proxy (see `options.tileProxyTemplate`).
113
115
@@ -270,6 +272,8 @@ route()
270
272
271
273
In `route()`, corridor radius can auto-expand when a pass fails with `no_path`, `no_node`, `poor_snap`, or `incomplete_path`. This keeps normal requests small while still handling larger real-world detours.
272
274
275
+
The tile retry loop also means route failure reasons are more informative: `no_node` means no nearby graph node was found, `poor_snap` means endpoint snapping quality exceeded `maxAcceptableSnapDistanceM`, and `incomplete_path` means the selected engine produced an invalid route that will be retried or surfaced to the caller.
276
+
273
277
Both `zxy` (XYZ) and `tms` (TMS, Y-flipped) schemas are supported.
274
278
275
279
### 2. Graph construction — `graphBuilder.js`
@@ -303,7 +307,7 @@ Endpoints are snapped to graph nodes with a cached `KDBush` spatial index and a
303
307
304
308
### 4. Routing execution and engine selection — `chRouter.js`
305
309
306
-
`queryRoute` supports explicit engine IDs and an `auto` mode. In `auto`, the selector in `src/tuning.js` uses route and graph features (`E`, `N`, beeline, density and branching bands) plus runtime capability (for example SharedArrayBuffer and Worker availability) to choose the best engine for each query.
310
+
`queryRoute` supports explicit engine IDs and an `auto` mode. In `auto`, the selector in `src/tuning/tuning.js` uses route and graph features (`E`, `N`, beeline, density and branching bands) plus runtime capability (for example SharedArrayBuffer and Worker availability) to choose the best engine for each query.
0 commit comments