|
| 1 | +--- |
| 2 | +title: Linear Referencing |
| 3 | +description: How Overture uses linear references to describe properties that vary along a segment |
| 4 | +pagination_label: Linear Referencing |
| 5 | +--- |
| 6 | + |
| 7 | +import ThemedImage from '@theme/ThemedImage'; |
| 8 | +import useBaseUrl from '@docusaurus/useBaseUrl'; |
| 9 | + |
| 10 | +Linear referencing allows properties to apply to portions of a [segment](../segments-and-connectors#segments) without splitting the geometry. This promotes shape stability and reduces versioning when only part of a road changes. |
| 11 | + |
| 12 | +To avoid splitting road segments at any and every property change, linear referencing defines how properties that apply to portions of a segment can vary along that segment while it is generally understood to be the same "road." Segment splits are then reserved for more significant intersections so that we don't have to version the entire road any time any piece of the road changes. |
| 13 | + |
| 14 | +## Linear reference values |
| 15 | + |
| 16 | +A linear reference is a **normalized position** from `0.0` (start of segment) to `1.0` (end of segment). |
| 17 | + |
| 18 | +## `at` vs `between` |
| 19 | + |
| 20 | +| Property | Purpose | Example | |
| 21 | +|----------|---------|---------| |
| 22 | +| `at` | Single point location | `at: 0.3` — 30% along segment | |
| 23 | +| `between` | Range along segment | `between: [0.2, 0.7]` — 20% to 70% | |
| 24 | + |
| 25 | +When `between` is not provided (or is null), the attribute applies to the full segment. |
| 26 | + |
| 27 | +## Calculation method |
| 28 | + |
| 29 | +Overture computes linear references using **WGS84 geodetic distance** in meters: |
| 30 | + |
| 31 | +``` |
| 32 | +linear_ref = geodetic_distance_along_segment_from_start / total_geodetic_length |
| 33 | +``` |
| 34 | + |
| 35 | +Both distances must be computed on the WGS84 ellipsoid, not planar distance on raw lon/lat coordinates. Other approaches exist (e.g., projected coordinates), but geodetic distance provides consistent accuracy globally. |
| 36 | + |
| 37 | +### Examples |
| 38 | + |
| 39 | +**Apache Sedona (SQL):** |
| 40 | + |
| 41 | +```sql |
| 42 | +SELECT ST_LENGTHSPHEROID(ST_GEOMFROMWKB(geometry)) AS segment_length_m |
| 43 | +FROM segments; |
| 44 | +``` |
| 45 | + |
| 46 | +**pyproj (Python):** |
| 47 | + |
| 48 | +```python |
| 49 | +from pyproj import Geod |
| 50 | +from shapely import wkb |
| 51 | + |
| 52 | +geod = Geod(ellps="WGS84") |
| 53 | +line_geometry = wkb.loads(geometry) # geometry is WKB bytes |
| 54 | +segment_length = geod.geometry_length(line_geometry) # meters |
| 55 | +``` |
| 56 | + |
| 57 | +See the [transportation-splitter](https://github.com/OvertureMaps/transportation-splitter) for a complete implementation. |
| 58 | + |
| 59 | +:::warning |
| 60 | +Functions like `ST_LINELOCATEPOINT` can produce incorrect results on geometries that cross over or near themselves in 2D (curved on-ramps, mountain switchbacks, cul-de-sacs). These functions may pick the wrong location when the line passes over or close to itself, even though the geometry is valid because crossings occur at different elevations or positions along the segment. Note that Overture [disallows self-intersecting segments](../segments-and-connectors#loops) in its own data. |
| 61 | +::: |
| 62 | + |
| 63 | +## Why geodetic distance matters |
| 64 | + |
| 65 | +Using planar distance (treating lon/lat as Cartesian x/y) can produce incorrect linear references, especially at high latitudes or for long segments. For a 10 km east-west segment at 60°N latitude, planar calculations can underestimate length by ~50%. Some map projections (e.g., EPSG:3857) yield reasonable results for short, straight segments, but accuracy degrades with segment length and curvature. |
| 66 | + |
| 67 | +If a consumer calculates linear references differently than Overture, attribution or connector positions may be misaligned, potentially causing visual discrepancies on rendered maps or routing failures. |
| 68 | + |
| 69 | +## Edge cases |
| 70 | + |
| 71 | +For very short segments (under 1 meter), floating-point precision may be limited. Treat `at` values near `0.0` or `1.0` as equivalent to endpoints. When a connector does not fall exactly on the geometry, the linear reference corresponds to the closest point on the segment. |
0 commit comments