@@ -60,7 +60,9 @@ public class FeedMetadata {
60
60
new Pair <>("Zone-Based Fares" , GtfsArea .FILENAME ),
61
61
new Pair <>("Transfer Fares" , GtfsFareTransferRule .FILENAME ),
62
62
new Pair <>("Time-Based Fares" , GtfsTimeframe .FILENAME ),
63
- new Pair <>("Levels" , GtfsLevel .FILENAME ));
63
+ new Pair <>("Levels" , GtfsLevel .FILENAME ),
64
+ new Pair <>("Booking Rules" , GtfsBookingRules .FILENAME ),
65
+ new Pair <>("Fixed-Stops Demand Responsive Transit" , GtfsLocationGroups .FILENAME ));
64
66
65
67
protected FeedMetadata () {}
66
68
@@ -156,6 +158,60 @@ private void loadSpecFeaturesBasedOnFieldPresence(GtfsFeedContainer feedContaine
156
158
loadPathwayExtraFeature (feedContainer );
157
159
loadRouteBasedFaresFeature (feedContainer );
158
160
loadContinuousStopsFeature (feedContainer );
161
+ loadZoneBasedDemandResponsiveTransitFeature (feedContainer );
162
+ loadDeviatedFixedRouteFeature (feedContainer );
163
+ }
164
+
165
+ private void loadDeviatedFixedRouteFeature (GtfsFeedContainer feedContainer ) {
166
+ specFeatures .put ("Deviated Fixed Route" , hasAtLeastOneTripWithAllFields (feedContainer ));
167
+ }
168
+
169
+ private boolean hasAtLeastOneTripWithAllFields (GtfsFeedContainer feedContainer ) {
170
+ Optional <GtfsTableContainer <?>> optionalStopTimeTable =
171
+ feedContainer .getTableForFilename (GtfsStopTime .FILENAME );
172
+ if (optionalStopTimeTable .isPresent ()) {
173
+ for (GtfsEntity entity : optionalStopTimeTable .get ().getEntities ()) {
174
+ if (entity instanceof GtfsStopTime ) {
175
+ GtfsStopTime stopTime = (GtfsStopTime ) entity ;
176
+ return stopTime .hasTripId ()
177
+ && stopTime .tripId () != null
178
+ && stopTime .hasLocationId ()
179
+ && stopTime .locationId () != null
180
+ && stopTime .hasStopId ()
181
+ && stopTime .stopId () != null
182
+ && stopTime .hasArrivalTime ()
183
+ && stopTime .arrivalTime () != null
184
+ && stopTime .hasDepartureTime ()
185
+ && stopTime .departureTime () != null ;
186
+ }
187
+ }
188
+ }
189
+ return false ;
190
+ }
191
+
192
+ private void loadZoneBasedDemandResponsiveTransitFeature (GtfsFeedContainer feedContainer ) {
193
+ specFeatures .put (
194
+ "Zone-Based Demand Responsive Transit" , hasAtLeastOneTripWithOnlyLocationId (feedContainer ));
195
+ }
196
+
197
+ private boolean hasAtLeastOneTripWithOnlyLocationId (GtfsFeedContainer feedContainer ) {
198
+ Optional <GtfsTableContainer <?>> optionalStopTimeTable =
199
+ feedContainer .getTableForFilename (GtfsStopTime .FILENAME );
200
+ if (optionalStopTimeTable .isPresent ()) {
201
+ for (GtfsEntity entity : optionalStopTimeTable .get ().getEntities ()) {
202
+ if (entity instanceof GtfsStopTime ) {
203
+ GtfsStopTime stopTime = (GtfsStopTime ) entity ;
204
+ if (stopTime .hasTripId ()
205
+ && stopTime .tripId () != null
206
+ && stopTime .hasLocationId ()
207
+ && stopTime .locationId () != null
208
+ && (!stopTime .hasStopId () || stopTime .stopId () == null )) {
209
+ return true ;
210
+ }
211
+ }
212
+ }
213
+ }
214
+ return false ;
159
215
}
160
216
161
217
private void loadContinuousStopsFeature (GtfsFeedContainer feedContainer ) {
0 commit comments