diff --git a/docs/schema/concepts/by-theme/transportation/index.mdx b/docs/schema/concepts/by-theme/transportation/index.mdx index fd9686d7c..7c17c1595 100644 --- a/docs/schema/concepts/by-theme/transportation/index.mdx +++ b/docs/schema/concepts/by-theme/transportation/index.mdx @@ -60,8 +60,8 @@ properties: ### Destinations The destination property in the `segment` feature type supports routing use cases. It describes the transitions from one segment to another on the way to a specified location. In turn-by-turn routing applications, this is what is known as “follow signs for” — the human-readable directions and signposts along a road, highway, or interstate that get us from point A to point Z, by way of any number of paths in between. We designed the `destinations` property with a flexible schema that will allow us to capture and model navigation data from many different sources. -### Linear referencing -The `segment` feature type uses linear referencing to describe the properties of specific sections of a road along a road segment. To avoid splitting road segments at any and every property change, we added linear referencing, which defines how some properties apply to portions of a segment can change along a segment that 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. Other than some expected challenges learning how Linear Referencing worked, we noticed that the main difficulty really arises is when people want to convert the transportation data into a routing graph. Many routing engines want the data to be split at every 'decision point' where each decision is what amounts to a connector between segments the routing engine would consider routing on (e.g. vehicle routing would eliminate sidewalks). However that decision of what segments would be considered for routing someone varies significantly by application, even within similar 'types' of routing, so we could not identify a common subset of splitting rules that would meet all or even most of the various use cases of the members, much less the community at large. +### [Linear referencing](/schema/concepts/by-theme/transportation/linear-referencing) +The `segment` feature type uses linear referencing to describe the properties of specific sections of a road along a road segment. To avoid splitting road segments at any and every property change, we added linear referencing, which 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. Other than some expected challenges learning how linear referencing worked, we noticed that the main difficulty really arises when people want to convert the transportation data into a routing graph. Many routing engines want the data to be split at every 'decision point' where each decision is what amounts to a connector between segments the routing engine would consider routing on (e.g. vehicle routing would eliminate sidewalks). However that decision of what segments would be considered for routing varies significantly by application, even within similar 'types' of routing, so we could not identify a common subset of splitting rules that would meet all or even most of the various use cases of the members, much less the community at large. ### [Scoped and rule-based properties](/schema/concepts/scoping-rules) The schema allows the values of properties to be specified at the sub-feature level. For example: diff --git a/docs/schema/concepts/by-theme/transportation/linear-referencing.mdx b/docs/schema/concepts/by-theme/transportation/linear-referencing.mdx new file mode 100644 index 000000000..ac55f38cc --- /dev/null +++ b/docs/schema/concepts/by-theme/transportation/linear-referencing.mdx @@ -0,0 +1,62 @@ +--- +title: Linear Referencing +--- + +Linear referencing allows properties to apply to portions of a segment without splitting the geometry. This promotes shape stability and reduces versioning when only part of a road changes. + +## Linear reference values + +A linear reference is a **normalized position** from `0.0` (start of segment) to `1.0` (end of segment). + +## `at` vs `between` + +| Property | Purpose | Example | +|----------|---------|---------| +| `at` | Single point location | `at: 0.3` — 30% along segment | +| `between` | Range along segment | `between: [0.2, 0.7]` — 20% to 70% | + +When `between` is not provided (or is null), the attribute applies to the full segment. + +## Calculation method + +Overture computes linear references using **WGS84 geodetic distance** in meters: + +``` +linear_ref = geodetic_distance_along_segment_from_start / total_geodetic_length +``` + +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. + +### Examples + +**Apache Sedona (SQL):** + +```sql +SELECT ST_LENGTHSPHEROID(ST_GEOMFROMWKB(geometry)) AS segment_length_m +FROM segments; +``` + +**pyproj (Python):** + +```python +from pyproj import Geod +from shapely import wkb + +geod = Geod(ellps="WGS84") +line_geometry = wkb.loads(geometry) # geometry is WKB bytes +segment_length = geod.geometry_length(line_geometry) # meters +``` + +See the [transportation-splitter](https://github.com/OvertureMaps/transportation-splitter) for a complete implementation. + +**Warning:** 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](/schema/concepts/by-theme/transportation/shape-connectivity#loops) in its own data. + +## Why geodetic distance matters + +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. + +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. + +## Edge cases + +For very short segments (< 1m), floating-point precision may be limited. Treat `at ≈ 0.0` or `at ≈ 1.0` as equivalent to endpoints. When a connector doesn't fall exactly on the geometry, the linear reference corresponds to the closest point on the segment.