Skip to content

Commit

Permalink
Updated manchester plans generator
Browse files Browse the repository at this point in the history
  • Loading branch information
CorinStaves committed Oct 18, 2024
1 parent 54892d4 commit 3816def
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 51 deletions.
9 changes: 5 additions & 4 deletions src/main/java/census/CensusReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import gis.GisUtils;
import org.apache.log4j.Logger;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.TransportMode;
import trip.Place;
Expand Down Expand Up @@ -68,9 +69,9 @@ public static Set<Trip> readAndProcessMatrix(Map<String, Geometry> zones, String
if(Math.random() <= scaleFactor) {
commutersRead++;
// Specify the home location randomly
Coord homeCoord = GisUtils.drawRandomPointFromGeometry(home);
Point homePoint = GisUtils.drawRandomPointFromGeometry(home);
// Specify the working location randomly
Coord workCoord = GisUtils.drawRandomPointFromGeometry(work);
Point workPoint = GisUtils.drawRandomPointFromGeometry(work);

// Store zone for each commuter
Map<Place,String> MSOAs = new HashMap<>(2);
Expand All @@ -79,8 +80,8 @@ public static Set<Trip> readAndProcessMatrix(Map<String, Geometry> zones, String

// Store coords for each commuter
Map<Place,Coord> coords = new HashMap<>(2);
coords.put(Place.HOME,homeCoord);
coords.put(Place.DESTINATION,workCoord);
coords.put(Place.HOME,new Coord(homePoint.getX(), homePoint.getY()));
coords.put(Place.DESTINATION,new Coord(workPoint.getX(),workPoint.getY()));

// Coords in boundary (always true)
Map<Place,Boolean> coordsInBoundary = new HashMap<>(2);
Expand Down
82 changes: 38 additions & 44 deletions src/main/java/demand/GenerateManchesterPlans.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package demand;
import gis.GisUtils;
import gis.GpkgReader;
import network.NetworkUtils2;
import org.apache.log4j.Logger;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.Point;
Expand All @@ -17,14 +17,12 @@
import org.matsim.api.core.v01.population.*;
import org.matsim.core.config.Config;
import org.matsim.core.config.ConfigUtils;
import org.matsim.core.gbl.MatsimRandom;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.network.io.MatsimNetworkReader;
import org.matsim.core.router.FastDijkstraFactory;
import org.matsim.core.router.costcalculators.FreespeedTravelTimeAndDisutility;
import org.matsim.core.router.util.LeastCostPathCalculator;
import org.matsim.core.scenario.ScenarioUtils;
import org.matsim.core.utils.geometry.geotools.MGC;
import org.matsim.core.utils.gis.ShapeFileReader;
import org.matsim.core.utils.misc.Counter;
import org.opengis.feature.simple.SimpleFeature;
Expand Down Expand Up @@ -63,7 +61,7 @@ public class GenerateManchesterPlans {
private final TimeDistributions timeDistribution;
private final String omxFolder;
private Map<Integer, Geometry> shapeMap;

private Geometry regionBoundary;
private Geometry networkBoundary;
private LeastCostPathCalculator lcpCalculator;

Expand Down Expand Up @@ -104,6 +102,7 @@ public static void main(String[] args) throws FactoryException, IOException {
private void run() throws IOException {

// READ NETWORK BOUNDARY
this.regionBoundary = GpkgReader.readRegionBoundary();
this.networkBoundary = GpkgReader.readNetworkBoundary();

// READ ZONES SHAPEFILE
Expand Down Expand Up @@ -164,27 +163,27 @@ private void run() throws IOException {
int origZoneId = i+1;
int destZoneId = j+1;
TimeSampler morningTimeSampler = new MorningTimeSampler();
createOD(morningUc1[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(morningUc2[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(morningUc3[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(morningUc4[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(morningUc5[i][j] * 2.58 / 2.5,"truck",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(morningUc1[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(morningUc2[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(morningUc3[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(morningUc4[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(morningUc5[i][j] * 2.58 / 2.5,"truck",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
// createOD(morningUc5[i][j] * 2.58,"car",morningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);

TimeSampler ipTimeSampler = new InterpeakTimeSampler();
createOD(interpeakUc1[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(interpeakUc2[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(interpeakUc3[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(interpeakUc4[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(interpeakUc5[i][j] * 9.159 / 2.5,"truck",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(interpeakUc1[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(interpeakUc2[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(interpeakUc3[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(interpeakUc4[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(interpeakUc5[i][j] * 9.159 / 2.5,"truck",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
// createOD(interpeakUc5[i][j] * 9.159,"car",ipTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);

TimeSampler eveningTimeSampler = new EveningTimeSampler();
createOD(eveningUc1[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(eveningUc2[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(eveningUc3[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(eveningUc4[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(eveningUc5[i][j] * 2.75 / 2.5,"truck",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId);
createOD(eveningUc1[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(eveningUc2[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(eveningUc3[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,true);
createOD(eveningUc4[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
createOD(eveningUc5[i][j] * 2.75 / 2.5,"truck",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId,false);
// createOD(eveningUc5[i][j] * 2.75,"car",eveningTimeSampler,origZoneId,destZoneId,origZoneId + "_" + destZoneId
}
}
Expand Down Expand Up @@ -254,43 +253,34 @@ public double sample() {
}
}

// Create random coordinates within a given polygon
private Coord drawRandomPointFromGeometry(Geometry g) {
Random rnd = MatsimRandom.getLocalInstance();
Point p;
double x, y;
do {
x = g.getEnvelopeInternal().getMinX()
+ rnd.nextDouble() * (g.getEnvelopeInternal().getMaxX() - g.getEnvelopeInternal().getMinX());
y = g.getEnvelopeInternal().getMinY()
+ rnd.nextDouble() * (g.getEnvelopeInternal().getMaxY() - g.getEnvelopeInternal().getMinY());
p = MGC.xy2Point(x, y);
} while (!g.contains(p));
return new Coord(p.getX(), p.getY());
}

// Create od relations for each MSOA pair
private void createOD(double pop,String mode,TimeSampler timeSampler, int origin, int destination, String toFromPrefix) {
private void createOD(double pop,String mode,TimeSampler timeSampler, int origin, int destination, String toFromPrefix, boolean externalOnly) {

if(pop > 0.) {
int popInt = (int) pop;
double remainder = pop - popInt;

// Specify the ID of these two MSOAs
Geometry origGeom = this.shapeMap.get(origin);
Geometry destGeom = this.shapeMap.get(destination);
// Get zone polygons
Geometry origZonePolygon = this.shapeMap.get(origin);
Geometry destZonePolygon = this.shapeMap.get(destination);

int i = 0;
if (origGeom != null && destGeom != null) {
if (origZonePolygon != null && destZonePolygon != null) {
Point origPoint = GisUtils.drawRandomPointFromGeometry(origZonePolygon);
Point destPoint = GisUtils.drawRandomPointFromGeometry(destZonePolygon);
while (i < popInt) {
if (rand.nextDouble() < this.sampleSize) {
createOnePerson(mode, timeSampler.sample(), drawRandomPointFromGeometry(origGeom), drawRandomPointFromGeometry(destGeom), toFromPrefix);
if(!externalOnly || !regionBoundary.contains(origPoint) || !regionBoundary.contains(destPoint)) {
createOnePerson(mode, timeSampler.sample(), origPoint, destPoint, toFromPrefix);
}
}
i++;
}
if (rand.nextDouble() <= remainder) {
if (rand.nextDouble() < this.sampleSize) {
createOnePerson(mode, timeSampler.sample(), drawRandomPointFromGeometry(origGeom), drawRandomPointFromGeometry(destGeom), toFromPrefix);
if(!externalOnly || !regionBoundary.contains(origPoint) || !regionBoundary.contains(destPoint)) {
createOnePerson(mode, timeSampler.sample(), origPoint, destPoint, toFromPrefix);
}
}
}
} else {
Expand All @@ -301,7 +291,7 @@ private void createOD(double pop,String mode,TimeSampler timeSampler, int origi
}

// Create plan for each commuter
private void createOnePerson( String mode, double time, Coord origCoord, Coord destCoord, String toFromPrefix) {
private void createOnePerson( String mode, double time, Point origPoint, Point destPoint, String toFromPrefix) {

totalTrips.incCounter();

Expand All @@ -310,13 +300,17 @@ private void createOnePerson( String mode, double time, Coord origCoord, Coord d

Plan plan = scenario.getPopulation().getFactory().createPlan();

// Convert points to coords
Coord origCoord = new Coord(origPoint.getX(),origPoint.getY());
Coord destCoord = new Coord(destPoint.getX(),destPoint.getY());

// Create activities
Activity origin = scenario.getPopulation().getFactory().createActivityFromCoord("loc", origCoord);
Activity destination = scenario.getPopulation().getFactory().createActivityFromCoord("loc", destCoord);

// Origin Link
Link originLink;
if (networkBoundary.contains(GEOMETRY_FACTORY.createPoint(new Coordinate(origCoord.getX(), origCoord.getY())))) {
if (networkBoundary.contains(origPoint)) {
originLink = NetworkUtils.getNearestLinkExactly(internalNetwork, origCoord);
} else {
originLink = NetworkUtils.getNearestLinkExactly(entryNetwork, origCoord);
Expand All @@ -325,7 +319,7 @@ private void createOnePerson( String mode, double time, Coord origCoord, Coord d

// Destination link
Link destinationLink;
if (networkBoundary.contains(GEOMETRY_FACTORY.createPoint(new Coordinate(destCoord.getX(), destCoord.getY())))) {
if (networkBoundary.contains(destPoint)) {
destinationLink = NetworkUtils.getNearestLinkExactly(internalNetwork, destCoord);
} else {
destinationLink = NetworkUtils.getNearestLinkExactly(exitNetwork, destCoord);
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/gis/GisUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ private static SimpleFeature findZone(Coord coord, SpatialIndex zonesQt) {
return null;
}

public static Coord drawRandomPointFromGeometry(Geometry g) {
public static Point drawRandomPointFromGeometry(Geometry g) {
Random rnd = MatsimRandom.getLocalInstance();
Point p;
double x, y;
Expand All @@ -174,7 +174,7 @@ public static Coord drawRandomPointFromGeometry(Geometry g) {
+ rnd.nextDouble() * (g.getEnvelopeInternal().getMaxY() - g.getEnvelopeInternal().getMinY());
p = MGC.xy2Point(x, y);
} while (!g.contains(p));
return new Coord(p.getX(), p.getY());
return p;
}

}
2 changes: 1 addition & 1 deletion src/main/java/resources/Properties.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Properties {
public static final String MATSIM_DEMAND_VEHICLES = "matsim.demand.vehicles";
public static final String MATSIM_DEMAND_PLANS = "matsim.demand.plans";
public static final String MATSIM_DEMAND_OUTPUT_EVENTS = "matsim.demand.output.events";
// public static final String MATSIM_DEMAND_OUTPUT_NETWORK = "matsim.demand.output.network";
public static final String MATSIM_DEMAND_OUTPUT_NETWORK = "matsim.demand.output.network";
public static final String MATSIM_DEMAND_OUTPUT_VEHICLES = "matsim.demand.output.vehicles";
public static final String MATSIM_DEMAND_OUTPUT_SCALE_FACTOR = "matsim.demand.output.scale.factor";

Expand Down

0 comments on commit 3816def

Please sign in to comment.