MATSIM
HeavyCompressedNetworkRoute.java
Go to the documentation of this file.
1 package org.matsim.core.population.routes.heavycompressed;
2 
3 import org.matsim.api.core.v01.Id;
8 
9 import java.util.ArrayList;
10 import java.util.HashSet;
11 import java.util.List;
12 import java.util.Set;
13 
35 
36  private final static byte[] EMPTY_ROUTE = new byte[0];
37 
38  private final HeavyCompressedNetworkRouteFactory.CompressionData compressionData;
39  private int uncompressedLength = -1;
40  private byte[] route = EMPTY_ROUTE;
41 
44  this.setStartLinkId(startLinkId);
45  this.setEndLinkId(endLinkId);
46  }
47 
48  @Override
50  return (HeavyCompressedNetworkRoute) super.clone();
51  }
52 
53  @Override
54  public List<Id<Link>> getLinkIds() {
55  if (this.uncompressedLength < 0) { // it seems the route never got initialized correctly
56  return new ArrayList<>(0);
57  }
58  ArrayList<Id<Link>> links = new ArrayList<>(this.uncompressedLength);
59  Id<Link> previousLinkId = getStartLinkId();
60  Id<Link> endLinkId = getEndLinkId();
61  if ((previousLinkId == null) || (endLinkId == null)) {
62  return links;
63  }
64  if (previousLinkId.equals(endLinkId) && this.uncompressedLength == 0) {
65  return links;
66  }
67  int[] route = VarIntUtils.decode(this.route);
68  for (int linkIndex : route) {
69  Id<Link> linkId = Id.get(linkIndex, Link.class);
70  getLinksTillLink(links, linkId, previousLinkId);
71  links.add(linkId);
72  previousLinkId = linkId;
73  }
74  getLinksTillLink(links, endLinkId, previousLinkId);
75 
76  return links;
77  }
78 
79  private void getLinksTillLink(final List<Id<Link>> links, final Id<Link> nextLinkId, final Id<Link> startLinkId) {
80  Link[] allLinks = this.compressionData.links();
81  Link[] subsequentLinks = this.compressionData.subsequentLinks();
82  Id<Link> linkId = startLinkId;
83  Link nextLink = allLinks[nextLinkId.index()];
84  while (true) { // loop until we hit "return;"
85  Link link = allLinks[linkId.index()];
86  if (link.getToNode() == nextLink.getFromNode()) {
87  return;
88  }
89  linkId = subsequentLinks[linkId.index()].getId();
90  links.add(linkId);
91  }
92  }
93 
94  @Override
95  public void setLinkIds(final Id<Link> startLinkId, final List<Id<Link>> srcRoute, final Id<Link> endLinkId) {
96  Link[] subsequentLinks = this.compressionData.subsequentLinks();
97  Link[] links = this.compressionData.links();
98 
99  Set<Id<Node>> visitedNodes = new HashSet<>();
100  Set<Id<Node>> multiplyVisitedNodes = new HashSet<>();
101  setStartLinkId(startLinkId);
102  setEndLinkId(endLinkId);
103  if ((srcRoute == null) || (srcRoute.size() == 0)) {
104  this.uncompressedLength = 0;
105  return;
106  }
107 
108  int pos = 0;
109  int[] route = new int[srcRoute.size()];
110  // compress route
111  Id<Link> previousLinkId = startLinkId;
112  for (Id<Link> linkId : srcRoute) {
113  Link link = links[linkId.index()];
114  Id<Node> fromNodeId = link.getFromNode().getId();
115  if (!visitedNodes.add(fromNodeId)) {
116  // the node was already visited
117  multiplyVisitedNodes.add(fromNodeId);
118  }
119  if (!subsequentLinks[previousLinkId.index()].getId().equals(linkId)) {
120  route[pos] = linkId.index();
121  pos++;
122  }
123  previousLinkId = linkId;
124  }
125  Link endLink = links[endLinkId.index()];
126  Id<Node> fromNodeId = endLink.getFromNode().getId();
127  if (!visitedNodes.add(fromNodeId)) {
128  // the node was already visited
129  multiplyVisitedNodes.add(fromNodeId);
130  }
131 
132  if (!multiplyVisitedNodes.isEmpty()) {
133  // the route contains at least one loop, we need to re-encode it and make sure
134  // that no loop is left out when reconstructing the uncompressed route
135  pos = 0;
136  previousLinkId = startLinkId;
137  for (Id<Link> linkId : srcRoute) {
138  Link link = links[linkId.index()];
139  fromNodeId = link.getFromNode().getId();
140  if (!subsequentLinks[previousLinkId.index()].getId().equals(linkId) || multiplyVisitedNodes.contains(fromNodeId)) {
141  route[pos] = linkId.index();
142  pos++;
143  }
144  previousLinkId = linkId;
145  }
146  }
147 
148  this.route = VarIntUtils.encode(route, 0, pos);
149  this.uncompressedLength = srcRoute.size();
150  }
151 
152 }
static< T > Id< T > get(int index, final Class< T > type)
Definition: Id.java:112
void getLinksTillLink(final List< Id< Link >> links, final Id< Link > nextLinkId, final Id< Link > startLinkId)
void setLinkIds(final Id< Link > startLinkId, final List< Id< Link >> srcRoute, final Id< Link > endLinkId)
HeavyCompressedNetworkRoute(Id< Link > startLinkId, Id< Link > endLinkId, HeavyCompressedNetworkRouteFactory.CompressionData compressionData)