Skip to content

Commit

Permalink
Enhanced and Refactored TransferRestrictions (untested)
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksander1234519 committed Aug 21, 2024
1 parent 1822d56 commit 50eb84c
Showing 1 changed file with 170 additions and 107 deletions.
277 changes: 170 additions & 107 deletions src/main/java/org/matsim/prepare/commercial/TransferRestrictions.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.LineString;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.api.core.v01.network.Node;
Expand All @@ -14,10 +15,7 @@
import org.locationtech.jts.geom.MultiLineString;

import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand All @@ -26,27 +24,114 @@ public class TransferRestrictions {
Transfers Restrictions from the shapefile to the given Network.
*/

private static final String ruhrNetworkPath = "D:\\Projects\\VSP\\RUHR\\metropole-ruhr-v2.0.network_resolutionHigh-with-pt.xml";
// private static final String ruhrNetworkPath = "D:\\Projects\\VSP\\RUHR\\metropole-ruhr-v2.0.network_resolutionHigh-with-pt.xml";
private static final String ruhrNetworkPath = "D:\\Projects\\VSP\\RUHR\\metropole-ruhr-v2.0_network.xml";
private static final String restrictionPath = "D:\\Projects\\VSP\\RUHR\\commercialTraffic\\Restriktionen_RVR_20231121\\Restriktionen_RVR_20231121.shp";
private static final String outputPath = "scenarios/metropole-ruhr-v1.0/ruhr_network_with_restrictions.xml.gz";

public static void main(String[] args){
//Read in shp and xml files
Network network = NetworkUtils.readNetwork(ruhrNetworkPath);
/**
* Create a copy of the given network with car-links only (no pt, no bike-only-links, ...)
*/
private static Network copyNetworkWithoutPT(Network network_with_pt){
Network network_no_pt = NetworkUtils.createNetwork();
ShpOptions shp = new ShpOptions(Path.of(restrictionPath), null, null);

//Create copy of network which only contains links, where car/freight-traffic is allowed (not pt, no bike-only-links, ...)
for(Node n : network.getNodes().values()){
for(Node n : network_with_pt.getNodes().values()){
if(!n.getId().toString().startsWith("pt") && !n.getId().toString().startsWith("bike")){
network_no_pt.addNode(n);
}
}
for(Link l : network.getLinks().values()){
for(Link l : network_with_pt.getLinks().values()){
if(l.getAllowedModes().contains("car") || l.getAllowedModes().contains("freight")){
network_no_pt.addLink(l);
}
}
return network_no_pt;
}

private static void findLinksFromFeature(SimpleFeature i, Network network_no_pt, Map<Id<Link>, String[]> linkId2RestrictionCode){
//Transform into LineString object (The MultilineString in this file saves all the Geometry in the first LineString)
//System.out.println(i.getID());
MultiLineString way = (MultiLineString) i.getDefaultGeometry();
LineString waypart = (LineString) way.getGeometryN(0); //Get first LineString (only relevant one)
Coordinate[] coordinates = waypart.getCoordinates(); //All vertices of the LineString

//TODO DEBUG
boolean foundLink = false;

//Check for every vertices-combination if there is a link that the restriction can be assigned to
for(int j = 1; j < coordinates.length; j++){
for(int k = j; k < coordinates.length; k++){
//Get two vertices and compute the Euclidean center of then
Coord start = MGC.coordinate2Coord(coordinates[k]);
Coord end = MGC.coordinate2Coord(coordinates[k-j]);
Coord center = CoordUtils.getCenter(start, end);

//Find the nearest link to the center vertice
Link centerNearestLink = NetworkUtils.getNearestLinkExactly(network_no_pt, center);

//Assure that the link assignment was correct
//-> Check if the link was already found
{
if(linkId2RestrictionCode.containsKey(centerNearestLink.getId())) continue;
}

//-> Check if distance of start or end to the found link is too high
{
//Compute the distance from start to the found link
double x_s = start.getX();
double y_s = start.getY();
double x_e = end.getX();
double y_e = end.getY();
double x_1 = centerNearestLink.getFromNode().getCoord().getX();
double y_1 = centerNearestLink.getFromNode().getCoord().getY();
double x_2 = centerNearestLink.getToNode().getCoord().getX();
double y_2 = centerNearestLink.getToNode().getCoord().getY();
double distance_start = Math.abs((y_2-y_1)*x_s - (x_2-x_1)*y_s + x_2*y_1 - y_2*x_1) / Math.sqrt(Math.pow(x_2-y_1, 2) + Math.pow(x_2 - x_1, 2));
double distance_end = Math.abs((y_2-y_1)*x_e - (x_2-x_1)*y_e + x_2*y_1 - y_2*x_1) / Math.sqrt(Math.pow(x_2-y_1, 2) + Math.pow(x_2 - x_1, 2));

if(distance_start > 10 ||distance_end > 10) continue;
}

//-> Check if rotation difference is too high
{
double link_euclidean_length = NetworkUtils.getEuclideanDistance(centerNearestLink.getFromNode().getCoord(), centerNearestLink.getToNode().getCoord());
double[] lineAsVector = new double[]{end.getX() - start.getX(), end.getY() - start.getY()};
double[] linkAsVector = new double[]{
centerNearestLink.getToNode().getCoord().getX() - centerNearestLink.getFromNode().getCoord().getX(),
centerNearestLink.getToNode().getCoord().getY() - centerNearestLink.getFromNode().getCoord().getY()};
// Compute the rotation-angle between the two using the dot-product: cos(rot)= (a*b) / (||a||*||b||)
double rotation = (lineAsVector[0] * linkAsVector[0] + lineAsVector[1] * linkAsVector[1]) /
(link_euclidean_length * NetworkUtils.getEuclideanDistance(start, end));
//Convert into degree
rotation = (Math.acos(Math.abs(rotation)) / Math.PI) * 180;

if (rotation > 5) { //5 is an arbitrary choice
continue;
}
}

//Final step: Save the restrictions in the map
foundLink = true;
Link oppositeLink = NetworkUtils.findLinkInOppositeDirection(centerNearestLink);

linkId2RestrictionCode.putIfAbsent(centerNearestLink.getId(),
new String[]{(String) i.getAttribute("typ"),
((String)i.getAttribute("wert")).replace(",", ".")});

if(oppositeLink == null) continue;
linkId2RestrictionCode.putIfAbsent(oppositeLink.getId(),
new String[]{(String) i.getAttribute("typ"),
((String)i.getAttribute("wert")).replace(",", ".")});

}
}
}

public static void applyRestrictions(String ruhrNetworkPath, String restrictionPath, String outputPath){
//Read in shp and xml files
Network network = NetworkUtils.readNetwork(ruhrNetworkPath);
Network network_no_pt = copyNetworkWithoutPT(network);
ShpOptions shp = new ShpOptions(Path.of(restrictionPath), null, null);

// Add all freight-modes to all car-links
Collection<? extends Link> links = network.getLinks().values();
Expand All @@ -58,107 +143,85 @@ public static void main(String[] args){
}
}

// Remove freight-modes from restricted links
for(SimpleFeature i : shp.readFeatures()){
//Transform into LineString object
MultiLineString way = (MultiLineString) i.getDefaultGeometry();
LineString waypart = (LineString) way.getGeometryN(0);

//Read coordinates and prepare Coord
Coordinate[] coordinates = waypart.getCoordinates();

//Translate Coordinate into Coord-objects and get the nearest link for every node-pair
for (int j = 0; j < coordinates.length; j++){
Coord coord = MGC.coordinate2Coord(coordinates[j]);

//Finds the center of two nodes and searches for the link from there
if(j != 0){
Coord center = CoordUtils.getCenter(coord, coord);
Link nearestLink = NetworkUtils.getNearestLinkExactly(network_no_pt, center);
Link oppositeLink = NetworkUtils.findLinkInOppositeDirection(nearestLink);
Set<String> allowedModes = new HashSet<>(nearestLink.getAllowedModes()); // Makes a copy, because original is immutable

//Sort out links, that were assigned incorrectly
double distance = NetworkUtils.getEuclideanDistance(nearestLink.getFromNode().getCoord(), center);
double links_euclidean_length = NetworkUtils.getEuclideanDistance(nearestLink.getFromNode().getCoord(), nearestLink.getToNode().getCoord());
if(distance > links_euclidean_length+20){
continue;
}

//Get value if numeric
float value = -1;
try{
value = Float.parseFloat(((String)i.getAttribute("wert")).replace(",", "."));
} catch(Exception ignored){
Map<Id<Link>, String[]> linkId2RestrictionCode = new HashMap<>();
//Iterate through every SimpleFeature and find the corresponding Link in the network and save the restriction code in the Map.
for(SimpleFeature i : shp.readFeatures()) {
findLinksFromFeature(i, network_no_pt, linkId2RestrictionCode);
}

//Apply Restrictions to network
for(Map.Entry<Id<Link>, String[]> e : linkId2RestrictionCode.entrySet()) {
Id<Link> id = e.getKey();
String type = e.getValue()[0];
float value = -1;
try{ value = Float.parseFloat(e.getValue()[1]); } catch(Exception ignored) {}
//System.out.println(id);
Set<String> allowedModes = new HashSet<>(network.getLinks().get(id).getAllowedModes()); // Makes a copy, because original is immutable

switch(type){
case "253":
// No freight allowed
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
break;
case "262":
// Weight specific restriction
if(value > 12){ // # TODO: Das hier scheint in der Dok falsch zu sein: < 12 waere sinnvoller
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
} else {
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
}

//Filter out all modes, that are not allowed
switch((String) i.getAttribute("typ")){
case "253":
// No freight allowed
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
break;
case "262":
// Weight specific restriction
if(value > 12){ // # TODO: Das hier scheint in der Dok falsch zu sein: < 12 waere sinnvoller
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
} else {
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
}
break;
case "264":
// Height restriction: No freight allowed if restriction is <= 4 meters
if (value <= 4 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
}
break;
case "265":
// Width restriction: No freight allowed if restriction is <= 2.5 meters
if (value <= 2.5 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
}
break;
case "266":
// Length restriction: No freight > 8t allowed if restriction is <= 10 meters
if (value <= 10 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
}
break;
default:
break;
break;
case "264":
// Height restriction: No freight allowed if restriction is <= 4 meters
if (value <= 4 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
}

//Update the allowed link modes
nearestLink.setAllowedModes(allowedModes);
if(oppositeLink != null){
oppositeLink.setAllowedModes(allowedModes);
break;
case "265":
// Width restriction: No freight allowed if restriction is <= 2.5 meters
if (value <= 2.5 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
allowedModes.remove("truck8t");
}
}
break;
case "266":
// Length restriction: No freight > 8t allowed if restriction is <= 10 meters
if (value <= 10 && value != -1){
allowedModes.remove("freight");
allowedModes.remove("truck40t");
allowedModes.remove("truck26t");
allowedModes.remove("truck18t");
}
break;
default:
break;
}
//Update the allowed link modes
network.getLinks().get(id).setAllowedModes(allowedModes);
}
NetworkUtils.writeNetwork(network, outputPath);
}

public static void main(String[] args) {
TransferRestrictions.applyRestrictions(ruhrNetworkPath, restrictionPath, outputPath);
}
}

0 comments on commit 50eb84c

Please sign in to comment.