///|
pub fn summarize_route(
  points : ArrayView[Point],
  zoom? : Int = 12,
  simplify_tolerance_m? : Double = 15.0,
) -> Result[RouteSummary, RouteError] {
  match require_points(points) {
    Ok(_) => ()
    Err(err) => return Err(err)
  }
  let distance_m = match route_distance_meters(points) {
    Ok(value) => value
    Err(err) => return Err(err)
  }
  let bbox = match bounding_box(points) {
    Ok(value) => value
    Err(err) => return Err(err)
  }
  let simplified = match
    simplify_route(points, tolerance_m=simplify_tolerance_m) {
    Ok(value) => value
    Err(err) => return Err(err)
  }
  let encoded_polyline = match encode_polyline(points) {
    Ok(value) => value
    Err(err) => return Err(err)
  }
  let tiles = match tile_cover(points, zoom) {
    Ok(value) => value
    Err(err) => return Err(err)
  }
  Ok({
    point_count: points.length(),
    simplified_point_count: simplified.length(),
    distance_m,
    bbox,
    encoded_polyline,
    tiles,
    zoom,
  })
}

///|
pub fn RouteSummary::report(self : RouteSummary) -> String {
  [
    "points: \{self.point_count}",
    "distance_m: \{round_meters(self.distance_m)}",
    "simplified_points: \{self.simplified_point_count}",
    "bbox: \{self.bbox.to_string()}",
    "encoded_polyline: \{self.encoded_polyline}",
    "tiles@\{self.zoom}: \{tiles_to_string(self.tiles)}",
  ].join("\n")
}