Shapes¶
Shapes ¶
Shapes(lf: Optional[LazyFrame] = None, stop_shapes: Optional[LazyFrame] = None, gdf: Optional[GeoDataFrame] = None)
Manage GTFS shapes.txt data using Polars LazyFrames.
Attributes:
| Name | Type | Description |
|---|---|---|
lf |
LazyFrame
|
One row per point (real shape point or inserted
stop) per synthetic |
stop_shapes |
LazyFrame
|
The subset of |
gdf |
GeoDataFrame
|
One row per |
Wraps already-loaded shape frames, or leaves them empty for load to fill in.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lf
|
Optional[LazyFrame]
|
Optional pre-loaded shape-points LazyFrame. |
None
|
stop_shapes
|
Optional[LazyFrame]
|
Optional pre-computed stop-subset LazyFrame (see the class docstring). |
None
|
gdf
|
Optional[GeoDataFrame]
|
Optional pre-built per- |
None
|
Source code in pyGTFSHandler/models/shapes.py
load ¶
load(path: Union[str, Path, List[Union[str, Path]], None], trip_shape_ids_lf: LazyFrame, stops_lf: LazyFrame, check_files: bool = False, min_file_id: int = 0, collision_registry=None, aoi: Optional[Union[GeoDataFrame, GeoSeries]] = None) -> None
Builds self.lf/self.stop_shapes/self.gdf.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Union[str, Path, List[Union[str, Path]], None]
|
GTFS directory/directories to look for |
required |
trip_shape_ids_lf
|
LazyFrame
|
Output of |
required |
stops_lf
|
LazyFrame
|
The feed's stops LazyFrame ( |
required |
aoi
|
Optional[Union[GeoDataFrame, GeoSeries]]
|
Optional Area of Interest (GeoDataFrame/GeoSeries), same
object callers already pass into |
None
|
Source code in pyGTFSHandler/models/shapes.py
assign_direction_ids ¶
assign_direction_ids(trip_shape_ids_lf: LazyFrame, trips_lf: LazyFrame, stops_lf: Optional[LazyFrame] = None, method: str = 'both') -> pl.LazyFrame
Integrates a globally-reconciled direction_id into self.stop_shapes.
See the module docstring's "Direction assignment pipeline" section
for how this fits together with _assign_direction_ids_for_route
and the module-level bearing helpers. In short: adds a route_id,
a resolved direction_id (0/1), and a boolean direction_conflict
flag directly onto self.stop_shapes, on top of the raw
shape_direction/shape_direction_backwards bearings already
there.
Bearings are gathered and split per (route_id, parent_station),
not per raw stop_id (falling back to stop_id itself when
stops_lf isn't given or a stop has no parent_station): a
station's separate platform stop_ids (e.g. paired platforms on
either side of a road) are where GTFS actually records distinct
rows, but splitting each platform's handful of shapes independently
starves the widest-gap computation of the corroborating shapes its
sibling platform sees, right where it matters most -- multi-route
interchanges. Pooling by station gives every shape passing through
it, on any of its platforms, a say in that station's split.
Per-station local clustering (_widest_gap_split) only ever
produces labels that are meaningful at that one station; a route
whose shapes branch (e.g. one trip pattern continuing straight,
another turning off) can trivially get inconsistent 0/1 numbering
between stations if each is labelled independently.
_assign_direction_ids_for_route reconciles that per route_id --
see its docstring for the full algorithm.
A shape_id shared by more than one route_id (uncommon, but
possible) gets one row per (shape_id, stop_id, route_id) here,
since direction is inherently a per-route concept -- so
self.stop_shapes may end up with more rows than before for such
shapes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
trip_shape_ids_lf
|
LazyFrame
|
Output of |
required |
trips_lf
|
LazyFrame
|
The feed's trips LazyFrame, at least |
required |
stops_lf
|
Optional[LazyFrame]
|
The feed's stops LazyFrame ( |
None
|
method
|
str
|
|
'both'
|
Returns:
| Type | Description |
|---|---|
LazyFrame
|
|
LazyFrame
|
|
LazyFrame
|
|
Source code in pyGTFSHandler/models/shapes.py
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 | |
See also Direction & headway methodology for the bearing-based direction assignment implemented here.