use of com.graphhopper.coll.GHIntHashSet in project graphhopper by graphhopper.
the class LocationIndexTreeCHTest method testCHGraphBug.
@Test
public void testCHGraphBug() {
// 0
// |
// | X 2--3
// |
// 1
GraphHopperStorage g = createGHStorage(new RAMDirectory(), encodingManager, false);
NodeAccess na = g.getNodeAccess();
na.setNode(0, 1, 0);
na.setNode(1, 0, 0);
na.setNode(2, 0.5, 0.5);
na.setNode(3, 0.5, 1);
EdgeIteratorState iter1 = g.edge(1, 0, 100, true);
g.edge(2, 3, 100, true);
CHGraphImpl lg = (CHGraphImpl) g.getGraph(CHGraph.class);
g.freeze();
lg.setLevel(0, 11);
lg.setLevel(1, 10);
// disconnect higher 0 from lower 1
lg.disconnect(lg.createEdgeExplorer(), iter1);
lg.setLevel(2, 12);
lg.setLevel(3, 13);
// disconnect higher 3 from lower 2
lg.disconnect(lg.createEdgeExplorer(), iter1);
LocationIndexTree index = createIndex(g, 100000);
// very close to 2, but should match the edge 0--1
GHIntHashSet set = new GHIntHashSet();
index.findNetworkEntries(0.51, 0.2, set, 0);
index.findNetworkEntries(0.51, 0.2, set, 1);
IntSet expectedSet = new GHIntHashSet();
expectedSet.add(0);
expectedSet.add(2);
assertEquals(expectedSet, set);
assertEquals(0, findID(index, 0.51, 0.2));
assertEquals(1, findID(index, 0.1, 0.1));
assertEquals(2, findID(index, 0.51, 0.51));
assertEquals(3, findID(index, 0.51, 1.1));
}
use of com.graphhopper.coll.GHIntHashSet in project graphhopper by graphhopper.
the class GenericWeightingTest method testBlockedById.
@Test
public void testBlockedById() {
EdgeIteratorState edge = graph.getEdgeIteratorState(0, 1);
ConfigMap cMap = encoder.readStringMap(new PMap());
Weighting instance = new GenericWeighting(encoder, cMap);
assertEquals(edgeWeight, instance.calcWeight(edge, false, EdgeIterator.NO_EDGE), 1e-8);
GHIntHashSet blockedEdges = new GHIntHashSet(1);
cMap.put(BLOCKED_EDGES, blockedEdges);
blockedEdges.add(0);
instance = new GenericWeighting(encoder, cMap);
assertEquals(Double.POSITIVE_INFINITY, instance.calcWeight(edge, false, EdgeIterator.NO_EDGE), 1e-8);
}
use of com.graphhopper.coll.GHIntHashSet in project graphhopper by graphhopper.
the class LocationIndexTreeTest method testInMemIndex.
@Test
public void testInMemIndex() {
Graph graph = createTestGraph(encodingManager);
LocationIndexTree index = createIndexNoPrepare(graph, 50000);
index.prepareAlgo();
LocationIndexTree.InMemConstructionIndex inMemIndex = index.getPrepareInMemIndex();
assertEquals(Helper.createTList(4, 4), index.getEntries());
assertEquals(4, inMemIndex.getEntriesOf(0).size());
assertEquals(10, inMemIndex.getEntriesOf(1).size());
assertEquals(0, inMemIndex.getEntriesOf(2).size());
// [LEAF 0 {} {0, 2}, LEAF 2 {} {0, 1}, LEAF 1 {} {2}, LEAF 3 {} {1}, LEAF 8 {} {0}, LEAF 10 {} {0}, LEAF 9 {} {0}, LEAF 4 {} {2}, LEAF 6 {} {0, 1, 2, 3}, LEAF 5 {} {0, 2, 3}, LEAF 7 {} {1, 2, 3}, LEAF 13 {} {1}]
// System.out.println(inMemIndex.getLayer(2));
index.dataAccess.create(10);
inMemIndex.store(inMemIndex.root, LocationIndexTree.START_POINTER);
// [LEAF 0 {2} {}, LEAF 2 {1} {}, LEAF 1 {2} {}, LEAF 3 {1} {}, LEAF 8 {0} {}, LEAF 10 {0} {}, LEAF 9 {0} {}, LEAF 4 {2} {}, LEAF 6 {0, 3} {}, LEAF 5 {0, 2, 3} {}, LEAF 7 {1, 2, 3} {}, LEAF 13 {1} {}]
// System.out.println(inMemIndex.getLayer(2));
GHIntHashSet set = new GHIntHashSet();
set.add(0);
GHIntHashSet foundIds = new GHIntHashSet();
index.findNetworkEntries(0.5, -0.5, foundIds, 0);
assertEquals(set, foundIds);
set.add(1);
set.add(2);
foundIds.clear();
index.findNetworkEntries(-0.5, -0.9, foundIds, 0);
index.findNetworkEntries(-0.5, -0.9, foundIds, 1);
assertEquals(set, foundIds);
assertEquals(2, findID(index, -0.5, -0.9));
// The optimization if(dist > normedHalf) => feed nodeA or nodeB
// although this reduces chance of nodes outside of the tile
// in practice it even increases file size!?
// Is this due to the CHGraph disconnect problem?
// set.clear();
// set.add(4);
// assertEquals(set, index.findNetworkEntries(-0.7, 1.5));
//
// set.clear();
// set.add(4);
// assertEquals(set, index.findNetworkEntries(-0.5, 0.5));
}
use of com.graphhopper.coll.GHIntHashSet in project graphhopper by graphhopper.
the class LocationIndexTreeTest method testRMin.
@Test
public void testRMin() {
Graph graph = createTestGraph(encodingManager);
LocationIndexTree index = createIndex(graph, 50000);
// query: 0.05 | -0.3
DistanceCalc distCalc = new DistancePlaneProjection();
double rmin = index.calculateRMin(0.05, -0.3);
double check = distCalc.calcDist(0.05, Math.abs(graph.getNodeAccess().getLon(2)) - index.getDeltaLon(), -0.3, -0.3);
assertTrue((rmin - check) < 0.0001);
double rmin2 = index.calculateRMin(0.05, -0.3, 1);
double check2 = distCalc.calcDist(0.05, Math.abs(graph.getNodeAccess().getLat(0)), -0.3, -0.3);
assertTrue((rmin2 - check2) < 0.0001);
GHIntHashSet points = new GHIntHashSet();
assertEquals(Double.MAX_VALUE, index.calcMinDistance(0.05, -0.3, points), 1e-1);
points.add(0);
points.add(1);
assertEquals(54757.03, index.calcMinDistance(0.05, -0.3, points), 1e-1);
/*GraphVisualizer gv = new GraphVisualizer(graph, index.getDeltaLat(), index.getDeltaLon(), index.getCenter(0, 0).lat, index.getCenter(0, 0).lon);
try {
Thread.sleep(4000);
} catch(InterruptedException ie) {}*/
}
use of com.graphhopper.coll.GHIntHashSet in project graphhopper by graphhopper.
the class LocationIndexTree method findNClosest.
/**
* Returns all edges that are within the specified radius around the queried position.
* Searches at most 9 cells to avoid performance problems. Hence, if the radius is larger than
* the cell width then not all edges might be returned.
*
* TODO: either clarify the method name and description (to only search e.g. 9 tiles) or
* refactor so it can handle a radius larger than 9 tiles. Also remove reference to 'NClosest',
* which is misleading, and don't always return at least one value. See map-matching #65.
* TODO: tidy up logic - see comments in graphhopper #994.
*
* @param radius in meters
*/
public List<QueryResult> findNClosest(final double queryLat, final double queryLon, final EdgeFilter edgeFilter, double radius) {
// Return ALL results which are very close and e.g. within the GPS signal accuracy.
// Also important to get all edges if GPS point is close to a junction.
final double returnAllResultsWithin = distCalc.calcNormalizedDist(radius);
// implement a cheap priority queue via List, sublist and Collections.sort
final List<QueryResult> queryResults = new ArrayList<QueryResult>();
GHIntHashSet set = new GHIntHashSet();
// Doing 2 iterations means searching 9 tiles.
for (int iteration = 0; iteration < 2; iteration++) {
// should we use the return value of earlyFinish?
findNetworkEntries(queryLat, queryLon, set, iteration);
final GHBitSet exploredNodes = new GHTBitSet(new GHIntHashSet(set));
final EdgeExplorer explorer = graph.createEdgeExplorer(edgeFilter);
set.forEach(new IntPredicate() {
@Override
public boolean apply(int node) {
new XFirstSearchCheck(queryLat, queryLon, exploredNodes, edgeFilter) {
@Override
protected double getQueryDistance() {
// do not skip search if distance is 0 or near zero (equalNormedDelta)
return Double.MAX_VALUE;
}
@Override
protected boolean check(int node, double normedDist, int wayIndex, EdgeIteratorState edge, QueryResult.Position pos) {
if (normedDist < returnAllResultsWithin || queryResults.isEmpty() || queryResults.get(0).getQueryDistance() > normedDist) {
// TODO: refactor below:
// - should only add edges within search radius (below allows the
// returning of a candidate outside search radius if it's the only
// one). Removing this test would simplify it a lot and probably
// match the expected behaviour (see method description)
// - create QueryResult first and the add/set as required - clean up
// the index tracking business.
int index = -1;
for (int qrIndex = 0; qrIndex < queryResults.size(); qrIndex++) {
QueryResult qr = queryResults.get(qrIndex);
// overwrite older queryResults which are potentially more far away than returnAllResultsWithin
if (qr.getQueryDistance() > returnAllResultsWithin) {
index = qrIndex;
break;
}
// avoid duplicate edges
if (qr.getClosestEdge().getEdge() == edge.getEdge()) {
if (qr.getQueryDistance() < normedDist) {
// do not add current edge
return true;
} else {
// overwrite old edge with current
index = qrIndex;
break;
}
}
}
QueryResult qr = new QueryResult(queryLat, queryLon);
qr.setQueryDistance(normedDist);
qr.setClosestNode(node);
qr.setClosestEdge(edge.detach(false));
qr.setWayIndex(wayIndex);
qr.setSnappedPosition(pos);
if (index < 0) {
queryResults.add(qr);
} else {
queryResults.set(index, qr);
}
}
return true;
}
}.start(explorer, node);
return true;
}
});
}
// TODO: pass boolean argument for whether or not to sort? Can be expensive if not required.
Collections.sort(queryResults, QR_COMPARATOR);
for (QueryResult qr : queryResults) {
if (qr.isValid()) {
// denormalize distance
qr.setQueryDistance(distCalc.calcDenormalizedDist(qr.getQueryDistance()));
qr.calcSnappedPoint(distCalc);
} else {
throw new IllegalStateException("Invalid QueryResult should not happen here: " + qr);
}
}
return queryResults;
}
Aggregations