From de839bd4bea51528987823cb6d92a6de45e69805 Mon Sep 17 00:00:00 2001 From: Alex Iannicelli Date: Wed, 2 Sep 2026 14:11:59 -0400 Subject: [PATCH] Add travel_time property to water segments Adds an optional travel_time property (integer seconds, minimum 1) to the water subtype in both the Pydantic WaterSegment model and the YAML JSON Schema, capturing the scheduled end-to-end crossing time sourced from the OSM duration tag on ferry routes. Includes examples, counterexamples, regenerated JSON Schema baseline, changelog fragment, and a docs note. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Signed-off-by: Alex Iannicelli --- .../segment/water/bad-travel-time-type.yaml | 14 ++++++++++ .../water/bad-travel-time-wrong-subtype.yaml | 14 ++++++++++ .../segment/water/bad-travel-time-zero.yaml | 13 ++++++++++ .../reference/transportation/segment.mdx | 6 ++++- .../segment/water/water-ferry.yaml | 20 ++++++++++++++ .../changelog.d/711.feature.md | 1 + .../schema/transportation/segment/water.py | 26 +++++++++++++++++-- .../tests/segment_baseline_schema.json | 7 +++++ .../segment/water/bad-travel-time-type.yaml | 14 ++++++++++ .../water/bad-travel-time-wrong-subtype.yaml | 14 ++++++++++ .../segment/water/bad-travel-time-zero.yaml | 13 ++++++++++ .../segment/water/water-ferry.yaml | 20 ++++++++++++++ schema/transportation/segment.yaml | 14 +++++++++- 13 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 counterexamples/transportation/segment/water/bad-travel-time-type.yaml create mode 100644 counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml create mode 100644 counterexamples/transportation/segment/water/bad-travel-time-zero.yaml create mode 100644 examples/transportation/segment/water/water-ferry.yaml create mode 100644 packages/overture-schema-theme-transportation/changelog.d/711.feature.md create mode 100644 reference/counterexamples/transportation/segment/water/bad-travel-time-type.yaml create mode 100644 reference/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml create mode 100644 reference/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml create mode 100644 reference/examples/transportation/segment/water/water-ferry.yaml diff --git a/counterexamples/transportation/segment/water/bad-travel-time-type.yaml b/counterexamples/transportation/segment/water/bad-travel-time-type.yaml new file mode 100644 index 000000000..5367da43c --- /dev/null +++ b/counterexamples/transportation/segment/water/bad-travel-time-type.yaml @@ -0,0 +1,14 @@ +--- +# Counterexample: travel_time is an integer number of seconds, not an +# ISO 8601 / OSM-style duration string. +id: bad-travel-time-type +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + travel_time: "00:15" diff --git a/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml b/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml new file mode 100644 index 000000000..5057138fd --- /dev/null +++ b/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml @@ -0,0 +1,14 @@ +--- +# Counterexample: travel_time is only allowed on water segments. +id: bad-travel-time-wrong-subtype +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: road + class: primary + travel_time: 900 diff --git a/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml b/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml new file mode 100644 index 000000000..7752b8169 --- /dev/null +++ b/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml @@ -0,0 +1,13 @@ +--- +# Counterexample: travel_time must be a positive number of seconds. +id: bad-travel-time-zero +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + travel_time: 0 diff --git a/docs/schema/reference/transportation/segment.mdx b/docs/schema/reference/transportation/segment.mdx index 828fa5520..8b1469a09 100644 --- a/docs/schema/reference/transportation/segment.mdx +++ b/docs/schema/reference/transportation/segment.mdx @@ -103,7 +103,11 @@ The schema for `rail` segments is under development. -The schema for `water` segments is under development. +The schema for `water` segments is under development. Water segments support +an optional `travel_time` property that captures the scheduled time, in +seconds, to traverse the full segment from end to end, including time spent +docking, loading, and unloading (sourced from the OSM `duration` tag on ferry +routes). diff --git a/examples/transportation/segment/water/water-ferry.yaml b/examples/transportation/segment/water/water-ferry.yaml new file mode 100644 index 000000000..bc170ad20 --- /dev/null +++ b/examples/transportation/segment/water/water-ferry.yaml @@ -0,0 +1,20 @@ +--- +id: overture:transportation:segment:123 +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + connectors: + - connector_id: fooConnector + at: 0 + - connector_id: barConnector + at: 1 + names: + primary: Generic Ferry Route + # 15-minute scheduled crossing, e.g. from OSM duration=00:15 + travel_time: 900 diff --git a/packages/overture-schema-theme-transportation/changelog.d/711.feature.md b/packages/overture-schema-theme-transportation/changelog.d/711.feature.md new file mode 100644 index 000000000..0be9847bd --- /dev/null +++ b/packages/overture-schema-theme-transportation/changelog.d/711.feature.md @@ -0,0 +1 @@ +Added a `travel_time` property to water segments capturing the scheduled end-to-end crossing time in seconds, sourced from the OSM `duration` tag on ferry routes. diff --git a/packages/overture-schema-theme-transportation/src/overture/schema/transportation/segment/water.py b/packages/overture-schema-theme-transportation/src/overture/schema/transportation/segment/water.py index ed68b4b98..e327a8cb2 100644 --- a/packages/overture-schema-theme-transportation/src/overture/schema/transportation/segment/water.py +++ b/packages/overture-schema-theme-transportation/src/overture/schema/transportation/segment/water.py @@ -1,11 +1,29 @@ """Water segment and its supporting types.""" -from typing import Literal +import textwrap +from typing import Annotated, Literal, NewType -from pydantic import ConfigDict +from pydantic import ConfigDict, Field + +from overture.schema.system.numeric import int32 from ._common import SegmentSubtype, TransportationSegment +TravelTime = NewType( + "TravelTime", + Annotated[ + int32, + Field( + ge=1, + description=textwrap.dedent(""" + Scheduled travel time, in seconds, to traverse the full segment from end + to end, including time spent docking, loading, and unloading. Sourced + from the OSM duration tag on ferry routes. + """).strip(), + ), + ], +) + class WaterSegment(TransportationSegment): """Water segment properties.""" @@ -15,3 +33,7 @@ class WaterSegment(TransportationSegment): # Discriminator subtype: Literal[SegmentSubtype.WATER] + + # Optional + + travel_time: TravelTime | None = None diff --git a/packages/overture-schema-theme-transportation/tests/segment_baseline_schema.json b/packages/overture-schema-theme-transportation/tests/segment_baseline_schema.json index d9f38e4f4..62cf00936 100644 --- a/packages/overture-schema-theme-transportation/tests/segment_baseline_schema.json +++ b/packages/overture-schema-theme-transportation/tests/segment_baseline_schema.json @@ -1660,6 +1660,13 @@ "title": "Theme", "type": "string" }, + "travel_time": { + "description": "Scheduled travel time, in seconds, to traverse the full segment from end\nto end, including time spent docking, loading, and unloading. Sourced\nfrom the OSM duration tag on ferry routes.", + "maximum": 2147483647, + "minimum": 1, + "title": "Travel Time", + "type": "integer" + }, "type": { "const": "segment", "title": "Type", diff --git a/reference/counterexamples/transportation/segment/water/bad-travel-time-type.yaml b/reference/counterexamples/transportation/segment/water/bad-travel-time-type.yaml new file mode 100644 index 000000000..5367da43c --- /dev/null +++ b/reference/counterexamples/transportation/segment/water/bad-travel-time-type.yaml @@ -0,0 +1,14 @@ +--- +# Counterexample: travel_time is an integer number of seconds, not an +# ISO 8601 / OSM-style duration string. +id: bad-travel-time-type +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + travel_time: "00:15" diff --git a/reference/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml b/reference/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml new file mode 100644 index 000000000..5057138fd --- /dev/null +++ b/reference/counterexamples/transportation/segment/water/bad-travel-time-wrong-subtype.yaml @@ -0,0 +1,14 @@ +--- +# Counterexample: travel_time is only allowed on water segments. +id: bad-travel-time-wrong-subtype +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: road + class: primary + travel_time: 900 diff --git a/reference/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml b/reference/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml new file mode 100644 index 000000000..7752b8169 --- /dev/null +++ b/reference/counterexamples/transportation/segment/water/bad-travel-time-zero.yaml @@ -0,0 +1,13 @@ +--- +# Counterexample: travel_time must be a positive number of seconds. +id: bad-travel-time-zero +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + travel_time: 0 diff --git a/reference/examples/transportation/segment/water/water-ferry.yaml b/reference/examples/transportation/segment/water/water-ferry.yaml new file mode 100644 index 000000000..bc170ad20 --- /dev/null +++ b/reference/examples/transportation/segment/water/water-ferry.yaml @@ -0,0 +1,20 @@ +--- +id: overture:transportation:segment:123 +type: Feature +geometry: + type: LineString + coordinates: [[0, 0], [1, 1]] +properties: + theme: transportation + type: segment + version: 1 + subtype: water + connectors: + - connector_id: fooConnector + at: 0 + - connector_id: barConnector + at: 1 + names: + primary: Generic Ferry Route + # 15-minute scheduled crossing, e.g. from OSM duration=00:15 + travel_time: 900 diff --git a/schema/transportation/segment.yaml b/schema/transportation/segment.yaml index 4a959a1a6..7f846f111 100644 --- a/schema/transportation/segment.yaml +++ b/schema/transportation/segment.yaml @@ -47,9 +47,10 @@ properties: subtype: { const: rail } class: { "$ref": "#/$defs/propertyDefinitions/railClass" } rail_flags: { "$ref": "#/$defs/propertyContainers/railFlagsContainer" } - - title: "Water-Specific Properties" # Placeholder for future water properties + - title: "Water-Specific Properties" properties: subtype: { const: water } + travel_time: { "$ref": "#/$defs/propertyDefinitions/travelTime" } properties: subtype: description: Broad category of transportation segment. @@ -305,6 +306,17 @@ properties: - driveway # Service road intended for deliveries - alley # Service road intended for rear entrances, fire exits - cycle_crossing # Cycleway that intersects with other roads + travelTime: + description: >- + Scheduled travel time, in seconds, to traverse the full segment + from end to end, including time spent docking, loading, and + unloading. + type: integer + minimum: 1 + "$comment": >- + Sourced from the OSM duration tag on ferry routes. Unlike a speed + limit, this value captures the scheduled end-to-end crossing time, + so routers can compute realistic ETAs for ferry crossings. speed: description: >- A speed value, i.e. a certain number of distance units