Skip to content

Commit

Permalink
CropGTFS: remove taxi modes and transfers
Browse files Browse the repository at this point in the history
also added polygon for Stockholm, Sweden
  • Loading branch information
abyrd committed Apr 5, 2024
1 parent 953757c commit 591048f
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 13 deletions.
67 changes: 55 additions & 12 deletions src/main/java/com/conveyal/gtfs/CropGTFS.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.conveyal.gtfs;

import com.conveyal.gtfs.model.Route;
import com.conveyal.gtfs.model.Stop;
import com.conveyal.gtfs.model.StopTime;
import com.conveyal.gtfs.model.Transfer;
Expand All @@ -18,30 +19,33 @@
import java.util.Set;

/**
* Remove all stops outside the bounding box,
* then remove all stop_times outside the bounding box,
* recording all trips with two or more stop_times inside the bounding box.
* Then remove all trips with no stoptimes or one single stoptime,
* then remove all transfers whose stops have been removed.
*
* Note that this does not crop the GTFS shapes, only the stops and stoptimes.
* Therefore in some tools like Transport Analyst, the data set will appear to extend beyond the bounding box
* because the entire shapes are drawn.
* Remove all stops outside the bounding box, then remove all stop_times outside the bounding box, recording all
* trips with two or more stop_times inside the bounding box. Then remove all trips with no stoptimes or one single
* stoptime, and remove all transfers whose stops have been removed.
* Also removes all routes with route_types that we don't support (TPEG >= 1500).
* Note that this does not crop the GTFS shapes, only the stops and stoptimes. Therefore, in tools like the R5 web UI,
* the data set will appear to extend beyond the bounding box because the entire shapes are drawn.
*/
public class CropGTFS {

// Logger is not super useful because as a library, gtfs-lib has no logger implementation defined by default.
private static final Logger LOG = LoggerFactory.getLogger(CropGTFS.class);

private static final String inputFile = "/Users/abyrd/test-est/gtfs_fr-cha_pourOAD.zip";
private static final String outputFile = ""; //"/Users/abyrd/geodata/nl/NL-2016-08-23-noplatforms-noshapes.gtfs.zip";
private static final String inputFile = "/Users/abyrd/data/stockholm/sweden.gtfs.zip";
private static final String outputFile = "/Users/abyrd/data/stockholm/stockholm-filtered.gtfs.zip";

// Replace all stops with their parent stations to simplify trip patterns.
private static final boolean MERGE_STATIONS = true;

// Remove all shapes from the GTFS to make it simpler to render in a web UI
private static final boolean REMOVE_SHAPES = true;

// Remove all routes with taxi and car modes, as well as trips and stoptimes that reference them transitively.
private static final boolean REMOVE_UNSUPPORTED_MODES = true;

// Remove all transfers before writing out.
private static final boolean REMOVE_TRANSFERS = true;

public static void main (String[] args) {

GTFSFeed feed = GTFSFeed.writableTempFileFromGtfs(inputFile);
Expand All @@ -52,7 +56,43 @@ public static void main (String[] args) {
Set<String> retainedTripIds = new HashSet<>();

// The geometry within which we will keep all stops
Geometry bounds = Geometries.getNetherlandsWithoutTexel();
Geometry bounds = Geometries.getStockholm();

if (REMOVE_UNSUPPORTED_MODES) {
System.out.println("Removing routes with unsupported route_type (mode of transport)...");
Set<String> routeIdsRemoved = new HashSet<>();
for (Iterator<Route> routeIterator = feed.routes.values().iterator(); routeIterator.hasNext(); ) {
Route route = routeIterator.next();
if (route.route_type >= 1500) {
routeIterator.remove();
routeIdsRemoved.add(route.route_id);
}
}
Set<String> tripIdsRemoved = new HashSet<>();
for (Iterator<Trip> tripIterator = feed.trips.values().iterator(); tripIterator.hasNext(); ) {
Trip trip = tripIterator.next();
if (routeIdsRemoved.contains(trip.route_id)) {
tripIterator.remove();
tripIdsRemoved.add(trip.trip_id);
}
}
int nStopTimesRemoved = 0;
for (Iterator<StopTime> it = feed.stop_times.values().iterator(); it.hasNext(); ) {
StopTime st = it.next();
if (tripIdsRemoved.contains(st.trip_id)) {
it.remove();
nStopTimesRemoved += 1;
}
}
System.out.println("Number of routes removed: " + routeIdsRemoved.size());
System.out.println("Number of trips removed: " + tripIdsRemoved.size());
System.out.println("Number of stop_times removed: " + nStopTimesRemoved);
}

if (REMOVE_TRANSFERS) {
feed.transfers.clear();
System.out.println("Removed all transfers.");
}

System.out.println("Removing stops outside bounding box...");
Map<String, String> stopIdReplacements = new HashMap<>(); // Used when collapsing stops into stations.
Expand All @@ -75,6 +115,7 @@ public static void main (String[] args) {
}

if (MERGE_STATIONS) {
int nUpdated = 0;
System.out.println("Replacing stop_ids in stop_times with those of their parent stations...");
for (Fun.Tuple2 key : feed.stop_times.keySet()) {
StopTime stopTime = feed.stop_times.get(key);
Expand All @@ -83,8 +124,10 @@ public static void main (String[] args) {
// Entry.setValue is an unsupported operation in MapDB, just re-put the StopTime.
stopTime.stop_id = replacementStopId;
feed.stop_times.put(key, stopTime);
nUpdated += 1;
}
}
System.out.println("Number of stop_times updated: " + nUpdated);
}

if (REMOVE_SHAPES) {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/com/conveyal/gtfs/Geometries.java
Original file line number Diff line number Diff line change
Expand Up @@ -508,4 +508,8 @@ public static Geometry getZuidHolland() {
return geometryFactory.toGeometry(new Envelope(4.002074, 4.98848, 51.696796, 52.278661));
}

public static Geometry getStockholm() {
// return geometryFactory.toGeometry(new Envelope(16.96617,19.42143, 58.59599,60.49487));
return geometryFactory.toGeometry(new Envelope(17.21558,19.23706,58.79098,60.17157));
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/conveyal/r5/transit/TransitLayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ public static TransitModes getTransitModes(int routeType) {
return TransitModes.FERRY;
} else if (routeType >= 1300 && routeType < 1400) { //Telecabin Service
return TransitModes.GONDOLA;
} else if (routeType >= 1400 && routeType < 1500) { //Funicalar Service
} else if (routeType >= 1400 && routeType < 1500) { //Funicular Service
return TransitModes.FUNICULAR;
} else if (routeType >= 1500 && routeType < 1600) { //Taxi Service
throw new IllegalArgumentException("Taxi route_type code not supported: " + routeType);
Expand Down

0 comments on commit 591048f

Please sign in to comment.