Skip to content

Commit

Permalink
feat(gh-update): Update DataAccess to latest graphhopper version
Browse files Browse the repository at this point in the history
  • Loading branch information
rtroilo committed Dec 21, 2023
1 parent c8839d4 commit c153fa7
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 120 deletions.
50 changes: 22 additions & 28 deletions core/src/main/java/com/graphhopper/storage/index/LineIntIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
import com.graphhopper.storage.DAType;
import com.graphhopper.storage.DataAccess;
import com.graphhopper.storage.Directory;
import com.graphhopper.util.Constants;
import com.graphhopper.util.GHUtility;
import com.graphhopper.util.Helper;
import com.graphhopper.util.shapes.BBox;

import java.util.function.IntConsumer;

public class LineIntIndex {

private final int MAGIC_INT = Integer.MAX_VALUE / 22318;
// do not start with 0 as a positive value means leaf and a negative means "entry with subentries"
static final int START_POINTER = 1;

Expand All @@ -48,12 +48,8 @@ public class LineIntIndex {
private SpatialKeyAlgo keyAlgo;

public LineIntIndex(BBox bBox, Directory dir, String name) {
this(bBox, dir, name, dir.getDefaultType(name, true));
}

public LineIntIndex(BBox bBox, Directory dir, String name, DAType daType) {
this.bounds = bBox;
this.dataAccess = dir.create(name, daType);
this.dataAccess = dir.find(name, DAType.getPreferredInt(dir.getDefaultType()));
}

public boolean loadExisting() {
Expand All @@ -63,7 +59,9 @@ public boolean loadExisting() {
if (!dataAccess.loadExisting())
return false;

GHUtility.checkDAVersion("location_index", Constants.VERSION_LOCATION_IDX, dataAccess.getHeader(0));
if (dataAccess.getHeader(0) != MAGIC_INT)
throw new IllegalStateException("incorrect location index version, expected:" + MAGIC_INT);

checksum = dataAccess.getHeader(1 * 4);
minResolutionInMeter = dataAccess.getHeader(2 * 4);
indexStructureInfo = IndexStructureInfo.create(bounds, minResolutionInMeter);
Expand Down Expand Up @@ -159,12 +157,8 @@ private void fillIDs(long keyPart, IntConsumer consumer) {
}

public void query(BBox queryShape, final LocationIndex.Visitor function) {
query(LocationIndex.createBBoxTileFilter(queryShape), function);
}

public void query(LocationIndex.TileFilter tileFilter, final LocationIndex.Visitor function) {
final IntHashSet set = new IntHashSet();
query(START_POINTER, tileFilter,
query(START_POINTER, queryShape,
bounds.minLat, bounds.minLon, bounds.maxLat - bounds.minLat, bounds.maxLon - bounds.minLon,
new LocationIndex.Visitor() {
@Override
Expand All @@ -185,10 +179,10 @@ public void onEdge(int edgeId) {
}, 0);
}

private void query(int intPointer, LocationIndex.TileFilter tileFilter,
double minLat, double minLon,
double deltaLatPerDepth, double deltaLonPerDepth,
LocationIndex.Visitor function, int depth) {
private void query(int intPointer, BBox queryBBox,
double minLat, double minLon,
double deltaLatPerDepth, double deltaLonPerDepth,
LocationIndex.Visitor function, int depth) {
long pointer = (long) intPointer * 4;
if (depth == entries.length) {
int nextIntPointer = dataAccess.getInt(pointer);
Expand Down Expand Up @@ -217,25 +211,25 @@ private void query(int intPointer, LocationIndex.TileFilter tileFilter,
double tmpMinLon = minLon + deltaLonPerDepth * pixelXY[0];
double tmpMinLat = minLat + deltaLatPerDepth * pixelXY[1];

BBox bbox = (tileFilter != null || function.isTileInfo()) ? new BBox(tmpMinLon, tmpMinLon + deltaLonPerDepth, tmpMinLat, tmpMinLat + deltaLatPerDepth) : null;
BBox bbox = (queryBBox != null || function.isTileInfo()) ? new BBox(tmpMinLon, tmpMinLon + deltaLonPerDepth, tmpMinLat, tmpMinLat + deltaLatPerDepth) : null;
if (function.isTileInfo())
function.onTile(bbox, depth);
if (tileFilter == null || tileFilter.acceptAll(bbox)) {
if (queryBBox == null || queryBBox.contains(bbox)) {
// fill without a restriction!
query(nextIntPointer, null, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
} else if (tileFilter.acceptPartially(bbox)) {
query(nextIntPointer, tileFilter, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
} else if (queryBBox.intersects(bbox)) {
query(nextIntPointer, queryBBox, tmpMinLat, tmpMinLon, deltaLatPerDepth, deltaLonPerDepth, function, depth + 1);
}
}
}

/**
* This method collects edge ids from the neighborhood of a point and puts them into foundEntries.
* <p>
*
* If it is called with iteration = 0, it just looks in the tile the query point is in.
* If it is called with iteration = 0,1,2,.., it will look in additional tiles further and further
* from the start tile. (In a square that grows by one pixel in all four directions per iteration).
* <p>
*
* See discussion at issue #221.
* <p>
*/
Expand All @@ -246,11 +240,11 @@ public void findEdgeIdsInNeighborhood(double queryLat, double queryLon, int iter
int subqueryY = y + yreg;
int subqueryXA = x - iteration;
int subqueryXB = x + iteration;
if (subqueryXA >= 0 && subqueryY >= 0 && subqueryXA < indexStructureInfo.getParts() && subqueryY < indexStructureInfo.getParts()) {
if (subqueryXA >= 0 && subqueryY >= 0) { // TODO: Also don't walk off the _other_ side of the grid.
long keyPart = keyAlgo.encode(subqueryXA, subqueryY) << (64 - keyAlgo.getBits());
fillIDs(keyPart, foundEntries);
}
if (iteration > 0 && subqueryXB >= 0 && subqueryY >= 0 && subqueryXB < indexStructureInfo.getParts() && subqueryY < indexStructureInfo.getParts()) {
if (iteration > 0 && subqueryXB >= 0 && subqueryY >= 0) {
long keyPart = keyAlgo.encode(subqueryXB, subqueryY) << (64 - keyAlgo.getBits());
fillIDs(keyPart, foundEntries);
}
Expand All @@ -260,11 +254,11 @@ public void findEdgeIdsInNeighborhood(double queryLat, double queryLon, int iter
int subqueryX = x + xreg;
int subqueryYA = y - iteration;
int subqueryYB = y + iteration;
if (subqueryX >= 0 && subqueryYA >= 0 && subqueryX < indexStructureInfo.getParts() && subqueryYA < indexStructureInfo.getParts()) {
if (subqueryX >= 0 && subqueryYA >= 0) {
long keyPart = keyAlgo.encode(subqueryX, subqueryYA) << (64 - keyAlgo.getBits());
fillIDs(keyPart, foundEntries);
}
if (subqueryX >= 0 && subqueryYB >= 0 && subqueryX < indexStructureInfo.getParts() && subqueryYB < indexStructureInfo.getParts()) {
if (subqueryX >= 0 && subqueryYB >= 0) {
long keyPart = keyAlgo.encode(subqueryX, subqueryYB) << (64 - keyAlgo.getBits());
fillIDs(keyPart, foundEntries);
}
Expand All @@ -284,7 +278,7 @@ public void setMinResolutionInMeter(int minResolutionInMeter) {
}

public void flush() {
dataAccess.setHeader(0, Constants.VERSION_LOCATION_IDX);
dataAccess.setHeader(0, MAGIC_INT);
dataAccess.setHeader(1 * 4, checksum);
dataAccess.setHeader(2 * 4, minResolutionInMeter);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import com.graphhopper.routing.util.EdgeFilter;
import com.graphhopper.util.shapes.BBox;

import java.util.List;

/**
* Provides a way to map real world data "lat,lon" to internal ids/indices of a memory efficient graph
* - often just implemented as an array.
Expand All @@ -46,49 +48,16 @@ public interface LocationIndex {
*/
Snap findClosest(double lat, double lon, EdgeFilter edgeFilter);

List<Snap> findCandidateSnaps(final double queryLat, final double queryLon, final EdgeFilter edgeFilter);
/**
* This method explores the LocationIndex with the specified Visitor. It visits only the stored edges (and only once)
* and limited by the queryBBox. Also (a few) more edges slightly outside of queryBBox could be
* returned that you can avoid via doing an explicit BBox check of the coordinates.
*/
default void query(BBox queryBBox, Visitor function) {
query(createBBoxTileFilter(queryBBox), function);
}

void query(TileFilter tileFilter, Visitor function);
void query(BBox queryBBox, Visitor function);

void close();


interface TileFilter {

/**
* @return true if all edges within the given bounding box shall be accepted
*/
boolean acceptAll(BBox tile);

/**
* @return true if edges within the given bounding box shall potentially be accepted. In this
* case the tile filter will be applied again for smaller bounding boxes on a lower level.
* If this is the lowest level already simply all edges will be accepted.
*/
boolean acceptPartially(BBox tile);
}

static TileFilter createBBoxTileFilter(BBox queryBBox) {
return queryBBox == null ? null : new TileFilter() {
@Override
public boolean acceptAll(BBox tile) {
return queryBBox.contains(tile);
}

@Override
public boolean acceptPartially(BBox tile) {
return queryBBox.intersects(tile);
}
};
}

/**
* This interface allows to visit edges stored in the LocationIndex.
*/
Expand All @@ -107,4 +76,5 @@ default boolean isTileInfo() {
default void onTile(BBox bbox, int depth) {
}
}

}
Loading

0 comments on commit c153fa7

Please sign in to comment.