MATSIM
SpeedyGraphBuilder.java
Go to the documentation of this file.
1 package org.matsim.core.router.speedy;
2 
3 import org.matsim.api.core.v01.Id;
9 
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collections;
13 import java.util.List;
14 
20 public class SpeedyGraphBuilder {
21 
22  private int nodeCount;
23  private int linkCount;
24  private int[] nodeData;
25  private int[] linkData;
26  private Link[] links;
27  private Node[] nodes;
28 
29  public static SpeedyGraph build(Network network) {
30  if (hasTurnRestrictions(network)) {
31  return new SpeedyGraphBuilder().buildWithTurnRestrictions(network);
32  }
34  }
35 
36  private static boolean hasTurnRestrictions(Network network) {
37  for (Link link : network.getLinks().values()) {
38  if (NetworkUtils.getDisallowedNextLinks(link) != null) {
39  return true;
40  }
41  }
42  return false;
43  }
44 
46 
48 
49  // create routing graph from context
50  this.nodeCount = context.getNodeCount();
51  this.linkCount = context.getLinkCount();
52 
53  this.nodeData = new int[this.nodeCount * SpeedyGraph.NODE_SIZE];
54  this.linkData = new int[this.linkCount * SpeedyGraph.LINK_SIZE];
55  this.links = new Link[this.linkCount];
56  this.nodes = new Node[this.nodeCount];
57 
58  Arrays.fill(this.nodeData, -1);
59  Arrays.fill(this.linkData, -1);
60 
61  for (Node node : network.getNodes().values()) {
62  this.nodes[node.getId().index()] = node;
63  }
64  List<Id<Link>> linkIds = new ArrayList<>(network.getLinks().keySet());
65  Collections.sort(linkIds);
66  for (Id<Link> linkId : linkIds) {
67  Link link = network.getLinks().get(linkId);
68  if (context.replacedLinks.get(link.getId()) == null) {
69  addLink(link);
70  }
71  }
72  for (TurnRestrictionsContext.ColoredNode node : context.coloredNodes) {
73  this.nodes[node.index()] = node.node();
74  }
75  for (TurnRestrictionsContext.ColoredLink link : context.coloredLinks) {
76  addLink(link);
77  }
78 
79  return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links, true);
80  }
81 
83  this.nodeCount = Id.getNumberOfIds(Node.class);
84  this.linkCount = Id.getNumberOfIds(Link.class);
85 
86  this.nodeData = new int[this.nodeCount * SpeedyGraph.NODE_SIZE];
87  this.linkData = new int[this.linkCount * SpeedyGraph.LINK_SIZE];
88  this.links = new Link[this.linkCount];
89  this.nodes = new Node[this.nodeCount];
90 
91  Arrays.fill(this.nodeData, -1);
92  Arrays.fill(this.linkData, -1);
93 
94  for (Node node : network.getNodes().values()) {
95  this.nodes[node.getId().index()] = node;
96  }
97  List<Id<Link>> linkIds = new ArrayList<>(network.getLinks().keySet());
98  Collections.sort(linkIds);
99  for (Id<Link> linkId : linkIds) {
100  Link link = network.getLinks().get(linkId);
101  addLink(link);
102  }
103 
104  return new SpeedyGraph(this.nodeData, this.linkData, this.nodes, this.links, false);
105  }
106 
107  private void addLink(Link link) {
108  int fromNodeIdx = link.getFromNode().getId().index();
109  int toNodeIdx = link.getToNode().getId().index();
110  int linkIdx = link.getId().index();
111 
112  int base = linkIdx * SpeedyGraph.LINK_SIZE;
113  this.linkData[base + 2] = fromNodeIdx;
114  this.linkData[base + 3] = toNodeIdx;
115  this.linkData[base + 4] = (int) Math.round(link.getLength() * 100.0);
116  this.linkData[base + 5] = (int) Math.round(link.getLength() / link.getFreespeed() * 100.0);
117 
118  setOutLink(fromNodeIdx, linkIdx);
119  setInLink(toNodeIdx, linkIdx);
120 
121  this.links[linkIdx] = link;
122  }
123 
125  int fromNodeIdx = -1;
126  int toNodeIdx = -1;
127  int linkIdx = link.index;
128 
129  if (link.fromColoredNode != null) {
130  fromNodeIdx = link.fromColoredNode.index();
131  }
132  if (link.fromNode != null) {
133  fromNodeIdx = link.fromNode.getId().index();
134  }
135  if (link.toColoredNode != null) {
136  toNodeIdx = link.toColoredNode.index();
137  }
138  if (link.toNode != null) {
139  toNodeIdx = link.toNode.getId().index();
140  }
141 
142  int base = linkIdx * SpeedyGraph.LINK_SIZE;
143  this.linkData[base + 2] = fromNodeIdx;
144  this.linkData[base + 3] = toNodeIdx;
145  this.linkData[base + 4] = (int) Math.round(link.link.getLength() * 100.0);
146  this.linkData[base + 5] = (int) Math.round(link.link.getLength() / link.link.getFreespeed() * 100.0);
147 
148  setOutLink(fromNodeIdx, linkIdx);
149  setInLink(toNodeIdx, linkIdx);
150 
151  this.links[linkIdx] = link.link;
152  }
153 
154  private void setOutLink(int fromNodeIdx, int linkIdx) {
155  final int nodeI = fromNodeIdx * SpeedyGraph.NODE_SIZE;
156  int outLinkIdx = this.nodeData[nodeI];
157  if (outLinkIdx < 0) {
158  this.nodeData[nodeI] = linkIdx;
159  return;
160  }
161  int lastLinkIdx;
162  do {
163  lastLinkIdx = outLinkIdx;
164  outLinkIdx = this.linkData[lastLinkIdx * SpeedyGraph.LINK_SIZE];
165  } while (outLinkIdx >= 0);
166  this.linkData[lastLinkIdx * SpeedyGraph.LINK_SIZE] = linkIdx;
167  }
168 
169  private void setInLink(int toNodeIdx, int linkIdx) {
170  final int nodeI = toNodeIdx * SpeedyGraph.NODE_SIZE + 1;
171  int inLinkIdx = this.nodeData[nodeI];
172  if (inLinkIdx < 0) {
173  this.nodeData[nodeI] = linkIdx;
174  return;
175  }
176  int lastLinkIdx;
177  do {
178  lastLinkIdx = inLinkIdx;
179  inLinkIdx = this.linkData[lastLinkIdx * SpeedyGraph.LINK_SIZE + 1];
180  } while (inLinkIdx >= 0);
181  this.linkData[lastLinkIdx * SpeedyGraph.LINK_SIZE + 1] = linkIdx;
182  }
183 }
static< T > int getNumberOfIds(final Class< T > type)
Definition: Id.java:122
static boolean hasTurnRestrictions(Network network)
Map< Id< Node >, ? extends Node > getNodes()
SpeedyGraph buildWithoutTurnRestrictions(Network network)
static DisallowedNextLinks getDisallowedNextLinks(Link link)
record ColoredNode(int index, Node node, List< ColoredLink > outLinks, List< ColoredLink > inLinks)
void addLink(TurnRestrictionsContext.ColoredLink link)
Map< Id< Link >, ? extends Link > getLinks()