Skip to content

Commit

Permalink
Skims creator automatically updates volumes for stress
Browse files Browse the repository at this point in the history
  • Loading branch information
CorinStaves committed Dec 5, 2024
1 parent 28ef9e3 commit f1be6fc
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 105 deletions.
113 changes: 10 additions & 103 deletions src/main/java/network/CreateMatsimNetworkRoad.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ public static void main(String[] args) {
// Create network links
edges.forEach((id,edge) -> addLinkToNetwork(id,edge,net,fac));

// Add volumes from events file
addSimulationVolumes(net);

// Write crossing attributes
addCrossingAttributes(net);
// // Add volumes from events file
// NetworkUtils2.addSimulationVolumes(readSimulationVolumes(),net);
//
// // Write crossing attributes
// NetworkUtils2.addCrossingAttributes(net);

// Identify disconnected links
NetworkUtils2.identifyDisconnectedLinks(net,walk);
Expand Down Expand Up @@ -334,81 +334,9 @@ private static void addLinkToNetwork(int edgeID, SimpleFeature edge, Network net
}
}

private static void addCrossingAttributes(Network net) {
Map<Node, List<Link>> linksTo = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> new ArrayList<>()));
Map<Node,List<Link>> linksFrom = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> new ArrayList<>()));
Map<Node,Boolean> isJunction = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> false));

// List links arriving at each node
for (Link link : net.getLinks().values()) {
linksTo.get(link.getToNode()).add(link);
linksFrom.get(link.getFromNode()).add(link);
}

// Check whether each link is a junction (i.e. there are more than 2 links connected to node)
for (Node node : net.getNodes().values()) {
boolean junction = Stream.concat(linksFrom.get(node).stream(),linksTo.get(node).stream())
.mapToInt(l -> (int) l.getAttributes().getAttribute("edgeID"))
.distinct()
.count() > 2;
isJunction.put(node,junction);
}

for (Link link : net.getLinks().values()) {

boolean endsAtJct = isJunction.get(link.getToNode());
boolean crossVehicles = false;
double crossAadt = Double.NaN;
double crossWidth = Double.NaN;
double crossLanes = Double.NaN;
double crossSpeedLimit = Double.NaN;
double cross85PercSpeed = Double.NaN;

if(endsAtJct) {
int osmID = (int) link.getAttributes().getAttribute("osmID");
String name = (String) link.getAttributes().getAttribute("name");
Set<Link> crossingLinks = linksTo.get(link.getToNode())
.stream()
.filter(l -> (boolean) l.getAttributes().getAttribute("allowsCarFwd"))
.filter(l -> !isMatchingRoad(l,osmID,name))
.collect(Collectors.toSet());

if(!crossingLinks.isEmpty()) {

crossVehicles = true;
crossWidth = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("width"))
.sum();
crossLanes = crossingLinks.stream()
.mapToDouble(Link::getNumberOfLanes)
.sum();
crossAadt = crossingLinks.stream()
.mapToInt(l -> (int) l.getAttributes().getAttribute("aadtFwd"))
.sum();
crossSpeedLimit = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("speedLimitMPH"))
.max().getAsDouble();
cross85PercSpeed = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("veh85percSpeedKPH"))
.max().getAsDouble();
}
}

link.getAttributes().putAttribute("endsAtJct",endsAtJct);
link.getAttributes().putAttribute("crossVehicles",crossVehicles);
link.getAttributes().putAttribute("crossWidth",crossWidth);
link.getAttributes().putAttribute("crossLanes",crossLanes);
link.getAttributes().putAttribute("crossAadt",crossAadt);
link.getAttributes().putAttribute("crossSpeedLimitMPH",crossSpeedLimit);
link.getAttributes().putAttribute("cross85PercSpeed",cross85PercSpeed);
}
}

private static void addSimulationVolumes(Network network) {
log.info("Adding volumes from events...");
int scaleFactor = (int) (1 / Resources.instance.getDouble(Properties.MATSIM_DEMAND_OUTPUT_SCALE_FACTOR));
log.info("Multiplying all volumes from events file by a factor of " + scaleFactor);
public static DailyVolumeEventHandler readSimulationVolumes() {

// Read events file
EventsManager eventsManager = new EventsManagerImpl();
DailyVolumeEventHandler dailyVolumeEventHandler = new DailyVolumeEventHandler(Resources.instance.getString(Properties.MATSIM_DEMAND_OUTPUT_VEHICLES));
eventsManager.addHandler(dailyVolumeEventHandler);
Expand All @@ -420,23 +348,10 @@ private static void addSimulationVolumes(Network network) {
log.info("Identified " + carEvents + " car link enter events.");
log.info("Identified " + truckEvents + " truck link enter events.");

// Add forward AADT
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd_car", dailyVolumeEventHandler.getCarVolumes().getOrDefault(id,0) * scaleFactor));
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd_truck", dailyVolumeEventHandler.getTruckVolumes().getOrDefault(id,0) * scaleFactor));
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd", dailyVolumeEventHandler.getAdjVolumes().getOrDefault(id,0) * scaleFactor));

// Add forward + opposing AADT
for(Link link : network.getLinks().values()) {
int aadtFwd = (int) link.getAttributes().getAttribute("aadtFwd");
int aadtOpp = 0;
Link oppositeLink = NetworkUtils.findLinkInOppositeDirection(link);
if(oppositeLink != null) {
aadtOpp = (int) oppositeLink.getAttributes().getAttribute("aadtFwd");
}
link.getAttributes().putAttribute("aadt",aadtFwd + aadtOpp);
}
return dailyVolumeEventHandler;
}


private static void putDoubleAttribute(Link link, SimpleFeature edge, String name, String matsimName, double valueIfNull) {
Double attr = (Double) edge.getAttribute(name);
if(attr == null) {
Expand All @@ -453,13 +368,5 @@ private static void putIntegerAttribute(Link link, SimpleFeature edge, String na
link.getAttributes().putAttribute(matsimName,attr);
}

private static boolean isMatchingRoad(Link link, int osmID, String name) {
boolean osmIdMatch = link.getAttributes().getAttribute("osmID").equals(osmID);
boolean nameMatch = link.getAttributes().getAttribute("name").equals(name);
if(!name.equals("")) {
return nameMatch || osmIdMatch;
} else {
return osmIdMatch;
}
}

}
108 changes: 108 additions & 0 deletions src/main/java/network/NetworkUtils2.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

// Additional utils beyond NetworkUtils

import demand.volumes.DailyVolumeEventHandler;
import org.apache.log4j.Logger;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
Expand Down Expand Up @@ -31,6 +32,8 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class NetworkUtils2 {

Expand All @@ -57,6 +60,111 @@ public static Network extractModeSpecificNetwork(Network network, String transpo
return modeSpecificNetwork;
}


public static void addSimulationVolumes(DailyVolumeEventHandler dailyVolumeEventHandler, Network network) {

// Get scale factor
log.info("Adding volumes from events...");
int scaleFactor = (int) (1 / Resources.instance.getDouble(Properties.MATSIM_DEMAND_OUTPUT_SCALE_FACTOR));
log.info("Multiplying all volumes from events file by a factor of " + scaleFactor);

// Add forward AADT
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd_car", dailyVolumeEventHandler.getCarVolumes().getOrDefault(id,0) * scaleFactor));
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd_truck", dailyVolumeEventHandler.getTruckVolumes().getOrDefault(id,0) * scaleFactor));
network.getLinks().forEach((id,link) -> link.getAttributes().putAttribute("aadtFwd", dailyVolumeEventHandler.getAdjVolumes().getOrDefault(id,0) * scaleFactor));

// Add forward + opposing AADT
for(Link link : network.getLinks().values()) {
int aadtFwd = (int) link.getAttributes().getAttribute("aadtFwd");
int aadtOpp = 0;
Link oppositeLink = NetworkUtils.findLinkInOppositeDirection(link);
if(oppositeLink != null) {
aadtOpp = (int) oppositeLink.getAttributes().getAttribute("aadtFwd");
}
link.getAttributes().putAttribute("aadt",aadtFwd + aadtOpp);
}
}

public static void addCrossingAttributes(Network net) {
Map<Node, List<Link>> linksTo = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> new ArrayList<>()));
Map<Node,List<Link>> linksFrom = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> new ArrayList<>()));
Map<Node,Boolean> isJunction = net.getNodes().values().stream().collect(Collectors.toMap(n -> n, n -> false));

// List links arriving at each node
for (Link link : net.getLinks().values()) {
linksTo.get(link.getToNode()).add(link);
linksFrom.get(link.getFromNode()).add(link);
}

// Check whether each link is a junction (i.e. there are more than 2 links connected to node)
for (Node node : net.getNodes().values()) {
boolean junction = Stream.concat(linksFrom.get(node).stream(),linksTo.get(node).stream())
.mapToInt(l -> (int) l.getAttributes().getAttribute("edgeID"))
.distinct()
.count() > 2;
isJunction.put(node,junction);
}

for (Link link : net.getLinks().values()) {

boolean endsAtJct = isJunction.get(link.getToNode());
boolean crossVehicles = false;
double crossAadt = Double.NaN;
double crossWidth = Double.NaN;
double crossLanes = Double.NaN;
double crossSpeedLimit = Double.NaN;
double cross85PercSpeed = Double.NaN;

if(endsAtJct) {
int osmID = (int) link.getAttributes().getAttribute("osmID");
String name = (String) link.getAttributes().getAttribute("name");
Set<Link> crossingLinks = linksTo.get(link.getToNode())
.stream()
.filter(l -> (boolean) l.getAttributes().getAttribute("allowsCarFwd"))
.filter(l -> !isMatchingRoad(l,osmID,name))
.collect(Collectors.toSet());

if(!crossingLinks.isEmpty()) {

crossVehicles = true;
crossWidth = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("width"))
.sum();
crossLanes = crossingLinks.stream()
.mapToDouble(Link::getNumberOfLanes)
.sum();
crossAadt = crossingLinks.stream()
.mapToInt(l -> (int) l.getAttributes().getAttribute("aadtFwd"))
.sum();
crossSpeedLimit = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("speedLimitMPH"))
.max().getAsDouble();
cross85PercSpeed = crossingLinks.stream()
.mapToDouble(l -> (double) l.getAttributes().getAttribute("veh85percSpeedKPH"))
.max().getAsDouble();
}
}

link.getAttributes().putAttribute("endsAtJct",endsAtJct);
link.getAttributes().putAttribute("crossVehicles",crossVehicles);
link.getAttributes().putAttribute("crossWidth",crossWidth);
link.getAttributes().putAttribute("crossLanes",crossLanes);
link.getAttributes().putAttribute("crossAadt",crossAadt);
link.getAttributes().putAttribute("crossSpeedLimitMPH",crossSpeedLimit);
link.getAttributes().putAttribute("cross85PercSpeed",cross85PercSpeed);
}
}

private static boolean isMatchingRoad(Link link, int osmID, String name) {
boolean osmIdMatch = link.getAttributes().getAttribute("osmID").equals(osmID);
boolean nameMatch = link.getAttributes().getAttribute("name").equals(name);
if(!name.equals("")) {
return nameMatch || osmIdMatch;
} else {
return osmIdMatch;
}
}

public static void extractFromNodes(Network network, Set<Id<Node>> nodeIds) {
IdSet<Node> nodesToRemove = new IdSet<>(Node.class);
for (Node node : network.getNodes().values()) {
Expand Down
9 changes: 7 additions & 2 deletions src/main/java/skim/RunSkims.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package skim;

import demand.volumes.DailyVolumeEventHandler;
import estimation.RouteAttribute;
import gis.GpkgReader;
import io.OmxWriter;
Expand Down Expand Up @@ -38,7 +39,7 @@

public class RunSkims {

public static final String FILE_PATH_PREFIX = "intervention/cycling/";
public static final String FILE_PATH_PREFIX = "skims/";

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

Expand All @@ -62,18 +63,22 @@ public static void main(String[] args) throws IOException, FactoryException {
Network networkCar = NetworkUtils2.extractModeSpecificNetwork(networkCarInput, TransportMode.car);
Network carXy2l = NetworkUtils2.extractXy2LinksNetwork(networkCar, l -> !((boolean) l.getAttributes().getAttribute("motorway")));

// Car freespeed & congested travel time
// Car freespeed & congested travel time
String tfgmDemandEvents = Resources.instance.getString(Properties.MATSIM_DEMAND_OUTPUT_EVENTS);
TravelTimeCalculator.Builder builder = new TravelTimeCalculator.Builder(networkCar);
TravelTimeCalculator congested = builder.build();
DailyVolumeEventHandler dailyVolumeEventHandler = new DailyVolumeEventHandler(Resources.instance.getString(Properties.MATSIM_DEMAND_OUTPUT_VEHICLES));
EventsManager events = EventsUtils.createEventsManager();
events.addHandler(congested);
events.addHandler(dailyVolumeEventHandler);
(new MatsimEventsReader(events)).readFile(tfgmDemandEvents);
TravelTime congestedTime = congested.getLinkTravelTimes();
TravelDisutility congestedDisutility = new OnlyTimeDependentTravelDisutility(congested.getLinkTravelTimes());

// Create active mode networks
Network network = NetworkUtils2.readFullNetwork();
NetworkUtils2.addSimulationVolumes(dailyVolumeEventHandler,network);
NetworkUtils2.addCrossingAttributes(network);
Network networkWalk = NetworkUtils2.extractModeSpecificNetwork(network, TransportMode.walk);
Network networkBike = NetworkUtils2.extractModeSpecificNetwork(network, TransportMode.bike);

Expand Down

0 comments on commit f1be6fc

Please sign in to comment.