Skip to content

mamut_routing_tools.geometry.materialize

Route-geometry materialization: the engine behind the website's hash-addressed BKS road geometry.

Consumes the same group plan the website's route_geometry.py used to hand to the Julia materializer, and produces byte-compatible result payloads: per group, an edge_cache of node:{from}_{to} polylines, per-BKS edge_keys, and the set of straight-line fallback edges.

Semantics ported from site_api.jl: per-edge resolution walks the map candidates in cascade order, requires both endpoints to map to a graph vertex (nearest road node within 100 m must itself be a vertex), routes with the group metric, accepts a segment only when its endpoints land within 250 m of the instance node coordinates, tries the reversed edge before giving up, and falls back to a straight line between the node coordinates.

One addition over the Julia semantics: an instance node with no road node in its 100 m box (or whose nearest node is not a vertex) is projected onto the nearest straight edge of a node-level candidate graph and routed from that virtual point (:class:EdgeAnchor). Mamut2026 corner depots are often synthetic crop nodes of the generation-time extract; when the website re-fetches the city with other bounds, that node no longer exists and the depot sits mid-segment on a road, which used to turn every depot leg into a straight line. Nodes that resolve to a vertex keep the exact former path.

EdgeAnchor dataclass

EdgeAnchor(
    edge_index: int, fraction: float, lonlat: list[float]
)

An instance node resolved to a point ON a directed graph edge rather than to a vertex: fraction along edge_index (0 = tail, 1 = head), lonlat the projected point the polyline starts or ends at.

graph_node_maps

graph_node_maps(
    graph: RoadGraph,
    node_coordinates: dict[int, list[float]],
) -> tuple[dict[int, int], dict[int, EdgeAnchor]]

Both node resolutions of one candidate graph: vertices first, edge anchors only for what the vertex rule could not place.

Source code in MAMUT-routing-tools/src/mamut_routing_tools/geometry/materialize.py
def graph_node_maps(
    graph: RoadGraph, node_coordinates: dict[int, list[float]]
) -> tuple[dict[int, int], dict[int, EdgeAnchor]]:
    """Both node resolutions of one candidate graph: vertices first, edge
    anchors only for what the vertex rule could not place."""
    vertex_map = _graph_vertex_map(graph, node_coordinates)
    return vertex_map, _graph_edge_anchor_map(graph, node_coordinates, vertex_map)

materialize_plan

materialize_plan(
    repo_root: str | Path, plan: dict[str, Any]
) -> dict[str, dict[str, Any]]

Process every group; returns {result_file: result_payload}.

Source code in MAMUT-routing-tools/src/mamut_routing_tools/geometry/materialize.py
def materialize_plan(repo_root: str | Path, plan: dict[str, Any]) -> dict[str, dict[str, Any]]:
    """Process every group; returns {result_file: result_payload}."""
    root = Path(repo_root)
    results: dict[str, dict[str, Any]] = {}
    for group in plan["groups"]:
        results[str(group["result_file"])] = materialize_group(root, group)
    return results