Skip to content

Commit 4be9ffc

Browse files
authored
Allow querying for arbitrary geometry in location index (graphhopper#2890)
1 parent d2b8596 commit 4be9ffc

File tree

3 files changed

+47
-9
lines changed

3 files changed

+47
-9
lines changed

core/src/main/java/com/graphhopper/storage/index/LineIntIndex.java

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,12 @@ private void fillIDs(long keyPart, IntConsumer consumer) {
159159
}
160160

161161
public void query(BBox queryShape, final LocationIndex.Visitor function) {
162+
query(LocationIndex.createBBoxTileFilter(queryShape), function);
163+
}
164+
165+
public void query(LocationIndex.TileFilter tileFilter, final LocationIndex.Visitor function) {
162166
final IntHashSet set = new IntHashSet();
163-
query(START_POINTER, queryShape,
167+
query(START_POINTER, tileFilter,
164168
bounds.minLat, bounds.minLon, bounds.maxLat - bounds.minLat, bounds.maxLon - bounds.minLon,
165169
new LocationIndex.Visitor() {
166170
@Override
@@ -181,7 +185,7 @@ public void onEdge(int edgeId) {
181185
}, 0);
182186
}
183187

184-
private void query(int intPointer, BBox queryBBox,
188+
private void query(int intPointer, LocationIndex.TileFilter tileFilter,
185189
double minLat, double minLon,
186190
double deltaLatPerDepth, double deltaLonPerDepth,
187191
LocationIndex.Visitor function, int depth) {
@@ -213,14 +217,14 @@ private void query(int intPointer, BBox queryBBox,
213217
double tmpMinLon = minLon + deltaLonPerDepth * pixelXY[0];
214218
double tmpMinLat = minLat + deltaLatPerDepth * pixelXY[1];
215219

216-
BBox bbox = (queryBBox != null || function.isTileInfo()) ? new BBox(tmpMinLon, tmpMinLon + deltaLonPerDepth, tmpMinLat, tmpMinLat + deltaLatPerDepth) : null;
220+
BBox bbox = (tileFilter != null || function.isTileInfo()) ? new BBox(tmpMinLon, tmpMinLon + deltaLonPerDepth, tmpMinLat, tmpMinLat + deltaLatPerDepth) : null;
217221
if (function.isTileInfo())
218222
function.onTile(bbox, depth);
219-
if (queryBBox == null || queryBBox.contains(bbox)) {
223+
if (tileFilter == null || tileFilter.acceptAll(bbox)) {
220224
// fill without a restriction!
221225
query(nextIntPointer, null, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
222-
} else if (queryBBox.intersects(bbox)) {
223-
query(nextIntPointer, queryBBox, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
226+
} else if (tileFilter.acceptPartially(bbox)) {
227+
query(nextIntPointer, tileFilter, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
224228
}
225229
}
226230
}

core/src/main/java/com/graphhopper/storage/index/LocationIndex.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,44 @@ public interface LocationIndex {
5151
* and limited by the queryBBox. Also (a few) more edges slightly outside of queryBBox could be
5252
* returned that you can avoid via doing an explicit BBox check of the coordinates.
5353
*/
54-
void query(BBox queryBBox, Visitor function);
54+
default void query(BBox queryBBox, Visitor function) {
55+
query(createBBoxTileFilter(queryBBox), function);
56+
}
57+
58+
void query(TileFilter tileFilter, Visitor function);
5559

5660
void close();
5761

62+
63+
interface TileFilter {
64+
65+
/**
66+
* @return true if all edges within the given bounding box shall be accepted
67+
*/
68+
boolean acceptAll(BBox tile);
69+
70+
/**
71+
* @return true if edges within the given bounding box shall potentially be accepted. In this
72+
* case the tile filter will be applied again for smaller bounding boxes on a lower level.
73+
* If this is the lowest level already simply all edges will be accepted.
74+
*/
75+
boolean acceptPartially(BBox tile);
76+
}
77+
78+
static TileFilter createBBoxTileFilter(BBox queryBBox) {
79+
return queryBBox == null ? null : new TileFilter() {
80+
@Override
81+
public boolean acceptAll(BBox tile) {
82+
return queryBBox.contains(tile);
83+
}
84+
85+
@Override
86+
public boolean acceptPartially(BBox tile) {
87+
return queryBBox.intersects(tile);
88+
}
89+
};
90+
}
91+
5892
/**
5993
* This interface allows to visit edges stored in the LocationIndex.
6094
*/

core/src/main/java/com/graphhopper/storage/index/LocationIndexTree.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,8 +309,8 @@ public Snap findClosest(final double queryLat, final double queryLon, final Edge
309309
}
310310

311311
@Override
312-
public void query(BBox queryBBox, Visitor function) {
313-
lineIntIndex.query(queryBBox, function);
312+
public void query(TileFilter tileFilter, Visitor function) {
313+
lineIntIndex.query(tileFilter, function);
314314
}
315315

316316
public interface EdgeCheck {

0 commit comments

Comments
 (0)