MoonBit-native route encoding, GeoJSON export, route metrics, simplification, and Web Mercator tile coverage toolkit.
git clone https://github.com/NBB2006/routeweave.git
cd routeweavemoon check
moon build
moon test
moon run cmd/mainlet route = [
@routeweave.Point(31.23040, 121.47370),
@routeweave.Point(31.23120, 121.47800),
@routeweave.Point(31.23300, 121.48350),
]
let encoded = @routeweave.encode_polyline(route)
let geojson = @routeweave.to_geojson_feature(route, name="demo")
let summary = @routeweave.summarize_route(route, zoom=14)
let samples = @routeweave.sample_route_by_count(route, 5)
let spread = @routeweave.route_segment_spread(route)
let nearest = @routeweave.nearest_point_on_route(
@routeweave.Point(31.2320, 121.4800),
route,
)
let quality = @routeweave.route_quality_report(route)moon fmt --check
moon check --target all --deny-warn
moon build
moon test --target all --deny-warn
moon run cmd/main
moon infopub struct BBox {
min_lat : Double
min_lon : Double
max_lat : Double
max_lon : Double
}pub struct NearestPoint {
point : Point
distance_to_route_m : Double
distance_along_route_m : Double
segment_index : Int
fraction : Double
}fn NearestPoint::NearestPoint(point : Point, distance_to_route_m : Double, distance_along_route_m : Double, segment_index : Int, fraction : Double) -> NearestPointpub(all) enum RouteError {
EmptyRoute
InvalidCoordinate(index~ : Int, lat~ : Double, lon~ : Double)
InvalidPrecision(precision~ : Int)
InvalidZoom(zoom~ : Int)
InvalidTolerance(tolerance_m~ : Double)
InvalidDistance(distance_m~ : Double)
InvalidFraction(fraction~ : Double)
InvalidSegmentLength(length_m~ : Double)
InvalidSampleCount(count~ : Int)
InvalidTileCoordinate(tile~ : Tile)
MalformedPolyline(pos~ : Int, reason~ : String)
} derive(Eq)pub struct RouteIssue {
index : Int
code : String
severity : Int
detail : String
}fn RouteIssue::RouteIssue(index : Int, code : String, severity : Int, detail : String) -> RouteIssuepub struct RouteQualityReport {
point_count : Int
segment_count : Int
duplicate_points : Int
stationary_segments : Int
long_segments : Int
sharp_turns : Int
self_intersections : Int
score : Int
issues : Array[RouteIssue]
}fn RouteSample::RouteSample(point : Point, distance_m : Double, segment_index : Int, fraction : Double) -> RouteSamplefn RouteSlice::RouteSlice(start_m : Double, end_m : Double, distance_m : Double, points : Array[Point]) -> RouteSlicefn RouteStats::RouteStats(point_count : Int, segment_count : Int, distance_m : Double, direct_distance_m : Double, sinuosity : Double, min_segment_m : Double, max_segment_m : Double, average_segment_m : Double, bbox : BBox, center : Point) -> RouteStatsfn SegmentMetric::SegmentMetric(index : Int, start : Point, finish : Point, distance_m : Double, bearing_deg : Double) -> SegmentMetricpub struct SegmentSpread {
segment_count : Int
total_distance_m : Double
shortest_segment_m : Double
longest_segment_m : Double
average_segment_m : Double
standard_deviation_m : Double
coefficient_of_variation : Double
longest_segment_index : Int
}fn SegmentSpread::SegmentSpread(segment_count : Int, total_distance_m : Double, shortest_segment_m : Double, longest_segment_m : Double, average_segment_m : Double, standard_deviation_m : Double, coefficient_of_variation : Double, longest_segment_index : Int) -> SegmentSpreadfn TileBounds::TileBounds(tile : Tile, west : Double, south : Double, east : Double, north : Double) -> TileBoundspub struct TileRange {
z : Int
min_x : Int
min_y : Int
max_x : Int
max_y : Int
}fn along_track_distance_meters(query : Point, start : Point, finish : Point) -> Result[Double, RouteError]fn cross_track_distance_meters(query : Point, start : Point, finish : Point) -> Result[Double, RouteError]fn densify_route(points : ArrayView[Point], max_segment_m : Double) -> Result[Array[Point], RouteError]fn is_point_near_route(query : Point, route : ArrayView[Point], tolerance_m : Double) -> Result[Bool, RouteError]fn long_segment_indices(points : ArrayView[Point], max_segment_m : Double) -> Result[Array[Int], RouteError]fn nearest_point_on_route(query : Point, route : ArrayView[Point]) -> Result[NearestPoint, RouteError]fn nearest_points_to_geojson_feature_collection(points : ArrayView[NearestPoint], name? : String) -> Result[String, RouteError]fn point_at_distance(points : ArrayView[Point], distance_m : Double) -> Result[RouteSample, RouteError]fn remove_stationary_segments(points : ArrayView[Point], threshold_m? : Double) -> Result[Array[Point], RouteError]fn resample_route_by_count(points : ArrayView[Point], count : Int) -> Result[Array[Point], RouteError]fn resample_route_every(points : ArrayView[Point], interval_m : Double, include_end? : Bool) -> Result[Array[Point], RouteError]fn route_distance_along_for_point(query : Point, route : ArrayView[Point]) -> Result[Double, RouteError]fn route_is_evenly_sampled(points : ArrayView[Point], max_coefficient_of_variation? : Double) -> Result[Bool, RouteError]fn route_quality_issues(points : ArrayView[Point], stationary_threshold_m? : Double, max_segment_m? : Double, sharp_turn_deg? : Double) -> Result[Array[RouteIssue], RouteError]fn route_quality_report(points : ArrayView[Point], stationary_threshold_m? : Double, max_segment_m? : Double, sharp_turn_deg? : Double) -> Result[RouteQualityReport, RouteError]fn route_report_geojson(route : ArrayView[Point], zoom? : Int, name? : String) -> Result[String, RouteError]fn route_station_for_fraction(route : ArrayView[Point], fraction : Double) -> Result[RouteSample, RouteError]fn route_station_points(route : ArrayView[Point], fractions : ArrayView[Double]) -> Result[Array[RouteSample], RouteError]fn routes_to_geojson_feature_collection(routes : ArrayView[Array[Point]], name_prefix? : String) -> Result[String, RouteError]fn sample_route_by_count(points : ArrayView[Point], count : Int) -> Result[Array[RouteSample], RouteError]fn sample_route_every(points : ArrayView[Point], interval_m : Double, include_end? : Bool) -> Result[Array[RouteSample], RouteError]fn samples_to_geojson_feature_collection(samples : ArrayView[RouteSample], name? : String) -> Result[String, RouteError]fn segment_fraction_for_projection(query : Point, start : Point, finish : Point) -> Result[Double, RouteError]fn sharp_turn_indices(points : ArrayView[Point], threshold_deg? : Double) -> Result[Array[Int], RouteError]fn simplify_route(points : ArrayView[Point], tolerance_m? : Double) -> Result[Array[Point], RouteError]fn slice_route(points : ArrayView[Point], start_m : Double, end_m : Double) -> Result[RouteSlice, RouteError]fn snap_points_to_route(queries : ArrayView[Point], route : ArrayView[Point]) -> Result[Array[NearestPoint], RouteError]fn split_route_by_count(points : ArrayView[Point], count : Int) -> Result[Array[RouteSlice], RouteError]fn split_route_by_distance(points : ArrayView[Point], max_slice_m : Double) -> Result[Array[RouteSlice], RouteError]fn stationary_segment_indices(points : ArrayView[Point], threshold_m? : Double) -> Result[Array[Int], RouteError]fn summarize_route(points : ArrayView[Point], zoom? : Int, simplify_tolerance_m? : Double) -> Result[RouteSummary, RouteError]fn tiles_to_geojson_feature_collection(tiles : ArrayView[Tile], name? : String) -> Result[String, RouteError]MoonBit-native route encoding, GeoJSON export, route metrics, simplification, and Web Mercator tile coverage toolkit.