MATSIM
TurnRestrictionsNetworkCleaner.java
Go to the documentation of this file.
1 package org.matsim.core.network.turnRestrictions;
2 
3 import com.google.common.base.Verify;
4 import org.matsim.api.core.v01.Id;
12 
13 import java.util.*;
14 import java.util.stream.Collectors;
15 
25 
26 
27  @Override
28  public void run(Network network) {
29  TurnRestrictionsContext turnRestrictions = TurnRestrictionsContext.build(network);
30  colorNetwork(network, turnRestrictions);
31  new NetworkCleaner().run(network);
32  collapseNetwork(network, turnRestrictions);
33  reapplyRestrictions(network, turnRestrictions);
34  }
35 
36 
37  public void colorNetwork(Network network, TurnRestrictionsContext turnRestrictions) {
38 
39  for (Link link : network.getLinks().values()) {
40  if (turnRestrictions.replacedLinks.containsKey(link.getId())) {
41  network.removeLink(link.getId());
42  }
43  }
44 
45  for (TurnRestrictionsContext.ColoredNode coloredNode : turnRestrictions.coloredNodes) {
46  Node coloredCopy = NetworkUtils.createNode(getColoredNodeId(coloredNode), coloredNode.node().getCoord());
47  network.addNode(coloredCopy);
48  coloredCopy.getAttributes().putAttribute("colored", coloredNode.node().getId());
49  }
50 
51  for (TurnRestrictionsContext.ColoredLink coloredLink : turnRestrictions.coloredLinks) {
52  Node fromNode;
53  if (coloredLink.fromColoredNode != null) {
54  fromNode = network.getNodes().get(getColoredNodeId(coloredLink.fromColoredNode));
55  } else {
56  fromNode = network.getNodes().get(coloredLink.fromNode.getId());
57  }
58 
59  Node toNode;
60  if (coloredLink.toColoredNode != null) {
61  toNode = network.getNodes().get(getColoredNodeId(coloredLink.toColoredNode));
62  } else {
63  toNode = network.getNodes().get(coloredLink.toNode.getId());
64  }
65 
66  Verify.verifyNotNull(fromNode);
67  Verify.verifyNotNull(toNode);
68 
69  Id<Link> linkId = getColoredLinkId(coloredLink);
71  linkId,
72  fromNode,
73  toNode,
74  network,
75  coloredLink.link.getLength(),
76  coloredLink.link.getFreespeed(),
77  coloredLink.link.getCapacity(),
78  coloredLink.link.getNumberOfLanes()
79  );
80  link.getAttributes().putAttribute("colored", coloredLink.link.getId());
81  network.addLink(link);
82  }
83  }
84 
85 
86  private void collapseNetwork(Network network, TurnRestrictionsContext turnRestrictions) {
87 
88  for (TurnRestrictionsContext.ColoredNode coloredNode : turnRestrictions.coloredNodes) {
89  Id<Node> nodeId = getColoredNodeId(coloredNode);
90  // colored node copy still present, but not the original
91  if (network.getNodes().containsKey(nodeId) && !network.getNodes().containsKey(coloredNode.node().getId())) {
92  Node nodeCopy = NetworkUtils.createNode(coloredNode.node().getId(), coloredNode.node().getCoord());
93  network.addNode(nodeCopy);
94  for (TurnRestrictionsContext.ColoredLink coloredLink : coloredNode.inLinks()) {
95  if (network.getLinks().containsKey(coloredLink.link.getId())) {
96  nodeCopy.addInLink(network.getLinks().get(coloredLink.link.getId()));
97  }
98  }
99  for (TurnRestrictionsContext.ColoredLink coloredLink : coloredNode.outLinks()) {
100  if (network.getLinks().containsKey(coloredLink.link.getId())) {
101  nodeCopy.addOutLink(network.getLinks().get(coloredLink.link.getId()));
102  }
103  }
104  }
105  }
106 
107  for (Map.Entry<Id<Link>, TurnRestrictionsContext.ColoredLink> idColoredLinkEntry : turnRestrictions.replacedLinks.entrySet()) {
108  TurnRestrictionsContext.ColoredLink coloredLink = idColoredLinkEntry.getValue();
109  checkRealLinkExistence(network, coloredLink);
110  }
111 
112  for (Map.Entry<Id<Link>, List<TurnRestrictionsContext.ColoredLink>> idColoredLinkEntry : turnRestrictions.coloredLinksPerLinkMap.entrySet()) {
113  for (TurnRestrictionsContext.ColoredLink coloredLink : idColoredLinkEntry.getValue()) {
114  checkRealLinkExistence(network, coloredLink);
115  }
116  }
117 
118  //remove colored nodes / links
119  for (TurnRestrictionsContext.ColoredNode coloredNode : turnRestrictions.coloredNodes) {
120  Id<Node> nodeId = Id.createNodeId(coloredNode.node().getId() + "_" + coloredNode.index());
121  network.removeNode(nodeId);
122  }
123 
124  for (TurnRestrictionsContext.ColoredLink coloredLink : turnRestrictions.coloredLinks) {
125  Id<Link> linkId = Id.createLinkId(coloredLink.link.getId() + "_" + coloredLink.index);
126  turnRestrictions.network.removeLink(linkId);
127  }
128  }
129 
131  Id<Link> copyId = getColoredLinkId(coloredLink);
132  if (network.getLinks().containsKey(copyId) && !network.getLinks().containsKey(coloredLink.link.getId())) {
133  Link link = coloredLink.link;
134  Link linkCopy = NetworkUtils.createLink(
135  link.getId(),
136  link.getFromNode(),
137  link.getToNode(),
138  network,
139  link.getLength(),
140  link.getFreespeed(),
141  link.getCapacity(),
142  link.getNumberOfLanes()
143  );
144  // copy all attributes except initial turn restrictions
145  NetworkUtils.copyAttributesExceptDisallowedNextLinks(coloredLink.link, linkCopy);
146  network.addLink(linkCopy);
147  }
148  }
149 
150  private void reapplyRestrictions(Network network, TurnRestrictionsContext turnRestrictions) {
151  for (Map.Entry<Id<Link>, TurnRestrictionsContext.ColoredLink> idColoredLinkEntry : turnRestrictions.replacedLinks.entrySet()) {
152  Link link = network.getLinks().get(idColoredLinkEntry.getValue().link.getId());
153  List<Id<Link>> currentPath = new ArrayList<>();
154  if (idColoredLinkEntry.getValue().toNode != null) {
155  throw new RuntimeException("Shouldn't happen");
156  } else {
157  advance(idColoredLinkEntry.getValue(), currentPath, link, network, turnRestrictions);
158  }
159  }
160  }
161 
162  private void advance(TurnRestrictionsContext.ColoredLink coloredLink, List<Id<Link>> currentPath,
163  Link replacedStartLink, Network network, TurnRestrictionsContext turnRestrictions) {
164 
165  if (!network.getLinks().containsKey(coloredLink.link.getId())) {
166  // link sequence is not part of the network anymore and doesn't need to be explored.
167  return;
168  }
169 
170  if (coloredLink.toColoredNode != null) {
171  Node node = coloredLink.toColoredNode.node();
172 
173  // set of reachable links from the original node
174  // use id, as the link object may have been deleted and re-inserted as a copy during the process
175  Set<Id<Link>> unrestrictedReachableLinks = new HashSet<>(node.getOutLinks().values()
176  .stream()
177  .map(Identifiable::getId)
178  .filter(link -> network.getLinks().containsKey(link))
179  .collect(Collectors.toSet()));
180 
181 
182  List<TurnRestrictionsContext.ColoredLink> toAdvance = new ArrayList<>();
183  for (TurnRestrictionsContext.ColoredLink outLink : coloredLink.toColoredNode.outLinks()) {
184  // remove from the set all links that are also reachable from within the colored subgraph
185  unrestrictedReachableLinks.remove(outLink.link.getId());
186  if (outLink.toColoredNode != null) {
187  toAdvance.add(outLink);
188  }
189  }
190 
191  // any remaining link is _not_ reachable from within the colored subgraph
192  // -> there must be a turn restriction from the current start link across the path
193  if (!unrestrictedReachableLinks.isEmpty()) {
194  DisallowedNextLinks disallowedNextLinks = NetworkUtils.getOrCreateDisallowedNextLinks(replacedStartLink);
195  for (Id<Link> unrestrictedReachableLink : unrestrictedReachableLinks) {
196  List<Id<Link>> path = new ArrayList<>(currentPath);
197  path.add(unrestrictedReachableLink);
198  disallowedNextLinks.addDisallowedLinkSequence("car", path);
199  }
200  }
201 
202  for (TurnRestrictionsContext.ColoredLink link : toAdvance) {
203  List<Id<Link>> nextPath = new ArrayList<>(currentPath);
204  nextPath.add(link.link.getId());
205  if (turnRestrictions.replacedLinks.containsKey(link.link.getId())) {
206  return;
207  }
208  advance(link, nextPath, replacedStartLink, network, turnRestrictions);
209  }
210  }
211  }
212 
214  return Id.createNodeId(coloredNode.node().getId() + "_" + coloredNode.index());
215  }
216 
218  return Id.createLinkId(coloredLink.link.getId() + "_" + coloredLink.index);
219  }
220 }
void collapseNetwork(Network network, TurnRestrictionsContext turnRestrictions)
static DisallowedNextLinks getOrCreateDisallowedNextLinks(Link link)
Map< Id< Node >, ? extends Node > getNodes()
Link removeLink(final Id< Link > linkId)
Node removeNode(final Id< Node > nodeId)
static Id< Link > createLinkId(final long key)
Definition: Id.java:202
static Link createLink(Id< Link > id, Node from, Node to, Network network, double length, double freespeed, double capacity, double lanes)
Id< Link > getColoredLinkId(TurnRestrictionsContext.ColoredLink coloredLink)
void advance(TurnRestrictionsContext.ColoredLink coloredLink, List< Id< Link >> currentPath, Link replacedStartLink, Network network, TurnRestrictionsContext turnRestrictions)
void checkRealLinkExistence(Network network, TurnRestrictionsContext.ColoredLink coloredLink)
record ColoredNode(int index, Node node, List< ColoredLink > outLinks, List< ColoredLink > inLinks)
Object putAttribute(final String attribute, final Object value)
void reapplyRestrictions(Network network, TurnRestrictionsContext turnRestrictions)
Id< Node > getColoredNodeId(TurnRestrictionsContext.ColoredNode coloredNode)
Map< Id< Link >, ? extends Link > getLinks()
static void copyAttributesExceptDisallowedNextLinks(Link from, Link to)
Map< Id< Link >, ? extends Link > getOutLinks()
static Node createNode(Id< Node > id)
void colorNetwork(Network network, TurnRestrictionsContext turnRestrictions)
static Id< Node > createNodeId(final long key)
Definition: Id.java:211