This directory contains the static browser router and the policy used to grade pedestrian-network edges for different users. It is intentionally split into a human-editable policy layer and a generic implementation layer.
The distance-only profile is a neutral baseline. The wheelchair, blind/low-vision and elderly profiles are provisional: they recover useful ideas from OSWM’s historical Streamlit experiment but are not a claim that a route is guaranteed accessible. Their values require participatory calibration with users and accessibility specialists.
| File | Responsibility |
|---|---|
profile_rules.py |
Human-editable profile dictionaries |
profile_validation.py |
Structural and numerical safety checks |
grading.py |
Attribute normalization and grade calculation |
elevation.py |
Elevation-provider hierarchy and slope cache |
routing_demo.html |
Static MapLibre and PathFinder client |
../generation/routing_demo_gen.py |
Offline routing-data generation |
Policy changes should normally touch only profile_rules.py. The remaining
modules should not contain profile-specific accessibility judgments.
Every profile declares a routing_mode. The distance mode minimizes segment
length directly. The accessibility_grade mode consumes directional,
precomputed edge grades. Exactly one distance profile is required so every
accessibility route has an unambiguous comparison baseline.
Negative route costs are never allowed.
Accessibility-profile factors are composed with a weighted harmonic mean:
grade = sum(weights) / sum(weight / factor_grade)
This prevents one excellent characteristic from completely hiding a very poor one. Hard barriers are evaluated first, while grade caps handle serious but not universally impassable conditions.
The generator calculates separate forward and backward grades. Terrain rising
in feature-coordinate order is an ascent forward and a descent backward.
The distance profile needs no grades, so no redundant distance_grade_*
properties are written to every edge.
When an accessibility profile is selected, the browser offers Compare with distance-only. It calculates a second shortest-distance route between the same snapped points, draws it as an offset orange dashed line, and reports its distance plus the selected route’s absolute and percentage difference. The option is hidden when distance-only is already selected.
incline=*.incline:across=* is independent and is never inferred from a terrain model.
Copernicus GLO-30 and GLO-90 are digital surface models: their results are
explicitly treated as low-confidence terrain trends, not measured sidewalk
slopes. Together they provide a globally valid default for OSWM nodes.
Nodes can override the provider list through ELEVATION_CONFIG in config.py.
The current template contains an example local COG entry.
Downloaded raster tiles are kept under ignored .cache/. Compact derived
slopes are stored in data/routing/slope_cache.json, keyed by geometry,
mapped incline and provider configuration. Unchanged edges therefore do not
need to be sampled again.
| File | Contents |
|---|---|
data/routing/demo.geojson |
Transitional geometry plus compact grades |
data/routing/profiles.json |
Browser-safe labels and cost rules |
data/routing/metadata.json |
Ruleset, provenance and grade audit |
data/routing/slope_cache.json |
Reusable derived slopes |
The GeoJSON is transitional. A future version can serialize the same precomputed properties into typed arrays/a compact topology graph without changing the human-editable rules.
profile_rules.py.PROFILE_RULESET_VERSION.Run:
python -m unittest discover -s tests -p "test_routing_*.py" -v
data/routing/metadata.json.The generator records both a semantic version and a deterministic hash, making it clear which rules produced each node artifact.