routeable

An explainable accessibility route-planning engine and WebAssembly demo.

accessibility
routing
wasm
campus
moonbit
moon add 13131116363/routeable@0.1.0
Download zip
Version
0.1.0
License
Apache-2.0
Last updated
7 days ago
Downloads
2
README

#RouteAble / 路见无碍

RouteAble is an explainable accessibility route planner written primarily in MoonBit. Instead of returning only the shortest path, it filters obstacles for a chosen mobility profile and shows why each route segment was selected.

#Why it exists

Ordinary navigation usually assumes that every pedestrian can use stairs, narrow paths or poorly lit shortcuts. RouteAble models practical constraints for wheelchair users, people with low vision, stroller users and ordinary walkers. It is designed for bounded places such as campuses, parks, communities and venues where accessibility data can be maintained carefully.

#Features

  • Profile-aware hard constraints for stairs, slope, width, construction and rough surfaces.
  • Weighted Dijkstra search that balances distance with lighting, crossings, incline and coverage.
  • Segment-level explanations and warnings rather than a black-box recommendation.
  • A deterministic campus demonstration graph with 56 locations and 194 directed paths.
  • A runnable MoonBit CLI, browser demonstration, tests and GitHub Actions CI.

#Quick start

Prerequisites: MoonBit and Node.js 20+.

npm run generate:data npm run check npm test npm run demo

Build the WebAssembly target:

npm run build

Open the interactive static demo at http://127.0.0.1:4173:

npm run serve

#Project layout

PathPurpose
routeable.mbtPublic MoonBit domain model, constraints, planner and explanation API
campus_network.mbtGenerated, deterministic demonstration graph
cmd/mainRunnable CLI demonstration
web/Dependency-free interactive UI for the demo scenario
tools/generate_demo_network.mjsReproducibly generates the checked-in sample map
.github/workflows/ci.ymlChecks, tests and Wasm build

#Safety and data boundary

The included map is synthetic. RouteAble is a decision-support demonstration, not an emergency-navigation system. Real deployment requires local accessibility verification, a data maintenance process and context-appropriate safety review. Do not include personally identifying location trails in route data.

#Licence and third-party material

The source is licensed under Apache-2.0. The web demo uses no third-party images, map tiles or JavaScript packages. The campus data is generated by this repository and is synthetic.

#Publishing to mooncakes.io

The module metadata is ready for publication. Before publishing, log in to the MoonBit account that owns the 13131116363 namespace and verify the final semantic version:

moon login moon publish

Publishing is intentionally left to the account owner because it creates a public, versioned external release.

#
AlertLevel

pub(all) enum AlertLevel {
Info
Notice
Warning
Blocked
} derive(Eq,
Debug
)

#
Edge

pub(all) struct Edge {
id : Int
from : Int
to : Int
meters : Int
slope_percent : Int
steps : Int
lighting : Int
crossing : Int
construction : Bool
surface : Surface
width_cm : Int
covered : Bool
note : String
} derive(
Debug
)

#
Graph

pub(all) struct Graph {
nodes : Array[Node]
edges : Array[Edge]
} derive(
Debug
)

#
MobilityProfile

pub(all) enum MobilityProfile {
Wheelchair
LowVision
Stroller
Standard
} derive(Eq,
Debug
)

RouteAble is an offline-first, explainable accessibility route planner. Applications supply a small campus graph, community map, or compatible public data and receive a route plus a human-readable rationale.

#
Node

pub(all) struct Node {
id : Int
label : String
zone : String
x : Double
y : Double
has_rest_area : Bool
has_tactile_paving : Bool
} derive(
Debug
)

#
ProfileComparison

pub(all) struct ProfileComparison {
profile : MobilityProfile
reachable : Bool
distance_meters : Int
friction_score : Double
grade : String
message : String
} derive(
Debug
)

#
ProfileConfig

pub(all) struct ProfileConfig {
max_slope : Int
max_steps : Int
minimum_lighting : Int
minimum_width_cm : Int
avoid_crossings : Bool
avoid_gravel : Bool
rest_bonus : Double
} derive(
Debug
)

#
Route

pub(all) struct Route {
profile : MobilityProfile
node_ids : Array[Int]
segments : Array[RouteSegment]
total_meters : Int
total_score : Double
accessible : Bool
summary : String
warnings : Array[String]
} derive(
Debug
)

#
RouteMetrics

pub(all) struct RouteMetrics {
distance_meters : Int
average_slope : Double
total_crossings : Int
low_light_segments : Int
covered_segments : Int
rest_stops : Int
warning_count : Int
estimated_minutes : Int
} derive(
Debug
)

Route quality analysis built on top of the planner's public route result. These helpers make it possible for a UI to compare options without duplicating accessibility policy outside MoonBit.

#
RouteSegment

pub(all) struct RouteSegment {
edge_id : Int
from_label : String
to_label : String
meters : Int
score : Double
reasons : Array[String]
alerts : Array[String]
} derive(
Debug
)

#
Surface

pub(all) enum Surface {
Asphalt
Paving
Brick
Gravel
Indoor
} derive(Eq,
Debug
)

#
accessibility_grade

fn accessibility_grade(route : Route) -> String

#
alternative_destinations

fn alternative_destinations(graph : Graph, start : Int, profile : MobilityProfile) -> Array[Route]

#
compare_profiles

fn compare_profiles(graph : Graph, start : Int, destination : Int) -> Array[ProfileComparison]

#
demo_campus_graph

fn demo_campus_graph() -> Graph

Generated demo map: 56 locations and 194 directed accessible paths. Regenerate with: node tools/generate_demo_network.mjs

#
demo_landmarks

fn demo_landmarks() -> Array[Int]

#
edge_alerts

fn edge_alerts(edge : Edge, profile : MobilityProfile) -> Array[String]

#
edge_block_reason

fn edge_block_reason(edge : Edge, profile : MobilityProfile) -> String?

#
edge_reasons

fn edge_reasons(edge : Edge, profile : MobilityProfile) -> Array[String]

#
edge_score

fn edge_score(edge : Edge, profile : MobilityProfile) -> Double?

#
estimate_minutes

fn estimate_minutes(distance_meters : Int, profile : MobilityProfile) -> Int

#
nearest_rest_stop

fn nearest_rest_stop(graph : Graph, route : Route) -> Node?

#
plan

fn plan(graph : Graph, start : Int, destination : Int, profile : MobilityProfile) -> Route?

Compute the lowest-friction route for a profile using constrained Dijkstra.

#
profile_config

fn profile_config(profile : MobilityProfile) -> ProfileConfig

#
profile_name

fn profile_name(profile : MobilityProfile) -> String

#
reachable_profile_count

fn reachable_profile_count(graph : Graph, start : Int, destination : Int) -> Int

#
route_briefing

fn route_briefing(graph : Graph, route : Route) -> String

fn route_can_be_recommended(graph : Graph, route : Route) -> Bool

#
route_has_rest_stop

fn route_has_rest_stop(graph : Graph, route : Route) -> Bool

#
route_markdown

fn route_markdown(route : Route) -> String

#
route_metrics

fn route_metrics(graph : Graph, route : Route) -> RouteMetrics

#
route_quality_label

fn route_quality_label(metrics : RouteMetrics) -> String

#
route_steps

fn route_steps(route : Route) -> Array[String]

#
surface_name

fn surface_name(surface : Surface) -> String

#
valid_graph

fn valid_graph(graph : Graph) -> Bool

#
walking_speed_meters_per_minute

fn walking_speed_meters_per_minute(profile : MobilityProfile) -> Int