use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class ViaRouting method lookup.
/**
* @throws MultiplePointsNotFoundException in case one or more points could not be resolved
*/
public static List<Snap> lookup(EncodedValueLookup lookup, List<GHPoint> points, EdgeFilter snapFilter, LocationIndex locationIndex, List<String> snapPreventions, List<String> pointHints, DirectedEdgeFilter directedSnapFilter, List<Double> headings) {
if (points.size() < 2)
throw new IllegalArgumentException("At least 2 points have to be specified, but was:" + points.size());
final EnumEncodedValue<RoadClass> roadClassEnc = lookup.getEnumEncodedValue(RoadClass.KEY, RoadClass.class);
final EnumEncodedValue<RoadEnvironment> roadEnvEnc = lookup.getEnumEncodedValue(RoadEnvironment.KEY, RoadEnvironment.class);
EdgeFilter strictEdgeFilter = snapPreventions.isEmpty() ? snapFilter : new SnapPreventionEdgeFilter(snapFilter, roadClassEnc, roadEnvEnc, snapPreventions);
List<Snap> snaps = new ArrayList<>(points.size());
IntArrayList pointsNotFound = new IntArrayList();
for (int placeIndex = 0; placeIndex < points.size(); placeIndex++) {
GHPoint point = points.get(placeIndex);
Snap snap = null;
if (placeIndex < headings.size() && !Double.isNaN(headings.get(placeIndex))) {
if (!pointHints.isEmpty() && !Helper.isEmpty(pointHints.get(placeIndex)))
throw new IllegalArgumentException("Cannot specify heading and point_hint at the same time. " + "Make sure you specify either an empty point_hint (String) or a NaN heading (double) for point " + placeIndex);
snap = locationIndex.findClosest(point.lat, point.lon, new HeadingEdgeFilter(directedSnapFilter, headings.get(placeIndex), point));
} else if (!pointHints.isEmpty()) {
snap = locationIndex.findClosest(point.lat, point.lon, new NameSimilarityEdgeFilter(strictEdgeFilter, pointHints.get(placeIndex), point, 100));
} else if (!snapPreventions.isEmpty()) {
snap = locationIndex.findClosest(point.lat, point.lon, strictEdgeFilter);
}
if (snap == null || !snap.isValid())
snap = locationIndex.findClosest(point.lat, point.lon, snapFilter);
if (!snap.isValid())
pointsNotFound.add(placeIndex);
snaps.add(snap);
}
if (!pointsNotFound.isEmpty())
throw new MultiplePointsNotFoundException(pointsNotFound);
return snaps;
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class LandmarkStorage method createLandmarks.
/**
* This method calculates the landmarks and initial weightings to & from them.
*/
public void createLandmarks() {
if (isInitialized())
throw new IllegalStateException("Initialize the landmark storage only once!");
// fill 'from' and 'to' weights with maximum value
long maxBytes = (long) graph.getNodes() * LM_ROW_LENGTH;
this.landmarkWeightDA.create(2000);
this.landmarkWeightDA.ensureCapacity(maxBytes);
for (long pointer = 0; pointer < maxBytes; pointer += 2) {
landmarkWeightDA.setShort(pointer, (short) SHORT_INFINITY);
}
int[] empty = new int[landmarks];
Arrays.fill(empty, UNSET_SUBNETWORK);
landmarkIDs.add(empty);
byte[] subnetworks = new byte[graph.getNodes()];
Arrays.fill(subnetworks, (byte) UNSET_SUBNETWORK);
String snKey = Subnetwork.key(lmConfig.getName());
// instead of using the subnetworkEnc from PrepareRoutingSubnetworks.
if (!graph.getEncodingManager().hasEncodedValue(snKey))
throw new IllegalArgumentException("EncodedValue '" + snKey + "' does not exist. For Landmarks this is " + "currently required (also used in PrepareRoutingSubnetworks). See #2256");
// Exclude edges that we previously marked in PrepareRoutingSubnetworks to avoid problems like "connection not found".
final BooleanEncodedValue edgeInSubnetworkEnc = graph.getEncodingManager().getBooleanEncodedValue(snKey);
final IntHashSet blockedEdges;
// landmarks for an area like Europe+Asia, which improves the query speed.
if (areaIndex != null) {
StopWatch sw = new StopWatch().start();
blockedEdges = findBorderEdgeIds(areaIndex);
if (logDetails)
LOGGER.info("Made " + blockedEdges.size() + " edges inaccessible. Calculated country cut in " + sw.stop().getSeconds() + "s, " + Helper.getMemInfo());
} else {
blockedEdges = new IntHashSet();
}
EdgeFilter accessFilter = edge -> !edge.get(edgeInSubnetworkEnc) && !blockedEdges.contains(edge.getEdge());
EdgeFilter tarjanFilter = edge -> accessFilter.accept(edge) && Double.isFinite(weighting.calcEdgeWeightWithAccess(edge, false));
StopWatch sw = new StopWatch().start();
ConnectedComponents graphComponents = TarjanSCC.findComponents(graph, tarjanFilter, true);
if (logDetails)
LOGGER.info("Calculated " + graphComponents.getComponents().size() + " subnetworks via tarjan in " + sw.stop().getSeconds() + "s, " + Helper.getMemInfo());
String additionalInfo = "";
// guess the factor
if (factor <= 0) {
// A 'factor' is necessary to store the weight in just a short value but without losing too much precision.
// This factor is rather delicate to pick, we estimate it from an exploration with some "test landmarks",
// see estimateMaxWeight. If we pick the distance too big for small areas this could lead to (slightly)
// suboptimal routes as there will be too big rounding errors. But picking it too small is bad for performance
// e.g. for Germany at least 1500km is very important otherwise speed is at least twice as slow e.g. for 1000km
double maxWeight = estimateMaxWeight(graphComponents.getComponents(), accessFilter);
setMaximumWeight(maxWeight);
additionalInfo = ", maxWeight:" + maxWeight + " from quick estimation";
}
if (logDetails)
LOGGER.info("init landmarks for subnetworks with node count greater than " + minimumNodes + " with factor:" + factor + additionalInfo);
int nodes = 0;
for (IntArrayList subnetworkIds : graphComponents.getComponents()) {
nodes += subnetworkIds.size();
if (subnetworkIds.size() < minimumNodes)
continue;
if (factor <= 0)
throw new IllegalStateException("factor wasn't initialized " + factor + ", subnetworks:" + graphComponents.getComponents().size() + ", minimumNodes:" + minimumNodes + ", current size:" + subnetworkIds.size());
int index = subnetworkIds.size() - 1;
// ensure start node is reachable from both sides and no subnetwork is associated
for (; index >= 0; index--) {
int nextStartNode = subnetworkIds.get(index);
if (subnetworks[nextStartNode] == UNSET_SUBNETWORK) {
if (logDetails) {
GHPoint p = createPoint(graph, nextStartNode);
LOGGER.info("start node: " + nextStartNode + " (" + p + ") subnetwork " + index + ", subnetwork size: " + subnetworkIds.size() + ", " + Helper.getMemInfo() + ((areaIndex == null) ? "" : " area:" + areaIndex.query(p.lat, p.lon)));
}
if (createLandmarksForSubnetwork(nextStartNode, subnetworks, accessFilter))
break;
}
}
if (index < 0)
LOGGER.warn("next start node not found in big enough network of size " + subnetworkIds.size() + ", first element is " + subnetworkIds.get(0) + ", " + createPoint(graph, subnetworkIds.get(0)));
}
int subnetworkCount = landmarkIDs.size();
// store all landmark node IDs and one int for the factor itself.
this.landmarkWeightDA.ensureCapacity(maxBytes + /* landmark weights */
subnetworkCount * landmarks);
// calculate offset to point into landmark mapping
long bytePos = maxBytes;
for (int[] landmarks : landmarkIDs) {
for (int lmNodeId : landmarks) {
landmarkWeightDA.setInt(bytePos, lmNodeId);
bytePos += 4L;
}
}
landmarkWeightDA.setHeader(0 * 4, graph.getNodes());
landmarkWeightDA.setHeader(1 * 4, landmarks);
landmarkWeightDA.setHeader(2 * 4, subnetworkCount);
if (factor * DOUBLE_MLTPL > Integer.MAX_VALUE)
throw new UnsupportedOperationException("landmark weight factor cannot be bigger than Integer.MAX_VALUE " + factor * DOUBLE_MLTPL);
landmarkWeightDA.setHeader(3 * 4, (int) Math.round(factor * DOUBLE_MLTPL));
// serialize fast byte[] into DataAccess
subnetworkStorage.create(graph.getNodes());
for (int nodeId = 0; nodeId < subnetworks.length; nodeId++) {
subnetworkStorage.setSubnetwork(nodeId, subnetworks[nodeId]);
}
if (logDetails)
LOGGER.info("Finished landmark creation. Subnetwork node count sum " + nodes + " vs. nodes " + graph.getNodes());
initialized = true;
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class EdgeChangeBuilder method addRemovedEdges.
/**
* Adds the ids of the removed edges at the real tower nodes. We need to do this such that we cannot 'skip'
* virtual nodes by just using the original edges and also to prevent u-turns at the real nodes adjacent to the
* virtual ones.
*/
private void addRemovedEdges(int towerNode) {
if (isVirtualNode(towerNode))
throw new IllegalStateException("Node should not be virtual:" + towerNode + ", " + edgeChangesAtRealNodes);
QueryOverlay.EdgeChanges edgeChanges = edgeChangesAtRealNodes.get(towerNode);
List<EdgeIteratorState> existingEdges = edgeChanges.getAdditionalEdges();
IntArrayList removedEdges = edgeChanges.getRemovedEdges();
for (EdgeIteratorState existingEdge : existingEdges) {
removedEdges.add(getClosestEdge(existingEdge.getAdjNode()));
}
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class HeadingResolver method getEdgesWithDifferentHeading.
/**
* Returns a list of edge IDs of edges adjacent to the given base node that do *not* have the same or a similar
* heading as the given heading. If for example the tolerance is 45 degrees this method returns all edges for which
* the absolute difference to the given heading is greater than 45 degrees. The heading of an edge is defined as
* the direction of the first segment of an edge (adjacent and facing away from the base node).
*
* @param heading north based azimuth, between 0 and 360 degrees
* @see #setTolerance
*/
public IntArrayList getEdgesWithDifferentHeading(int baseNode, double heading) {
double xAxisAngle = AngleCalc.ANGLE_CALC.convertAzimuth2xaxisAngle(heading);
IntArrayList edges = new IntArrayList(1);
EdgeIterator iter = edgeExplorer.setBaseNode(baseNode);
while (iter.next()) {
PointList points = iter.fetchWayGeometry(FetchMode.ALL);
double orientation = AngleCalc.ANGLE_CALC.calcOrientation(points.getLat(0), points.getLon(0), points.getLat(1), points.getLon(1));
orientation = AngleCalc.ANGLE_CALC.alignOrientation(xAxisAngle, orientation);
double diff = Math.abs(orientation - xAxisAngle);
if (diff > toleranceRad)
edges.add(iter.getEdge());
}
return edges;
}
use of com.carrotsearch.hppc.IntArrayList in project graphhopper by graphhopper.
the class EdgeBasedWitnessPathSearcher method initCollections.
private void initCollections() {
changedEdges = new IntArrayList(1000);
dijkstraHeap = new IntFloatBinaryHeap(1000);
}
Aggregations