@@ -894,8 +894,12 @@ func (copier *Copier) copyTripsAndStopTimes() error {
894894 trip .StopTimes = sts
895895
896896 // Set StopPattern
897+ // Empty key means flex trip - assign unique pattern ID without caching
897898 patkey := stopPatternKey (trip .StopTimes )
898- if pat , ok := stopPatterns [patkey ]; ok {
899+ if patkey == "" {
900+ trip .StopPatternID .SetInt (len (stopPatterns ))
901+ stopPatterns [trip .TripID .Val ] = trip .StopPatternID .Int () // Use trip ID as unique key
902+ } else if pat , ok := stopPatterns [patkey ]; ok {
899903 trip .StopPatternID .SetInt (pat )
900904 } else {
901905 trip .StopPatternID .SetInt (len (stopPatterns ))
@@ -909,8 +913,7 @@ func (copier *Copier) copyTripsAndStopTimes() error {
909913 trip .ShapeID .Set (shapeid )
910914 } else {
911915 if shapeid , err := copier .createMissingShape (fmt .Sprintf ("generated-%d-%d" , trip .StopPatternID .Val , time .Now ().Unix ()), trip .StopTimes ); err != nil {
912- copier .log .Error ().Err (err ).Str ("filename" , "trips.txt" ).Str ("source_id" , trip .EntityID ()).Msg ("failed to create shape" )
913- trip .AddWarning (err )
916+ copier .log .Debug ().Err (err ).Str ("filename" , "trips.txt" ).Str ("source_id" , trip .EntityID ()).Msg ("skipping shape generation" )
914917 } else {
915918 // Set ShapeID
916919 stopPatternShapeIDs [trip .StopPatternID .Int ()] = shapeid
@@ -929,8 +932,12 @@ func (copier *Copier) copyTripsAndStopTimes() error {
929932 }
930933
931934 // Set JourneyPattern
935+ // Empty key means flex trip - don't deduplicate
932936 jkey := copier .options .JourneyPatternKey (trip )
933- if jpat , ok := journeyPatterns [jkey ]; ok {
937+ if jkey == "" {
938+ trip .JourneyPatternID .Set (trip .TripID .Val )
939+ trip .JourneyPatternOffset .Set (0 )
940+ } else if jpat , ok := journeyPatterns [jkey ]; ok {
934941 trip .JourneyPatternID .Set (jpat .key )
935942 trip .JourneyPatternOffset .SetInt (trip .StopTimes [0 ].ArrivalTime .Int () - jpat .firstArrival )
936943 tripOffsets [trip .TripID .Val ] = trip .JourneyPatternOffset .Int () // do not write stop times for this trip
@@ -1023,11 +1030,16 @@ func (copier *Copier) logCount(ent tt.Entity) {
10231030}
10241031
10251032func (copier * Copier ) createMissingShape (shapeID string , stoptimes []gtfs.StopTime ) (string , error ) {
1026- stopids := []string {}
1033+ // Only create shapes when ALL stop_times have stop_id set
1034+ // Fallback shape is undefined for location/location_group based stops
1035+ if ! gtfs .CheckFlexStopTimes (stoptimes ).CanUseStopBasedGeometry () {
1036+ return "" , errors .New ("cannot create shape: not all stop_times have stop_id (trip may use flex locations)" )
1037+ }
1038+ if len (stoptimes ) == 0 {
1039+ return "" , errors .New ("cannot create shape: no stop_times" )
1040+ }
1041+ stopids := make ([]string , 0 , len (stoptimes ))
10271042 for _ , st := range stoptimes {
1028- if ! st .StopID .Valid {
1029- continue
1030- }
10311043 stopids = append (stopids , st .StopID .Val )
10321044 }
10331045 line , dists , err := copier .geomCache .MakeShape (stopids ... )
0 commit comments