// search
Back to feed

Superblocker: Budapest update

An update to the first Superblocker post.

The first version demonstrated the graph problem, but it made several shortcuts: it analyzed a rectangular search result, inferred arterial roads from OpenStreetMap road classes and graph centrality, and treated road-network nodes as access proxies. The result was useful for testing the algorithm, but it was not an implementation-ready traffic plan.

The current version makes those distinctions explicit and runs the analysis on Budapest’s administrative polygon.

Budapest city-wide Superblocker analysis

The search endpoint now requests GeoJSON from Nominatim. If the result contains a valid polygon or multipolygon, the same geometry is used to:

  • download the OSM driving graph;
  • clip generated cells;
  • calculate coverage;
  • validate route endpoints;
  • draw the administrative outline on the map.

The bounding box is still kept for fitting the map. It is only used for analysis when Nominatim does not return an area geometry, and the result is marked as a fallback.

For Budapest, the exact-polygon run loaded 24,525 nodes and 64,026 directed edges. The rendered network contains 37,406 physical road segments covering 4,743.65 kilometres.

The algorithm generated 726 cells. Their union covers 34.7% of the administrative area. That number is not “34.7% of Budapest converted”. It is the area enclosed by accepted road cells divided by the municipal polygon. The Danube, parks, railway land, large industrial areas, and places without a closed boundary-road ring do not necessarily produce cells.

The run proposed 2,439 changes:

  • 2,371 modal filters;
  • 4 one-way conversions;
  • 24 local two-way repairs;
  • 40 full motor-traffic closures.

Each proposal is shown both as a map symbol and as a street-level work item. The list names the road and gives the exact point of the proposed change instead of presenting a pile of anonymous graph edges.

Street-level proposed changes in Budapest

The main algorithmic constraint is unchanged: a vehicle entering a generated cell from one sector must not be able to leave through another sector using the interior road network. Cross-traffic has to return to the boundary-road network.

The wording around validation has changed. A pass now means only this:

In the transformed directed graph, no modeled vehicle path connects entry points assigned to different sectors of the same generated cell.

All 726 Budapest cells passed that graph test. This does not prove that signs can be installed as drawn, that every turn is physically possible, or that drivers will comply. It also says nothing by itself about emergency access, loading, legal restrictions, signal timing, road width, or construction conditions.

Traffic evidence is handled separately. The app accepts measured traffic observations keyed by OSM way ID. When matching counts are supplied, measured vehicles per hour determine the boundary-road selection. Without measured counts, the app can still use road class and approximate edge centrality, but it labels the result modeled_topology and blocks it from implementation.

The same separation now exists for local access. Road-network nodes are no longer described as addresses. The app accepts explicit GeoJSON points for addresses, parcels, buildings, deliveries, and emergency access. Each target is assigned to a cell, snapped to its interior road graph, and checked for both an inbound path and a return path.

Exact boundary and evidence input controls

Every generated result has an evidence record and a release status. implementation_ready requires:

  1. an exact administrative boundary;
  2. measured traffic observations covering at least 80% of physical road length;
  3. a complete, named access-target dataset;
  4. successful directional and access-path tests;
  5. a transport-engineering review;
  6. an on-site inspection.

The two reviews are submitted after generation and are tied to a SHA-256 digest of the exact plan. Changing the geometry, actions, evidence, or statistics changes the plan ID, so an attestation cannot be reused for a modified result.

The Budapest run shown here intentionally had no external traffic-count or address/parcel dataset. Its status is therefore model_only, with four blockers: measured traffic evidence, complete access data, transport review, and site inspection. The UI shows those blockers instead of turning a successful graph test into a compliance claim.

City-scale processing is also substantially faster. The older rectangular run spent 670.4 seconds in partition processing. The exact-polygon Budapest run took 25.6 seconds to retrieve the graph and 14.6 seconds to process the partition, about 41 seconds end to end on the same test machine.

The speedup comes from indexing road geometries and cell polygons instead of repeatedly scanning them, reusing one coordinate transformer for area calculations, and limiting centrality sampling in topology-fallback mode. Runs with measured traffic skip centrality entirely.

The code, example evidence files, and the complete API description are in the repository: Superblocker

// comments