Skip to content

Commit 6d0d50e

Browse files
author
Silvio Heuberger
committed
- added bounding box expansion to the geohash
bounding box search. - also added a method to get a bounding box as WKT.
1 parent d565bde commit 6d0d50e

5 files changed

Lines changed: 101 additions & 4 deletions

File tree

‎src/main/java/ch/hsr/geohash/BoundingBox.java‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,35 @@ public WGS84Point getCenterPoint() {
9494
double centerLongitude = (minLon + maxLon) / 2;
9595
return new WGS84Point(centerLatitude, centerLongitude);
9696
}
97+
98+
public void expandToInclude(BoundingBox other) {
99+
if (other.minLon < minLon) {
100+
minLon = other.minLon;
101+
}
102+
if (other.maxLon > maxLon) {
103+
maxLon = other.maxLon;
104+
}
105+
if (other.minLat < minLat) {
106+
minLat = other.minLat;
107+
}
108+
if (other.maxLat > maxLat) {
109+
maxLat = other.maxLat;
110+
}
111+
}
112+
113+
public double getMinLon() {
114+
return minLon;
115+
}
116+
117+
public double getMinLat() {
118+
return minLat;
119+
}
120+
121+
public double getMaxLat() {
122+
return maxLat;
123+
}
124+
125+
public double getMaxLon() {
126+
return maxLon;
127+
}
97128
}

‎src/main/java/ch/hsr/geohash/queries/GeoHashBoundingBoxQuery.java‎

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,37 @@ public class GeoHashBoundingBoxQuery implements GeoHashQuery {
2525

2626
/* there's not going to be more than 4 hashes. */
2727
private List<GeoHash> searchHashes = new ArrayList<GeoHash>(4);
28-
28+
/* the combined bounding box of those hashes. */
29+
private BoundingBox boundingBox;
30+
2931
public GeoHashBoundingBoxQuery(BoundingBox bbox) {
3032
int fittingBits = GeoHashSizeTable.numberOfBitsForOverlappingGeoHash(bbox);
3133
WGS84Point center = bbox.getCenterPoint();
3234
GeoHash centerHash = GeoHash.withBitPrecision(center.getLatitude(), center.getLongitude(), fittingBits);
3335

3436
if (hashFits(centerHash, bbox)) {
35-
searchHashes.add(centerHash);
37+
addSearchHash(centerHash);
3638
} else {
3739
expandSearch(centerHash, bbox);
3840
}
3941
}
4042

43+
private void addSearchHash(GeoHash hash) {
44+
if (boundingBox == null) {
45+
boundingBox = new BoundingBox(hash.getBoundingBox());
46+
} else {
47+
boundingBox.expandToInclude(hash.getBoundingBox());
48+
}
49+
searchHashes.add(hash);
50+
}
51+
4152
private void expandSearch(GeoHash centerHash, BoundingBox bbox) {
42-
searchHashes.add(centerHash);
53+
addSearchHash(centerHash);
4354

4455
for (GeoHash adjacent : centerHash.getAdjacent()) {
4556
BoundingBox adjacentBox = adjacent.getBoundingBox();
4657
if (adjacentBox.intersects(bbox) && !searchHashes.contains(adjacent)) {
47-
searchHashes.add(adjacent);
58+
addSearchHash(adjacent);
4859
}
4960
}
5061
}
@@ -73,4 +84,10 @@ public String toString() {
7384
}
7485
return bui.toString();
7586
}
87+
88+
@Override
89+
public String getWktBox() {
90+
return "BOX(" + boundingBox.getMinLon() + " " + boundingBox.getMinLat() + "," + boundingBox.getMaxLon() + " "
91+
+ boundingBox.getMaxLat() + ")";
92+
}
7693
}

‎src/main/java/ch/hsr/geohash/queries/GeoHashCircleQuery.java‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public GeoHashCircleQuery(WGS84Point center, double radius) {
4444
public boolean contains(GeoHash hash) {
4545
return query.contains(hash);
4646
}
47+
48+
@Override
49+
public String getWktBox() {
50+
return query.getWktBox();
51+
}
4752

4853
@Override
4954
public List<GeoHash> getSearchHashes() {

‎src/main/java/ch/hsr/geohash/queries/GeoHashQuery.java‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ public interface GeoHashQuery {
1616
*/
1717
public abstract List<GeoHash> getSearchHashes();
1818

19+
public abstract String getWktBox();
20+
1921
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package ch.hsr.geohash;
2+
3+
import static org.junit.Assert.*;
4+
5+
import java.util.Arrays;
6+
import java.util.List;
7+
8+
import org.junit.Test;
9+
10+
import ch.hsr.geohash.queries.GeoHashCircleQuery;
11+
import ch.hsr.geohash.queries.GeoHashQuery;
12+
13+
public class GeoHashCircleQueryTest {
14+
private WGS84Point center = new WGS84Point(10.00254, 76.30627);;
15+
16+
@Test
17+
public void checkJerryDonSample1() {
18+
checkRadiusSearchHashes(1000, "t9y2bk" );
19+
}
20+
21+
@Test
22+
public void testJerryDonSample2() {
23+
checkRadiusSearchHashes(1500, "t9y2bh", "t9y2bs", "t9yb2b0", "t9yb2b8");
24+
}
25+
26+
@Test
27+
public void testJerryDonSample3() {
28+
checkRadiusSearchHashes(2500, "t9y2b");
29+
}
30+
31+
private void checkRadiusSearchHashes(int radius, String ... string) {
32+
GeoHashQuery query = new GeoHashCircleQuery(center, radius);
33+
List<String> expectedHashes = Arrays.asList(string);
34+
List<GeoHash> searchHashes = query.getSearchHashes();
35+
assertEquals(expectedHashes.size(), searchHashes.size());
36+
for(GeoHash hash : searchHashes){
37+
if(! expectedHashes.contains(hash.toBase32())){
38+
fail("Hash " + hash + " not found in list of expected hashes");
39+
}
40+
}
41+
}
42+
}

0 commit comments

Comments
 (0)