Skip to content

Commit bcdadbe

Browse files
Fix tests
1 parent 153d9ae commit bcdadbe

File tree

16 files changed

+552
-700
lines changed

16 files changed

+552
-700
lines changed

application/src/ext-test/java/org/opentripplanner/ext/flex/trip/FlexTripsMapperTest.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.opentripplanner.graph_builder.issue.api.DataImportIssueStore.NOOP;
66

77
import java.util.List;
8+
import java.util.stream.Stream;
89
import org.junit.jupiter.api.Test;
910
import org.opentripplanner.ext.flex.FlexStopTimesForTest;
1011
import org.opentripplanner.ext.flex.FlexTripsMapper;
@@ -19,8 +20,8 @@ class FlexTripsMapperTest {
1920
@Test
2021
void defaultTimePenalty() {
2122
var builder = new OtpTransitServiceBuilder(SiteRepository.of().build(), NOOP);
22-
var stopTimes = List.of(stopTime(0), stopTime(1));
23-
//builder.getStopTimesSortedByTrip().addAll(stopTimes);
23+
var stopTimes = Stream.of(stopTime(0), stopTime(1));
24+
builder.getStopTimesSortedByTrip().addAll(stopTimes);
2425
var trips = FlexTripsMapper.createFlexTrips(builder, NOOP);
2526
assertEquals("[UnscheduledTrip{F:flex-1}]", trips.toString());
2627
var unscheduled = (UnscheduledTrip) trips.getFirst();
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
booking_rule_id,booking_type,prior_notice_duration_min,prior_notice_duration_max,prior_notice_start_day,prior_notice_start_time,prior_notice_last_day,prior_notice_last_time,prior_notice_service_id,message,pickup_message,drop_off_message,phone_number,info_url,booking_url
2-
booking_route_17102,0,,,,,,,,"The Downtowner provides free door-to-door transportation within the downtown area of Aspen. To schedule a ride, use the Downtowner Android/iOS mobile app. You may also request a ride by calling (877) 230-6045.",,,877-230-6045,https://www.cityofaspen.com/270/Downtowner,
1+
booking_rule_id,booking_type,prior_notice_duration_min,prior_notice_duration_max,prior_notice_start_day,prior_notice_start_time,prior_notice_last_day,prior_notice_last_time,prior_notice_service_id,message,pickup_message,drop_off_message,phone_number,info_url,booking_url
2+
booking_route_17102,1,120,1440,,,,,,Call reservationist to schedule.,,,(770) 528-1053,,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
trip_id,arrival_time,departure_time,stop_id,stop_sequence,stop_headsign,pickup_type,drop_off_type,shape_dist_traveled,timepoint,continuous_pickup,continuous_drop_off,pickup_booking_rule_id,drop_off_booking_rule_id,start_pickup_drop_off_window,end_pickup_drop_off_window,mean_duration_factor,mean_duration_offset,safe_duration_factor,safe_duration_offset
1+
trip_id,arrival_time,departure_time,location_id,stop_sequence,stop_headsign,pickup_type,drop_off_type,shape_dist_traveled,timepoint,continuous_pickup,continuous_drop_off,pickup_booking_rule_id,drop_off_booking_rule_id,start_pickup_drop_off_window,end_pickup_drop_off_window,mean_duration_factor,mean_duration_offset,safe_duration_factor,safe_duration_offset
22
t_1289257_b_28352_tn_0,,,area_294,1,,2,2,0,0,1,1,booking_route_17102,booking_route_17102,08:00:00,23:00:00,1,9.00,1,20.00
33
t_1289262_b_29084_tn_0,,,area_294,1,,2,2,0,0,1,1,booking_route_17102,booking_route_17102,11:00:00,23:00:00,1,9.00,1,20.00

application/src/ext-test/resources/org/opentripplanner/ext/flex/cobblinc-scheduled-deviated-flex.gtfs/stop_times.txt

Lines changed: 289 additions & 289 deletions
Large diffs are not rendered by default.

application/src/main/java/org/opentripplanner/gtfs/mapping/GTFSToOtpTransitServiceMapper.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,7 @@ public GTFSToOtpTransitServiceMapper(
135135
directionMapper = new DirectionMapper(issueStore);
136136
tripMapper = new TripMapper(idFactory, routeMapper, directionMapper, translationHelper);
137137
bookingRuleMapper = new BookingRuleMapper(idFactory);
138-
stopTimeMapper = new StopTimeMapper(
139-
idFactory,
140-
stopMapper,
141-
tripMapper,
142-
bookingRuleMapper,
143-
translationHelper
144-
);
138+
stopTimeMapper = new StopTimeMapper(idFactory, builder, bookingRuleMapper, translationHelper);
145139
frequencyMapper = new FrequencyMapper(tripMapper);
146140
fareAttributeMapper = new FareAttributeMapper(idFactory);
147141
fareRuleMapper = new FareRuleMapper(routeMapper, fareAttributeMapper);
@@ -184,6 +178,7 @@ public void mapStopTripAndRouteDataIntoBuilder(GtfsRelationalDao data, CsvInputS
184178
builder.getTripsById().addAll(tripMapper.map(data.getAllTrips()));
185179

186180
builder.getPathways().addAll(pathwayMapper.map(data.getAllPathways()));
181+
data.getAllBookingRules().forEach(bookingRuleMapper::map);
187182
builder.getStopTimesSortedByTrip().addAll(stopTimeMapper.map(csvSource));
188183
builder.getFlexTimePenalty().putAll(tripMapper.flexSafeTimePenalties());
189184

application/src/main/java/org/opentripplanner/gtfs/mapping/PickDropMapper.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44

55
import javax.annotation.Nullable;
66
import org.opentripplanner.model.PickDrop;
7+
import org.opentripplanner.utils.lang.StringUtils;
78

89
public class PickDropMapper {
910

1011
public static PickDrop map(@Nullable String gtfsCode) {
11-
if (gtfsCode == null || gtfsCode.isBlank()) {
12+
if (StringUtils.hasNoValue(gtfsCode)) {
1213
return PickDrop.SCHEDULED;
1314
} else {
1415
return map(Integer.parseInt(gtfsCode));

application/src/main/java/org/opentripplanner/gtfs/mapping/StopMapper.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,6 @@ private RegularStop doMap(org.onebusaway.gtfs.model.Stop gtfsStop) {
101101
return builder.build();
102102
}
103103

104-
public SiteRepositoryBuilder siteRepositoryBuilder() {
105-
return siteRepositoryBuilder;
106-
}
107-
108104
private void assertLocationTypeIsStop(Stop gtfsStop) {
109105
if (gtfsStop.getLocationType() != Stop.LOCATION_TYPE_STOP) {
110106
throw new IllegalArgumentException(

application/src/main/java/org/opentripplanner/gtfs/mapping/StopTimeMapper.java

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -6,72 +6,65 @@
66
import java.util.Map;
77
import java.util.Objects;
88
import java.util.Optional;
9-
import java.util.stream.Collectors;
109
import java.util.stream.Stream;
1110
import javax.annotation.Nullable;
1211
import org.onebusaway.csv_entities.CsvInputSource;
13-
import org.onebusaway.csv_entities.schema.DefaultEntitySchemaFactory;
14-
import org.onebusaway.csv_entities.schema.EntitySchema;
12+
import org.opentripplanner.framework.i18n.I18NString;
1513
import org.opentripplanner.model.StopTime;
16-
import org.opentripplanner.transit.model.framework.AbstractTransitEntity;
14+
import org.opentripplanner.model.impl.OtpTransitServiceBuilder;
15+
import org.opentripplanner.transit.model.framework.EntityById;
1716
import org.opentripplanner.transit.model.framework.FeedScopedId;
1817
import org.opentripplanner.transit.model.timetable.Trip;
19-
import org.opentripplanner.transit.service.SiteRepositoryBuilder;
2018
import org.opentripplanner.utils.lang.StringUtils;
2119

2220
/**
2321
* Responsible for mapping GTFS StopTime into the OTP Transit model.
2422
*/
2523
class StopTimeMapper {
2624

27-
public static final EntitySchema SCHEMA = new DefaultEntitySchemaFactory()
28-
.getSchema(org.onebusaway.gtfs.model.StopTime.class);
29-
public static final String TIMEPOINT = "timepoint";
30-
public static final String SHAPE_DIST_TRAVELED = "shape_dist_traveled";
31-
public static final String STOP_SEQUENCE = "stop_sequence";
32-
public static final String DEPARTURE_TIME = "departure_time";
33-
public static final String ARRIVAL_TIME = "arrival_time";
34-
public static final String PICKUP_TYPE = "pickup_type";
35-
public static final String DROP_OFF_TYPE = "drop_off_type";
36-
public static final String PICKUP_BOOKING_RULE_ID = "pickup_booking_rule_id";
37-
public static final String DROP_OFF_BOOKING_RULE_ID = "drop_off_booking_rule_id";
38-
public static final String START_PICKUP_DROP_OFF_WINDOW = "start_pickup_drop_off_window";
39-
public static final String END_PICKUP_DROP_OFF_WINDOW = "end_pickup_drop_off_window";
40-
public static final String CONTINUOUS_PICKUP = "continuous_pickup";
41-
public static final String CONTINUOUS_DROP_OFF = "continuous_drop_off";
25+
private static final String TIMEPOINT = "timepoint";
26+
private static final String SHAPE_DIST_TRAVELED = "shape_dist_traveled";
27+
private static final String STOP_SEQUENCE = "stop_sequence";
28+
private static final String DEPARTURE_TIME = "departure_time";
29+
private static final String ARRIVAL_TIME = "arrival_time";
30+
private static final String PICKUP_TYPE = "pickup_type";
31+
private static final String DROP_OFF_TYPE = "drop_off_type";
32+
private static final String PICKUP_BOOKING_RULE_ID = "pickup_booking_rule_id";
33+
private static final String DROP_OFF_BOOKING_RULE_ID = "drop_off_booking_rule_id";
34+
private static final String START_PICKUP_DROP_OFF_WINDOW = "start_pickup_drop_off_window";
35+
private static final String END_PICKUP_DROP_OFF_WINDOW = "end_pickup_drop_off_window";
36+
private static final String CONTINUOUS_PICKUP = "continuous_pickup";
37+
private static final String CONTINUOUS_DROP_OFF = "continuous_drop_off";
38+
private static final String STOP_ID = "stop_id";
39+
private static final String LOCATION_ID = "location_id";
40+
private static final String STOP_GROUP_ID = "stop_group_id";
41+
private static final String STOP_HEADSIGN = "stop_headsign";
42+
private static final String FILE = "stops_times.txt";
4243
private final IdFactory idFactory;
4344

44-
private final TripMapper tripMapper;
45-
4645
private final BookingRuleMapper bookingRuleMapper;
4746
private final TranslationHelper translationHelper;
48-
private final SiteRepositoryBuilder siteRepositoryBuilder;
47+
private final OtpTransitServiceBuilder builder;
4948

5049
StopTimeMapper(
5150
IdFactory idFactory,
52-
StopMapper stopMapper,
53-
TripMapper tripMapper,
51+
OtpTransitServiceBuilder builder,
5452
BookingRuleMapper bookingRuleMapper,
5553
TranslationHelper translationHelper
5654
) {
5755
this.idFactory = idFactory;
58-
this.siteRepositoryBuilder = stopMapper.siteRepositoryBuilder();
59-
this.tripMapper = tripMapper;
56+
this.builder = builder;
6057
this.bookingRuleMapper = bookingRuleMapper;
6158
this.translationHelper = translationHelper;
6259
}
6360

6461
Stream<StopTime> map(CsvInputSource inputSource) throws IOException {
65-
var trips = tripMapper
66-
.getMappedTrips()
67-
.stream()
68-
.collect(Collectors.toMap(AbstractTransitEntity::getId, t -> t));
6962
return new StreamingCsvReader(inputSource)
70-
.rows(SCHEMA.getFilename())
71-
.map(st -> this.doMap(new StopTimeRow(st, idFactory), trips));
63+
.rows(FILE)
64+
.map(st -> this.doMap(new StopTimeRow(st, idFactory), builder.getTripsById()));
7265
}
7366

74-
private StopTime doMap(StopTimeRow row, Map<FeedScopedId, Trip> trips) {
67+
private StopTime doMap(StopTimeRow row, EntityById<Trip> trips) {
7568
StopTime lhs = new StopTime();
7669

7770
var tripId = idFactory.createId(row.requiredString("trip_id"), "stop time's trip");
@@ -81,23 +74,36 @@ private StopTime doMap(StopTimeRow row, Map<FeedScopedId, Trip> trips) {
8174
);
8275
lhs.setTrip(trip);
8376

84-
var stopId = row.string("stop_id");
85-
var stopLocationId = row.string("stop_location_id");
86-
var locationGroupId = row.string("stop_group_id");
77+
var stopId = row.string(STOP_ID);
78+
var stopLocationId = row.string(LOCATION_ID);
79+
var locationGroupId = row.string(STOP_GROUP_ID);
8780

81+
var siteRepositoryBuilder = builder.siteRepository();
8882
if (stopId != null) {
8983
var id = idFactory.createId(stopId, "stop_time's stop");
90-
lhs.setStop(Objects.requireNonNull(siteRepositoryBuilder.regularStopsById().get(id)));
84+
var stop = Objects.requireNonNull(
85+
siteRepositoryBuilder.regularStopsById().get(id),
86+
"Stop '%s' not found".formatted(stopId)
87+
);
88+
lhs.setStop(stop);
9189
} else if (stopLocationId != null) {
92-
var id = idFactory.createId(stopLocationId, "stop time's stop location");
93-
lhs.setStop(Objects.requireNonNull(siteRepositoryBuilder.areaStopById().get(id)));
90+
var id = idFactory.createId(stopLocationId, "stop time's location");
91+
var stop = Objects.requireNonNull(
92+
siteRepositoryBuilder.areaStopById().get(id),
93+
"Stop location '%s' not found".formatted(id)
94+
);
95+
lhs.setStop(stop);
9496
} else if (locationGroupId != null) {
9597
var id = idFactory.createId(locationGroupId, "stop time's location group");
9698
lhs.setStop(Objects.requireNonNull(siteRepositoryBuilder.groupStopById().get(id)));
99+
} else {
100+
throw new IllegalArgumentException(
101+
"Stop time must have either a %s, %s, or %s".formatted(STOP_ID, LOCATION_ID, STOP_GROUP_ID)
102+
);
97103
}
98104

99-
lhs.setArrivalTime(row.requiredTime(ARRIVAL_TIME));
100-
lhs.setDepartureTime(row.requiredTime(DEPARTURE_TIME));
105+
lhs.setArrivalTime(row.time(ARRIVAL_TIME));
106+
lhs.setDepartureTime(row.time(DEPARTURE_TIME));
101107
lhs.setStopSequence(row.integer(STOP_SEQUENCE));
102108

103109
lhs.setTimepoint(row.integer(TIMEPOINT));
@@ -115,15 +121,26 @@ private StopTime doMap(StopTimeRow row, Map<FeedScopedId, Trip> trips) {
115121
PickDropMapper.mapFlexContinuousPickDrop(row.integer(CONTINUOUS_DROP_OFF))
116122
);
117123

124+
row.optionalString(STOP_HEADSIGN).ifPresent(hs -> lhs.setStopHeadsign(I18NString.of(hs)));
118125
row
119126
.id(PICKUP_BOOKING_RULE_ID)
120127
.ifPresent(id ->
121-
lhs.setPickupBookingInfo(Objects.requireNonNull(bookingRuleMapper.findBookingRule(id)))
128+
lhs.setPickupBookingInfo(
129+
Objects.requireNonNull(
130+
bookingRuleMapper.findBookingRule(id),
131+
"Pickup booking rule '%s' not found".formatted(id)
132+
)
133+
)
122134
);
123135
row
124136
.id(DROP_OFF_BOOKING_RULE_ID)
125137
.ifPresent(id ->
126-
lhs.setPickupBookingInfo(Objects.requireNonNull(bookingRuleMapper.findBookingRule(id)))
138+
lhs.setPickupBookingInfo(
139+
Objects.requireNonNull(
140+
bookingRuleMapper.findBookingRule(id),
141+
"Drop off booking rule '%s' not found".formatted(id)
142+
)
143+
)
127144
);
128145

129146
return lhs;
@@ -135,7 +152,7 @@ public String requiredString(String field) {
135152
return row.get(field);
136153
} else {
137154
throw new IllegalArgumentException(
138-
"Missing required field '%s' in stop time CSV row".formatted(field)
155+
"Missing required field '%s' in stop time CSV row: %s".formatted(field, row)
139156
);
140157
}
141158
}
@@ -159,16 +176,6 @@ public double getDouble(String field) {
159176
}
160177
}
161178

162-
public int requiredTime(String field) {
163-
var value = row.get(field);
164-
if (value != null) {
165-
return getStringAsSeconds(value);
166-
} else {
167-
throw new IllegalArgumentException(
168-
"Missing required field '%s' in stop_times.txt".formatted(field)
169-
);
170-
}
171-
}
172179
public int time(String field) {
173180
var value = row.get(field);
174181
if (value != null) {
@@ -181,5 +188,9 @@ public int time(String field) {
181188
public Optional<FeedScopedId> id(String field) {
182189
return Optional.ofNullable(row.get(field)).map(s -> idFactory.createId(s, field));
183190
}
191+
192+
public Optional<String> optionalString(String stopHeadsign) {
193+
return Optional.ofNullable(row.get(stopHeadsign)).filter(StringUtils::hasValue);
194+
}
184195
}
185196
}

application/src/main/java/org/opentripplanner/gtfs/mapping/StreamingCsvReader.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,35 +37,39 @@ public Stream<Map<String, String>> rows(String fileName) throws IOException {
3737
}
3838

3939
private Stream<Map<String, String>> stream(String fileName) throws IOException {
40-
try (var source = inputSource.getResource(fileName)) {
41-
var streamReader = new InputStreamReader(source);
42-
BufferedReader lineReader = new BufferedReader(streamReader);
40+
var source = inputSource.getResource(fileName);
41+
var streamReader = new InputStreamReader(source);
42+
BufferedReader lineReader = new BufferedReader(streamReader);
4343

44-
// Skip the initial UTF BOM, if present
45-
lineReader.mark(1);
46-
int c = lineReader.read();
44+
// Skip the initial UTF BOM, if present
45+
lineReader.mark(1);
46+
int c = lineReader.read();
4747

48-
if (c != 0xFEFF) {
49-
lineReader.reset();
50-
}
51-
var fields = DelimitedTextParser.parse(lineReader.readLine()).stream().toList();
48+
if (c != 0xFEFF) {
49+
lineReader.reset();
50+
}
51+
var fields = DelimitedTextParser.parse(lineReader.readLine()).stream().toList();
5252

53-
return lineReader
54-
.lines()
55-
.map(line -> {
56-
var elements = DelimitedTextParser.parse(line);
57-
var values = new HashMap<String, String>(fields.size());
53+
return lineReader
54+
.lines()
55+
.filter(StringUtils::hasValue)
56+
.map(line -> {
57+
var elements = DelimitedTextParser.parse(line);
58+
var values = new HashMap<String, String>(fields.size());
5859

59-
for (int i = 0; i < fields.size(); i++) {
60-
var fieldName = fields.get(i);
60+
for (int i = 0; i < fields.size() && i < elements.size(); i++) {
61+
var fieldName = fields.get(i);
62+
try {
6163
var value = elements.get(i);
6264
if (StringUtils.hasValue(value)) {
6365
values.put(fieldName, value);
6466
}
67+
} catch (Exception e) {
68+
System.out.println(elements);
6569
}
70+
}
6671

67-
return values;
68-
});
69-
}
72+
return values;
73+
});
7074
}
7175
}

application/src/test/java/org/opentripplanner/gtfs/GtfsContextBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public static GtfsContextBuilder contextBuilder(@Nullable String defaultFeedId,
5555
false,
5656
StopTransferPriority.ALLOWED
5757
);
58-
//mapper.mapStopTripAndRouteDataIntoBuilder(gtfsImport.getDao());
58+
mapper.mapStopTripAndRouteDataIntoBuilder(gtfsImport.getDao(), gtfsImport.inputSource());
5959
mapper.mapAndAddTransfersToBuilder(gtfsImport.getDao());
6060
return new GtfsContextBuilder(feedId, transitBuilder).withDataImportIssueStore(
6161
DataImportIssueStore.NOOP

0 commit comments

Comments
 (0)