From 25f623204d167445e61d7e52a1e68d2a7a68a408 Mon Sep 17 00:00:00 2001 From: ansons Date: Wed, 9 Oct 2024 20:28:06 -0400 Subject: [PATCH] Add network config option to save GTFS shapes Fixes #751 --- .../analyst/cluster/TransportNetworkConfig.java | 5 +++++ .../com/conveyal/r5/transit/TransitLayer.java | 16 +++++++++++++--- .../conveyal/r5/transit/TransportNetwork.java | 2 +- .../r5/transit/TransportNetworkCache.java | 2 +- .../r5/transit/FrequencyRandomOffsetsTest.java | 4 ++-- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/conveyal/r5/analyst/cluster/TransportNetworkConfig.java b/src/main/java/com/conveyal/r5/analyst/cluster/TransportNetworkConfig.java index 387742634..6a5556b50 100644 --- a/src/main/java/com/conveyal/r5/analyst/cluster/TransportNetworkConfig.java +++ b/src/main/java/com/conveyal/r5/analyst/cluster/TransportNetworkConfig.java @@ -57,4 +57,9 @@ public class TransportNetworkConfig { */ public String traversalPermissionLabeler; + /** Whether to save detailed trip shapes from GTFS (e.g., for Conveyal Taui sites or the Network Viewer). If false, + * straight line segments between stops will be used in visualizations. + */ + public boolean saveShapes; + } diff --git a/src/main/java/com/conveyal/r5/transit/TransitLayer.java b/src/main/java/com/conveyal/r5/transit/TransitLayer.java index f978d5a5e..0af49bc75 100644 --- a/src/main/java/com/conveyal/r5/transit/TransitLayer.java +++ b/src/main/java/com/conveyal/r5/transit/TransitLayer.java @@ -10,6 +10,7 @@ import com.conveyal.gtfs.model.Stop; import com.conveyal.gtfs.model.StopTime; import com.conveyal.gtfs.model.Trip; +import com.conveyal.r5.analyst.cluster.TransportNetworkConfig; import com.conveyal.r5.api.util.TransitModes; import com.conveyal.r5.common.GeometryUtils; import com.conveyal.r5.streets.EdgeStore; @@ -66,8 +67,6 @@ public class TransitLayer implements Serializable, Cloneable { /** Maximum distance to record in distance tables, in meters. */ public static final int WALK_DISTANCE_LIMIT_METERS = 2000; - public static final boolean SAVE_SHAPES = false; - /** * Distance limit for transfers, meters. Set to 1km which is slightly above OTP's 600m (which was specified as * 1 m/s with 600s max time, which is actually somewhat less than 600m due to extra costs due to steps etc. @@ -166,6 +165,11 @@ public class TransitLayer implements Serializable, Cloneable { public Map fares; + /** Whether to save detailed trip shapes from GTFS (e.g., for Conveyal Taui sites). Unless the default false + * value is overwritten by a transportNetworkConfig file, straight line segments between stops will be used in + * visualiations.*/ + public boolean saveShapes = false; + /** Map from feed ID to feed CRC32 to ensure that we can't apply scenarios to the wrong feeds */ public Map feedChecksums = new HashMap<>(); @@ -179,6 +183,12 @@ public class TransitLayer implements Serializable, Cloneable { */ public String scenarioId; + public TransitLayer (TransportNetworkConfig config) { + if (config != null) { + saveShapes = config.saveShapes; + } + } + /** * Load a GTFS feed with full load level. The feed is not closed after being loaded. * TODO eliminate "load levels" @@ -307,7 +317,7 @@ public void loadFromGtfs (GTFSFeed gtfs, LoadLevel level) throws DuplicateFeedEx tripPattern.routeIndex = routeIndexForRoute.get(trip.route_id); - if (trip.shape_id != null && SAVE_SHAPES) { + if (trip.shape_id != null && saveShapes) { Shape shape = gtfs.getShape(trip.shape_id); if (shape == null) LOG.warn("Shape {} for trip {} was missing", trip.shape_id, trip.trip_id); else { diff --git a/src/main/java/com/conveyal/r5/transit/TransportNetwork.java b/src/main/java/com/conveyal/r5/transit/TransportNetwork.java index 4d351eedf..7429d0545 100644 --- a/src/main/java/com/conveyal/r5/transit/TransportNetwork.java +++ b/src/main/java/com/conveyal/r5/transit/TransportNetwork.java @@ -166,7 +166,7 @@ public static TransportNetwork fromInputs (OSM osm, Stream gtfsFeeds, streetLayer.indexStreets(); // Load transit data - TransitLayer transitLayer = new TransitLayer(); + TransitLayer transitLayer = new TransitLayer(config); gtfsFeeds.forEach(gtfsFeed -> { transitLayer.loadFromGtfs(gtfsFeed); // Is there a reason we can't push this close call down into the loader method? Maybe exception handling? diff --git a/src/main/java/com/conveyal/r5/transit/TransportNetworkCache.java b/src/main/java/com/conveyal/r5/transit/TransportNetworkCache.java index c67fe9d24..2541e939f 100644 --- a/src/main/java/com/conveyal/r5/transit/TransportNetworkCache.java +++ b/src/main/java/com/conveyal/r5/transit/TransportNetworkCache.java @@ -254,7 +254,7 @@ private TransportNetwork buildNetworkFromConfig (TransportNetworkConfig config) network.streetLayer.parentNetwork = network; network.streetLayer.indexStreets(); - network.transitLayer = new TransitLayer(); + network.transitLayer = new TransitLayer(config); config.gtfsIds.stream() .map(gtfsCache::get) diff --git a/src/test/java/com/conveyal/r5/transit/FrequencyRandomOffsetsTest.java b/src/test/java/com/conveyal/r5/transit/FrequencyRandomOffsetsTest.java index f0fd04763..b14b10558 100644 --- a/src/test/java/com/conveyal/r5/transit/FrequencyRandomOffsetsTest.java +++ b/src/test/java/com/conveyal/r5/transit/FrequencyRandomOffsetsTest.java @@ -19,7 +19,7 @@ public class FrequencyRandomOffsetsTest { @Test public void testPhasing () { // make a fake transit layer - TransitLayer layer = new TransitLayer(); + TransitLayer layer = new TransitLayer(null); layer.hasFrequencies = true; layer.hasSchedules = false; @@ -86,7 +86,7 @@ public void testPhasing () { @Test public void testPhasingAtLastStop () { // make a fake transit layer - TransitLayer layer = new TransitLayer(); + TransitLayer layer = new TransitLayer(null); layer.hasFrequencies = true; layer.hasSchedules = false;