Skip to content

Commit

Permalink
try to avoid restrictions that lead to unreachable links, add option …
Browse files Browse the repository at this point in the history
…to remove disallowed links from network (matsim-org#3257)
  • Loading branch information
rakow authored May 7, 2024
1 parent 87e84ac commit 791f39b
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.matsim.application.prepare.network;

import org.matsim.api.core.v01.TransportMode;
import org.matsim.api.core.v01.network.Link;
import org.matsim.api.core.v01.network.Network;
import org.matsim.application.MATSimAppCommand;
import org.matsim.core.network.DisallowedNextLinks;
import org.matsim.core.network.NetworkUtils;
import org.matsim.core.network.algorithms.MultimodalNetworkCleaner;
import picocli.CommandLine;
Expand All @@ -25,11 +27,30 @@ public class CleanNetwork implements MATSimAppCommand {
@CommandLine.Option(names = "--modes", description = "List of modes to clean", split = ",", defaultValue = TransportMode.car)
private Set<String> modes;

@CommandLine.Option(names = "--remove-turn-restrictions", description = "Remove turn restrictions for specified modes.", defaultValue = "false")
private boolean rmTurnRestrictions;

public static void main(String[] args) {
new CleanNetwork().execute(args);
}

@Override
public Integer call() throws Exception {

Network network = NetworkUtils.readNetwork(input.toString());

if (rmTurnRestrictions) {
for (Link link : network.getLinks().values()) {
DisallowedNextLinks disallowed = NetworkUtils.getDisallowedNextLinks(link);
if (disallowed != null) {
modes.forEach(disallowed::removeDisallowedLinkSequences);
if (disallowed.isEmpty()) {
NetworkUtils.removeDisallowedNextLinks(link);
}
}
}
}

var cleaner = new MultimodalNetworkCleaner(network);

for (String m : modes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.apache.commons.csv.CSVPrinter;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.locationtech.jts.geom.Geometry;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.TransportMode;
Expand All @@ -21,7 +20,6 @@
import org.matsim.core.scenario.ProjectionUtils;
import org.matsim.core.utils.geometry.CoordinateTransformation;
import org.matsim.core.utils.geometry.transformations.TransformationFactory;
import org.matsim.core.utils.gis.GeoFileReader;
import org.matsim.core.utils.io.IOUtils;
import org.xml.sax.SAXException;
import picocli.CommandLine;
Expand Down Expand Up @@ -70,8 +68,8 @@ private SumoNetworkConverter(List<Path> input, Path output, String fromCRS, Stri
this.fromCRS = fromCRS;
this.toCRS = toCRS;
this.freeSpeedFactor = freeSpeedFactor;
this.laneRestriction = laneRestriction;
}
this.laneRestriction = laneRestriction;
}

private SumoNetworkConverter() {
}
Expand Down Expand Up @@ -119,14 +117,6 @@ public static void main(String[] args) {
System.exit(new CommandLine(new SumoNetworkConverter()).execute(args));
}

/**
* Network area based on the cut-out.
*/
private static Geometry calculateNetworkArea(Path shapeFile) {
// only the first feature is used
return ((Geometry) GeoFileReader.getAllFeatures(shapeFile.toString()).iterator().next().getDefaultGeometry());
}

/**
* Determine if a mode is allowed on a link.
*/
Expand Down Expand Up @@ -342,6 +332,9 @@ public SumoNetworkHandler convert(Network network) throws ParserConfigurationExc

Set<Id<Link>> ignored = new HashSet<>();

// map of link and source link that are restricted
Map<Id<Link>, Set<Id<Link>>> restrictions = new HashMap<>();

for (Map.Entry<String, List<SumoNetworkHandler.Connection>> kv : sumoHandler.connections.entrySet()) {

Link link = network.getLinks().get(Id.createLinkId(kv.getKey()));
Expand All @@ -350,16 +343,30 @@ public SumoNetworkHandler convert(Network network) throws ParserConfigurationExc
Set<Id<Link>> outLinks = link.getToNode().getOutLinks().keySet();
Set<Id<Link>> allowed = kv.getValue().stream().map(c -> Id.createLinkId(c.to)).collect(Collectors.toSet());

Sets.SetView<Id<Link>> diff = Sets.difference(outLinks, allowed);
// Disallowed link ids
Sets.SetView<Id<Link>> dis = Sets.difference(outLinks, allowed);

if (outLinks.size() == diff.size()) {
if (outLinks.size() == dis.size()) {
ignored.add(link.getId());
continue;
}

if (!diff.isEmpty()) {
if (!dis.isEmpty()) {
DisallowedNextLinks disallowed = new DisallowedNextLinks();
for (Id<Link> id : diff) {
for (Id<Link> id : dis) {

Set<Id<Link>> restricted = restrictions.computeIfAbsent(id, (k) -> new HashSet<>());

Link targetLink = network.getLinks().get(id);
Map<Id<Link>, ? extends Link> turnLinks = targetLink.getFromNode().getOutLinks();

// Ensure that a link is always reachable from at least one other link
if (turnLinks.size() - 1 <= restricted.size()) {
ignored.add(id);
continue;
}

restricted.add(link.getId());
disallowed.addDisallowedLinkSequence(TransportMode.car, List.of(id));
}

Expand All @@ -368,6 +375,9 @@ public SumoNetworkHandler convert(Network network) throws ParserConfigurationExc
}
}

// clean again (possibly with turn restrictions)
new NetworkCleaner().run(network);

if (!ignored.isEmpty()) {
log.warn("Ignored turn restrictions for {} links with no connections: {}", ignored.size(), ignored);
}
Expand Down

0 comments on commit 791f39b

Please sign in to comment.