Skip to content

Commit

Permalink
Skims calculator and melbourne update
Browse files Browse the repository at this point in the history
  • Loading branch information
CorinStaves committed May 14, 2024
1 parent 17d4829 commit d7d3491
Show file tree
Hide file tree
Showing 17 changed files with 583 additions and 171 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
package routing;
package ch.sbb.matsim;

import accessibility.LocationData;
import gis.GpkgReader;
import network.NetworkUtils2;
import org.matsim.api.core.v01.Id;
import org.matsim.core.router.costcalculators.OnlyTimeDependentTravelDisutility;
import resources.Properties;
import resources.Resources;
import routing.ActiveAttributes;
import routing.Bicycle;
import routing.TravelAttribute;
import routing.disutility.DistanceDisutility;
import routing.travelTime.WalkTravelTime;
import ch.sbb.matsim.analysis.calc.IndicatorCalculator;
import ch.sbb.matsim.analysis.data.IndicatorData;
import ch.sbb.matsim.analysis.io.IndicatorWriter;
import routing.disutility.JibeDisutility;
import ch.sbb.matsim.analysis.CalculateData;
import ch.sbb.matsim.analysis.calc.GeometryCalculator;
import ch.sbb.matsim.analysis.data.GeometryData;
import ch.sbb.matsim.analysis.io.GeometryWriter;
import org.apache.log4j.Logger;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.Node;
Expand All @@ -31,15 +34,14 @@
public class RunZoneRouter {

private final static Logger log = Logger.getLogger(RunZoneRouter.class);
private final static Integer SAMPLE_SIZE = 400;

public static void main(String[] args) throws IOException, FactoryException {

if(args.length < 4 | args.length == 5) {
throw new RuntimeException("Program requires at least 4 arguments: \n" +
"(0) Properties file \n" +
"(1) Zone coordinates file (.csv) \n" +
"(2) Output file path (.gpkg) \n" +
"(2) Output file path (.csv or .gpkg) \n" +
"(3) Mode (walk or bike) \n" +
"(4+) OPTIONAL: Names of zones to be used for routing");
}
Expand All @@ -49,38 +51,27 @@ public static void main(String[] args) throws IOException, FactoryException {
String outputFile = args[2];
String mode = args[3];

String edgesFilePath = Resources.instance.getString(Properties.NETWORK_LINKS);

// Read network
Network modeNetwork = NetworkUtils2.readModeSpecificNetwork(mode);

// Create zone-coord map and remove spaces
Map<String, Coord> zoneCoordMap;
zoneCoordMap = CalculateData.buildZoneCoordMap(zoneCoordinates);
// Create zone-node map and remove spaces
LocationData zones = new LocationData("zones",zoneCoordinates, GpkgReader.readRegionBoundary());
zones.estimateNetworkNodes(modeNetwork);
Map<String,Id<Node>> zoneNodeMap = zones.getNodeIdMap().entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue,Map.Entry::getKey));

// Determine set of zones to be used for routing
// Determine set of zones to be used for routing (subset if given as additional arguments)
Set<String> routingZones;
if (args.length == 4) {
if(SAMPLE_SIZE != null) {
log.info("Randomly sampling " + SAMPLE_SIZE + " of " + zoneCoordMap.size() + " zones.");
List<String> routingZonesList = new ArrayList<>(zoneCoordMap.keySet());
Collections.shuffle(routingZonesList);
routingZones = routingZonesList.stream().limit(SAMPLE_SIZE).collect(Collectors.toSet());
} else {
routingZones = zoneCoordMap.keySet();
}
routingZones = zoneNodeMap.keySet();
} else {
routingZones = Arrays.stream(args).skip(5).
map(s -> s.replaceAll("\\s+", "")).
collect(Collectors.toSet());
zoneCoordMap = zoneCoordMap.entrySet().stream().
zoneNodeMap = zoneNodeMap.entrySet().stream().
filter(map -> routingZones.contains(map.getKey().replaceAll("\\s+", ""))).
collect(Collectors.toMap(map -> map.getKey().replaceAll("\\s+", ""), Map.Entry::getValue));
}

// Create zone-node map
Map<String, Node> zoneNodeMap = CalculateData.buildZoneNodeMap(zoneCoordMap,modeNetwork,modeNetwork);

// CREATE VEHICLE & SET UP TRAVEL TIME
Vehicle veh;
TravelTime tt;
Expand Down Expand Up @@ -113,7 +104,7 @@ public static void main(String[] args) throws IOException, FactoryException {
}*/

// DEFINE ADDITIONAL ROUTE ATTRIBUTES TO INCLUDE IN GPKG (DOES NOT AFFECT ROUTING)
LinkedHashMap<String,TravelAttribute> attributes = ActiveAttributes.getJibe(mode,veh);
LinkedHashMap<String, TravelAttribute> attributes = ActiveAttributes.getJibe(mode,veh);

// OUTPUT RESULTS
if(outputFile.endsWith(".csv")) {
Expand All @@ -123,7 +114,7 @@ public static void main(String[] args) throws IOException, FactoryException {
for(Map.Entry<String,TravelDisutility> e : travelDisutilities.entrySet()) {
log.info("Calculating attributes for route " + e.getKey());
IndicatorData<String> indicatorData = IndicatorCalculator.calculate(modeNetwork,routingZones,routingZones,
zoneNodeMap,tt,e.getValue(),attributes, veh,14);
zoneNodeMap,tt,e.getValue(),attributes, veh);
indicators.put(e.getKey(),indicatorData);
}
IndicatorWriter.writeAsCsv(indicators,outputFile);
Expand All @@ -134,10 +125,10 @@ public static void main(String[] args) throws IOException, FactoryException {
for(Map.Entry<String,TravelDisutility> e : travelDisutilities.entrySet()) {
log.info("Calculating geometries for route " + e.getKey());
GeometryData<String> routeData = GeometryCalculator.calculate(modeNetwork,routingZones,routingZones,
zoneNodeMap,tt,e.getValue(),attributes,veh,14);
zoneNodeMap,tt,e.getValue(),attributes,veh);
geometries.put(e.getKey(),routeData);
}
GeometryWriter.writeGpkg(geometries,zoneNodeMap,outputFile);
GeometryWriter.writeGpkg(modeNetwork,geometries,zoneNodeMap,outputFile);
} else {
log.error("Unable to output results: please specify output file as .gpkg or .csv");
}
Expand Down
38 changes: 23 additions & 15 deletions src/main/java/ch/sbb/matsim/analysis/CalculateData.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.locationtech.jts.geom.Point;
import org.locationtech.jts.index.SpatialIndex;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
Expand All @@ -56,6 +57,8 @@
import org.matsim.pt.transitSchedule.api.TransitScheduleReader;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.referencing.FactoryException;
import resources.Properties;
import resources.Resources;
import routing.TravelAttribute;

/**
Expand All @@ -75,11 +78,10 @@ public class CalculateData {
private final static GeometryFactory GEOMETRY_FACTORY = new GeometryFactory();

private final String outputDirectory;
private final int numberOfThreads;
private Integer batchSize;
private Map<String, Coord> zoneCoordMap = null;

public CalculateData(String outputDirectory, int numberOfThreads, Integer batchSize) {
public CalculateData(String outputDirectory, Integer batchSize) {
this.outputDirectory = outputDirectory;
File outputDir = new File(outputDirectory);
if (!outputDir.exists()) {
Expand All @@ -94,7 +96,6 @@ public CalculateData(String outputDirectory, int numberOfThreads, Integer batchS
}
}

this.numberOfThreads = numberOfThreads;
this.batchSize = batchSize;
}

Expand All @@ -120,6 +121,13 @@ public final void loadSamplingPointsFromFile(String filename) throws IOException
}
}

public final void setZoneCoordMap(Map<Integer,Coord> m) {
this.zoneCoordMap = new LinkedHashMap<>();
for(Map.Entry<Integer,Coord> e : m.entrySet()) {
zoneCoordMap.put(e.getKey().toString(),e.getValue());
}
}

public final void calculateRouteIndicators(String networkFilename, Config config, TravelTime tt, TravelDisutility td,
String outputPrefix, TravelAttribute[] aggregatedAttributes,
String transportMode, Predicate<Link> xy2linksPredicate) throws IOException {
Expand All @@ -137,7 +145,7 @@ public final void calculateRouteIndicators(String networkFilename, Config config
final Network xy2linksNetwork = NetworkUtils2.extractXy2LinksNetwork(modeSpecificNetwork, xy2linksPredicate);

log.info("calculating zone-node map");
Map<String, Node> zoneNodeMap = buildZoneNodeMap(zoneCoordMap, xy2linksNetwork, modeSpecificNetwork);
Map<String, Id<Node>> zoneNodeMap = buildZoneNodeMap(zoneCoordMap, xy2linksNetwork, modeSpecificNetwork);

log.info("splitting into batches of size " + batchSize);

Expand All @@ -154,7 +162,7 @@ public final void calculateRouteIndicators(String networkFilename, Config config
log.info("INITIATING BATCH " + counter + " OF " + numberOfBatches);
long startTime = System.currentTimeMillis();
IndicatorData<String> netIndicators = IndicatorCalculator.calculate(
modeSpecificNetwork, origins, destinations, zoneNodeMap, tt, td, null,null, this.numberOfThreads);
modeSpecificNetwork, origins, destinations, zoneNodeMap, tt, td, null,null);
long endTime = System.currentTimeMillis();
log.info("Batch " + counter + " calculation time: " + (endTime - startTime));

Expand Down Expand Up @@ -185,7 +193,7 @@ public final void calculateRouteGeometries(String networkFilename,Config config,
final Network xy2linksNetwork = NetworkUtils2.extractXy2LinksNetwork(modeSpecificNetwork, xy2linksPredicate);

log.info("calculating zone-node map");
Map<String, Node> zoneNodeMap = buildZoneNodeMap(zoneCoordMap, xy2linksNetwork, modeSpecificNetwork);
Map<String, Id<Node>> zoneNodeMap = buildZoneNodeMap(zoneCoordMap, xy2linksNetwork, modeSpecificNetwork);

log.info("fixing origin zones");
Set<String> originZones;
Expand All @@ -208,25 +216,25 @@ public final void calculateRouteGeometries(String networkFilename,Config config,
log.info("INITIATING BATCH " + counter + " OF " + numberOfBatches);
long startTime = System.currentTimeMillis();
GeometryData<String> geometries = GeometryCalculator.calculate(
modeSpecificNetwork, origins, destinations, zoneNodeMap, tt, td, null,null, this.numberOfThreads);
modeSpecificNetwork, origins, destinations, zoneNodeMap, tt, td, null,null);
long endTime = System.currentTimeMillis();
log.info("Batch " + counter + " calculation time: " + (endTime - startTime));

startTime = System.currentTimeMillis();
GeometryWriter.writeGpkg(geometries, zoneNodeMap, outputFilePath);
GeometryWriter.writeGpkg(modeSpecificNetwork, geometries, zoneNodeMap, outputFilePath);
endTime = System.currentTimeMillis();
log.info("Batch " + counter + " writing time: " + (endTime - startTime));

// break; // break for debugging only
}
}

public final void calculatePtIndicators(String networkFilename, String transitScheduleFilename, double startTime, double endTime, Config config, String outputPrefix, BiPredicate<TransitLine, TransitRoute> trainDetector) throws IOException {
public final void calculatePtIndicators(String transitScheduleFilename, double startTime, double endTime, Config config, String outputPrefix, BiPredicate<TransitLine, TransitRoute> trainDetector) throws IOException {
String prefix = outputPrefix == null ? "" : outputPrefix;
Scenario scenario = ScenarioUtils.createScenario(config);
log.info("loading schedule from " + transitScheduleFilename);
new TransitScheduleReader(scenario).readFile(transitScheduleFilename);
new MatsimNetworkReader(scenario.getNetwork()).readFile(networkFilename);
new MatsimNetworkReader(scenario.getNetwork()).readFile(Resources.instance.getString(Properties.MATSIM_TRANSIT_NETWORK));

log.info("prepare PT Matrix calculation");
RaptorStaticConfig raptorConfig = RaptorUtils.createStaticConfig(config);
Expand All @@ -246,7 +254,7 @@ public final void calculatePtIndicators(String networkFilename, String transitSc
Set<String> origins = Sets.newHashSet(originBatch);
log.info("BATCH " + counter + ": calc PT matrices for " + Time.writeTime(startTime) + " - " + Time.writeTime(endTime));
PtData<String> matrices = PtCalculator.calculatePtIndicators(
raptorData, origins, destinations, this.zoneCoordMap, startTime, endTime, 120, raptorParameters, this.numberOfThreads, trainDetector);
raptorData, origins, destinations, this.zoneCoordMap, startTime, endTime, 120, raptorParameters, trainDetector);

log.info("BATCH " + counter + ": write PT matrices to " + outputDirectory + (prefix.isEmpty() ? "" : (" with prefix " + prefix)));
PtWriter.writeAsCsv(matrices,outputDirectory + "/" + prefix + "_" + "batch" + counter + ".csv.gz");
Expand Down Expand Up @@ -297,13 +305,13 @@ public static Map<String, Coord> buildZoneCoordMap(String filename) throws IOExc
return zoneCoordMap;
}

public static <T> Map<T, Node> buildZoneNodeMap(Map<T, Coord> zoneCoordMap, Network xy2lNetwork, Network routingNetwork) {
Map<T, Node> zoneNodeMap = new HashMap<>();
public static <T> Map<T, Id<Node>> buildZoneNodeMap(Map<T, Coord> zoneCoordMap, Network xy2lNetwork, Network routingNetwork) {
Map<T, Id<Node>> zoneNodeMap = new HashMap<>();
for (Map.Entry<T, Coord> e : zoneCoordMap.entrySet()) {
T zoneId = e.getKey();
Coord coord = e.getValue();
Node node = routingNetwork.getNodes().get(NetworkUtils.getNearestLink(xy2lNetwork, coord).getToNode().getId());
zoneNodeMap.put(zoneId, node);
Id<Node> nodeId = routingNetwork.getNodes().get(NetworkUtils.getNearestLink(xy2lNetwork, coord).getToNode().getId()).getId();
zoneNodeMap.put(zoneId, nodeId);
}
return zoneNodeMap;
}
Expand Down
23 changes: 13 additions & 10 deletions src/main/java/ch/sbb/matsim/analysis/calc/GeometryCalculator.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

package ch.sbb.matsim.analysis.calc;

import resources.Properties;
import resources.Resources;
import routing.TravelAttribute;
import ch.sbb.matsim.analysis.data.GeometryData;
import ch.sbb.matsim.graph.Graph;
Expand Down Expand Up @@ -44,10 +46,10 @@ public final class GeometryCalculator {
private GeometryCalculator() {
}

public static <T> GeometryData<T> calculate(Network routingNetwork, Set<T> origins, Set<T> destinations, Map<T, Node> zoneNodeMap,
public static <T> GeometryData<T> calculate(Network routingNetwork, Set<T> origins, Set<T> destinations, Map<T, Id<Node>> zoneNodeMap,
TravelTime travelTime, TravelDisutility travelDisutility,
LinkedHashMap<String, TravelAttribute> travelAttributes,
Vehicle vehicle, int numberOfThreads) {
Vehicle vehicle) {
Graph routingGraph = new Graph(routingNetwork);

// prepare calculation
Expand All @@ -57,6 +59,7 @@ public static <T> GeometryData<T> calculate(Network routingNetwork, Set<T> origi
ConcurrentLinkedQueue<T> originZones = new ConcurrentLinkedQueue<>(origins);

Counter counter = new Counter("PathGeometries zone ", " / " + origins.size());
int numberOfThreads = Resources.instance.getInt(Properties.NUMBER_OF_THREADS);
Thread[] threads = new Thread[numberOfThreads];
for (int i = 0; i < numberOfThreads; i++) {
RowWorker<T> worker = new RowWorker<>(originZones, destinations, routingGraph, zoneNodeMap,
Expand All @@ -81,7 +84,7 @@ private static class RowWorker<T> implements Runnable {
private final ConcurrentLinkedQueue<T> originZones;
private final Set<T> destinationZones;
private final Graph graph;
private final Map<T, Node> zoneNodeMap;
private final Map<T, Id<Node>> zoneNodeMap;
private final GeometryData<T> geometryData;
private final TravelTime travelTime;
private final TravelDisutility travelDisutility;
Expand All @@ -93,7 +96,7 @@ private static class RowWorker<T> implements Runnable {

private final static Person PERSON = PopulationUtils.getFactory().createPerson(Id.create("thePerson", Person.class));

RowWorker(ConcurrentLinkedQueue<T> originZones, Set<T> destinationZones, Graph graph, Map<T, Node> zoneNodeMap, GeometryData<T> geometryData,
RowWorker(ConcurrentLinkedQueue<T> originZones, Set<T> destinationZones, Graph graph, Map<T, Id<Node>> zoneNodeMap, GeometryData<T> geometryData,
TravelTime travelTime, TravelDisutility travelDisutility, LinkedHashMap<String, TravelAttribute> travelAttributes, Vehicle vehicle, Counter counter) {
this.originZones = originZones;
this.destinationZones = destinationZones;
Expand Down Expand Up @@ -127,14 +130,14 @@ public void run() {
}

this.counter.incCounter();
Node fromNode = this.zoneNodeMap.get(fromZoneId);
if (fromNode != null) {
lcpTree.calculate(fromNode.getId().index(), 0, PERSON, vehicle);
Id<Node> fromNodeId = this.zoneNodeMap.get(fromZoneId);
if (fromNodeId != null) {
lcpTree.calculate(fromNodeId.index(), 0, PERSON, vehicle);

for (T toZoneId : this.destinationZones) {
Node toNode = this.zoneNodeMap.get(toZoneId);
if (toNode != null) {
int nodeIndex = toNode.getId().index();
Id<Node> toNodeId = this.zoneNodeMap.get(toZoneId);
if (toNodeId != null) {
int nodeIndex = toNodeId.index();

int[] linksTravelled = lcpTree.getLinkArray(nodeIndex);
double tt = lcpTree.getTime(nodeIndex);
Expand Down
Loading

0 comments on commit d7d3491

Please sign in to comment.