Files

4.0 KiB

Design: OSM turn-lane arrows

Boundaries

  • scripts/build-osm2streets-qgis.js remains the intermediates owner. It will append generated custom features to the existing in-memory laneArrows collection before it is written as lane_arrows_webscale.geojson.
  • No render layer, QGIS symbol, Blender material, or Cesium export contract changes. Existing lane_arrows_webscale styling and catalog ownership apply to generated features automatically.
  • Vendored upstream artwork lives under a dedicated repository-local asset directory with its CC0 license and a machine-readable manifest. The manifest is the source of truth for upstream path, source revision, local path, support status, and test status.

Asset Contract

  • Import every arrow SVG from openstreetmap/lane-icons/docs/ that represents an arrow. Preserve the source bytes and retain LICENSE.md with the assets.
  • Mark only through, left, right, through;left, and through;right as supported and tested in the manifest. All remaining imported arrows are unsupported and untested; no production parser may select them.
  • The upstream repository has left-side examples only. Derive right and through;right through a deterministic horizontal mirror of the matching left-side geometry, recording derived_from in the manifest.

Data Flow

  1. Parse OSM ways once using the existing OSM parser.
  2. Read turn:lanes:forward / turn:lanes:backward, split lane declarations by |, and map only the five supported normalized maneuvers to manifest entries.
  3. For each valid lane near a determinable intersection endpoint, calculate a stable lane center and road-local axis; transform the selected local arrow polygon into WGS84 coordinates.
  4. Add a GeoJSON feature with existing render-layer behavior and explicit provenance: custom source, OSM way id, direction, lane index, maneuver, source asset, and deterministic feature id/order.
  5. Record a structured skipped item when tags, lane geometry, or endpoint classification are insufficient. Do not invent a fallback location.
  6. Existing normalization, scene merge, GeoPackage import, Blender assembly, and Cesium export consume the expanded collection unchanged.

Geometry and Compatibility

  • Parse only the vendored SVG subset used by supported assets at build time: line elements and path commands are converted into local meter-scale polygons, with cubic curves sampled and SVG strokes expanded into outlines. The source SVG is the sole geometry authority; no hand-drawn replacement template is permitted. This stays dependency-free because the supported upstream syntax is intentionally small and covered by Node tests.
  • Use the upstream Standard Arrow shape as the geometry basis, but let the existing QGIS fill and outline preserve the project's visual language.
  • Preserve the existing osm2streets-generated arrow features. Custom features are additive and have provenance that distinguishes them from upstream osm2streets output.
  • Deterministic ordering is by way id, travel direction, and lane index.
  • Each asset manifest entry defines the source SVG's shaft-axis anchor_x. Placement aligns that axis, rather than the SVG viewBox center, with the lane centerline. Mirrored right-side variants mirror around the same axis.
  • Upstream SVG units are converted at 0.10 m per unit. This calibrates their local extent against the existing approximately 1.4 m osm2streets arrows; do not use SVG display-pixel scale as road-marking scale.

Risks and Rollback

  • OSM lane counts, one-way semantics, or endpoint topology can be incomplete. These cases remain skipped with diagnostics rather than creating misleading markings.
  • Asset import is self-contained and CC0. Rollback removes the custom feature generation and local asset directory; the existing arrow layer remains unchanged.
  • User approval of the two initial visual samples is required before the feature is enabled in production output.