Appearance
Spatial Service
Overview
The Spatial Service is the platform's geographic intelligence layer — responsible for all operations involving geographical data and mapping the geospatial relationships between entities in the OR stack. It functions as the unified interface to a suite of spatial tools and databases, enabling other services to geo-tag events, resolve locations, label road segments, and query spatial relationships without needing to manage low-level geospatial complexity directly.
From labelling an incident with the suburb it falls in, to determining which road segments are impacted by a traffic event, to encoding geographic regions into H3 hex tiles for efficient viewport queries — the Spatial Service is the single service through which all geospatial reasoning flows. It underpins the platform's ability to turn raw coordinates into meaningful location context that operators and AI agents can act on.
The service also integrates closely with the Location Reference Service (LRS), a REST/GraphQL API that ingests and transforms reference data into Tile38. LRS enables point-and-click location referencing on the map — when a user clicks a point, LRS finds all intersecting geo-features (LGAs, postcodes, road names, and up to 20 spatial attributes), calculates the nearest intersection, and returns a rich location description including distance, direction, and locality.
Architecture
- Port:
:1999 - Language: Julia
- Spatial Database: Tile38 (real-time geospatial data store)
- Graph Library: LightOSM (OpenStreetMap graph loading and routing)
- Geocoding: Mapbox Geocoding API
- Tiling: Uber H3 hex tiling system
Key Components
- Tile38 Interface — Stores and queries real-time geospatial data, tracking positions, locations, and boundaries of objects. Supports spatial operations like point-in-polygon, proximity search, and geofencing.
- LightOSM Interface — Loads the relevant OpenStreetMap graph on startup (version retrieved from the Experiment Manager via the
ListMapquery) and exposes graph-level operations for mapping objects to and from the OSM network. - Mapbox Geocoding — Converts latitude/longitude coordinates into street addresses for frontend display and human-readable location labelling.
- H3 Tiling API — Implements Uber's H3 hexagonal tiling system for spatial indexing and viewport-based data retrieval. Uses Resolution 6 for storing H3 hex indices in the database.
Data Flow
Experiment Manager (GQL) → provides map version metadata
↓
Spatial Service [:1999]
├── Loads LightOSM graph from S3 on startup
├── Initialises Tile38 geospatial store
└── Exposes HTTP endpoints for spatial operations
↓
Consumers: Data Loader, Data Ingestion, Frontend, LRSTile38 & Real-Time Geospatial Store
Tile38 is the backbone of the Spatial Service's real-time geospatial capabilities. It provides an in-memory spatial database optimised for tracking the positions and boundaries of objects, with support for geofencing, proximity queries, and spatial searches.
The LRS module uses its own Tile38 collections (LRS and LRS_AUX) to store reference geospatial data — including LGAs, postcodes, declared roads, and other geo-features. These collections are loaded by the LRS Data Loader EKS job, which runs on a schedule aligned with Map Manager step function updates.
LightOSM & Map Loading
On startup, the Spatial Service loads the current basemap as a LightOSM graph object. The map version is determined by querying the Experiment Manager's Map Data API, using the latest map stored under the BASEMAP_GEOMAPPING map type enum (based on the dt_dataloader timestamp).
This graph is held in memory and used for:
- Mapping external coordinate data onto OSM way segments
- Geocoding operations (matching input coordinates to the nearest road network elements)
- Providing the spatial backbone for other services that need to resolve coordinates to road IDs
The map can be reloaded at runtime without restarting the service.
Geocoding Interface
The geocoding interface maps coordinate-based route data onto OSM way segments. The message protocol has two parts:
Input Messages:
| Key | Type | Description |
|---|---|---|
route_id | String | Route ID for identifying the result in output (e.g. TMC location code) |
link_ids | Vector[Integer] | Link IDs (not used by the mapping interface directly) |
dirs | Vector[String] | Direction indicators — F (From: use path as-is) or T (To: reverse coordinates) |
coords | Vector[Vector[Float]] | Lat/lon coordinate pairs defining the path |
config | Dict | User settings for the mapper (e.g. mapping_error: "e_metric_combined") |
Output Messages:
| Key | Type | Description |
|---|---|---|
osm_ids | Vector[Integer] | Matched OSM way IDs |
route_id | String | Original route ID echoed back |
dirs | Vector[String] | OSM directions (A, B, O) |
error_value | Float | Error of match based on selected error metric |
len | Vector[Float] | Length of each matched OSM segment in metres |
offsets | Vector[Float] | Offset of first/last OSM IDs against input linestring in metres |
Direction convention: F means the coordinates follow the path direction and can be used as-is. T means coordinates are reversed — the list of GPS coordinates needs to be reversed to get the actual direction of intended travel. When flipping a series of segments, the entire link ordering must also be reversed, not just individual segment coordinates.
Offsets: The matched OSM linestring typically differs from the submitted path because OSM ways have fixed lengths. Positive offset values represent the additional distance that the OSM endpoints extend beyond the input linestring endpoints. To get the overlap of the matched first/last OSM IDs against the target linestring, subtract the offset value from the OSM segment length.
H3 Hex Tiling
The H3 system enables efficient spatial indexing for viewport-based data loading. The service exposes endpoints for encoding and decoding geographic features into H3 hex indices:
| Endpoint | Description |
|---|---|
/hex/encode_polygon | Encodes a polygon into H3 hex IDs |
/hex/encode_linestring | Encodes a linestring into H3 hex IDs |
/hex/encode_point | Encodes a point into H3 hex IDs |
/hex/decode_viewport | Decodes a viewport bounding box into H3 tile IDs |
These endpoints power zoom-level-aware data loading in the frontend:
| Level | Zoom | Tiles Covering Victoria | Roads Shown |
|---|---|---|---|
| Macro | 5 | 770 | Highways + Arterials |
| Meso | 6 | 5,394 | + Primary + Secondary |
| Micro | 7 | 37,826 | All (no road filter) |
At Zoom 5, each hex is approximately 8 km across (~16 km per tile hex). Resolution 6 is the standard for storing H3 indices in the database schema (columns on the Ways, EnvObj, and Events tables).
Location Reference Service (LRS)
The LRS is a REST/GraphQL API that provides rich location referencing for points and lines on the road network. It ingests reference data from Map Manager exports and VICMAP datasets into Tile38, then services two primary queries:
GetLocationReferenceDataForGeodetic— Given a point or set of points, returns intersecting geo-features (up to 20 spatial attributes including LGA, postcode, locality, road names, SES region, and more).GetLocationWayIdData— Given an OSM Way ID, resolves its geometries and finds all intersecting features.
Core LRS capabilities:
- Nearest Point: Finds the nearest road to an off-road point
- Closest Intersection: Finds the nearest intersection to a given point
- Literal Description: Calculates the nearest intersection, queries it for data, and returns distance, direction, locality, and road names
- Snapping: When
snappingOptionsistrue, points snap to the nearest intersection rather than the nearest road. For lines, snapping can be set independently for the first and last coordinates.
LRS data is refreshed through Map Manager step functions that run on a bi-monthly schedule (OSM deltas on the 1st and 15th, VICMAP TRANSPORT deltas on the 9th and 23rd), followed by the LRS Data Loader EKS job which loads updated data into Tile38.
Related Services
- Experiment Manager — Provides map version metadata and the GraphQL coordination layer
- Route Finder — Uses the same LightOSM graph infrastructure for route calculation
- Map Manager — Manages basemap versions, exports OSM data consumed by LRS
- Schematics — Uses Tile38 integration for spatial data in schematic views
- Data Ingestion — Sends coordinate data to Spatial for geo-tagging
- Data Loader — Loads reference data that Spatial Service consumes on startup
