Link Trips
processing.link_trips.link
Trip Linker Module.
MODE_TYPE_TO_ACCESS_EGRESS
module-attribute
MODE_TYPE_TO_ACCESS_EGRESS = {
ModeType.WALK.value: AccessEgressMode.WALK.value,
ModeType.BIKE.value: AccessEgressMode.BICYCLE.value,
ModeType.BIKESHARE.value: AccessEgressMode.BICYCLE.value,
ModeType.SCOOTERSHARE.value: AccessEgressMode.MICROMOBILITY.value,
ModeType.TAXI.value: AccessEgressMode.TNC.value,
ModeType.TNC.value: AccessEgressMode.TNC.value,
ModeType.CAR.value: AccessEgressMode.CAR_HOUSEHOLD.value,
ModeType.CARSHARE.value: AccessEgressMode.CAR_OTHER.value,
ModeType.SCHOOL_BUS.value: AccessEgressMode.TRANSFER_BUS.value,
ModeType.SHUTTLE.value: AccessEgressMode.TRANSFER_BUS.value,
ModeType.FERRY.value: AccessEgressMode.TRANSFER_OTHER.value,
ModeType.TRANSIT.value: AccessEgressMode.TRANSFER_OTHER.value,
ModeType.LONG_DISTANCE.value: AccessEgressMode.TRANSFER_OTHER.value,
ModeType.OTHER.value: AccessEgressMode.OTHER.value,
ModeType.MISSING.value: AccessEgressMode.MISSING.value,
}
ModeType to AccessEgressMode mapping for transit access/egress.
Maps travel mode types to access/egress mode categories used in transit trip analysis. This mapping is used when aggregating linked trips to classify non-transit segments as access or egress modes for transit journeys.
link_trips
link_trips(
unlinked_trips: pl.DataFrame,
change_mode_enum: str,
transit_mode_enums: list[str],
max_dwell_time: float = 120,
dwell_buffer_distance: float = 100,
) -> dict[str, pl.DataFrame]
Link unlinked trip segments into complete journey records.
Detects mode changes and aggregates trip chains by validating spatial and temporal continuity across consecutive trips.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
unlinked_trips
|
pl.DataFrame
|
Individual trip records with person_id, day_id, depart_time, arrive_time, o/d locations, o/d purposes, mode_type. |
required |
change_mode_enum
|
str
|
Enum label indicating a mode change purpose. |
required |
transit_mode_enums
|
list[str]
|
List of enum labels that count as transit modes. |
required |
max_dwell_time
|
float
|
Maximum time gap between trips to link them, in minutes (default: 120). |
120
|
dwell_buffer_distance
|
float
|
Maximum spatial distance between trips to link, in meters (default: 100). |
100
|
Returns:
| Type | Description |
|---|---|
dict[str, pl.DataFrame]
|
Dictionary containing: - unlinked_trips: Original trips with added linked_trip_id column - linked_trips: Aggregated journey records with combined attributes |
Algorithm
Phase 1: Link Trip IDs
- Sort unlinked trips by person, day, and departure time
- For each person-day sequence:
- If previous trip's destination purpose is change_mode_enum, continue current linked trip
- Validate spatial/temporal continuity:
- Time gap between trips ≤ max_dwell_time minutes
- Distance between previous destination and current origin ≤ dwell_buffer_distance meters
- Otherwise, start a new linked trip
- Assign globally unique linked_trip_id = (day_id * 1000) + sequence_number
Phase 2: Aggregate Linked Trips
- Group unlinked trips by linked_trip_id
- For each linked trip, aggregate:
- Origin/Destination: First trip's origin, last trip's destination
- Timing: First depart_time, last arrive_time
- Distance: Sum of all trip distances
- Duration: Sum of all trip durations (including dwell time)
- Purposes: First origin purpose, last destination purpose
- Mode Logic:
- If any trip uses transit → mode_type = TRANSIT
- Otherwise, use mode of longest distance trip
- Transit Details: Count boarding/alighting, aggregate access/egress modes
- Driver/Passenger: Aggregate from component trips
- Create trip_list array containing all component trip IDs
Notes
- Links trips when travelers make intermediate stops for mode changes or transfers
- Preserves full trip detail in unlinked_trips while creating journey-level linked_trips
- Transit detection ensures multi-modal journeys classified correctly
- Access/egress mode mapping converts trip modes to transit-specific codes
- Spatial/temporal thresholds prevent false linkages across separate journeys