Skip to content

Commit b42547b

Browse files
committed
Changed geohash function in java code
1 parent 0293732 commit b42547b

File tree

5 files changed

+73
-120
lines changed

5 files changed

+73
-120
lines changed

C/src/mainwindow.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -176,8 +176,8 @@ MainWindow::initMap(QWebEnginePage *page,
176176
std::vector<geopoint_t> lstGeoFilter = CoordGetFromFile(filteredCoordsFile, LMT_FILTERED_GPS_DATA);
177177
std::vector<geopoint_t> lstJavaFilter = CoordGetFromFile(pathToCoordsFile, LMT_FILTERED_GPS_DATA);
178178
// std::vector<geopoint_t> lstJavaFilter = CoordGetFromFile(filteredCoordsFile2, LMT_FILTERED_GPS_DATA);
179-
const int filterPrec = 8;
180-
const int minPoints = 2;
179+
const int filterPrec = 7;
180+
const int minPoints = 3;
181181

182182
// qDebug() << "RealTime Src distance: " << filterDistanceRealTime(lstCoords, GEOHASH_MAX_PRECISION, 1);
183183
// qDebug() << "RealTime Desk distance: " << filterDistanceRealTime(lstGeoFilter, GEOHASH_MAX_PRECISION, 1);
@@ -192,9 +192,9 @@ MainWindow::initMap(QWebEnginePage *page,
192192
qDebug() << "Java distance : " << CoordCaclulateDistance(lstJavaFilter);
193193

194194
//filter for display
195-
// lstCoords = CoordFilterByGeoHash(lstCoords, filterPrec, minPoints);
196-
// lstJavaFilter = CoordFilterByGeoHash(lstJavaFilter, filterPrec, minPoints);
197-
// lstGeoFilter = CoordFilterByGeoHash(lstGeoFilter, filterPrec, minPoints);
195+
lstCoords = CoordFilterByGeoHash(lstCoords, filterPrec, minPoints);
196+
lstJavaFilter = CoordFilterByGeoHash(lstJavaFilter, filterPrec, minPoints);
197+
lstGeoFilter = CoordFilterByGeoHash(lstGeoFilter, filterPrec, minPoints);
198198

199199
qDebug() << "2Src distance : " << CoordCaclulateDistance(lstCoords);
200200
qDebug() << "2Filtered distance : " << CoordCaclulateDistance(lstGeoFilter);

madlocationmanager/src/main/java/mad/location/manager/lib/Commons/Coordinates.java

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -74,53 +74,6 @@ private static GeoPoint pointPlusDistanceNorth(GeoPoint point, double distance)
7474
return getPointAhead(point, distance, 0.0);
7575
}
7676

77-
public static GeoPoint[] filterByGeoHash(List<GeoPoint> lstSrc,
78-
int precision,
79-
int minPointCount) {
80-
final int NOT_VALID_INDEX = -1;
81-
class AuxItem {
82-
int index, count;
83-
double lon, lat;
84-
85-
AuxItem() {
86-
index = NOT_VALID_INDEX;
87-
count = 0;
88-
lon = lat = 0.0;
89-
}
90-
}
91-
92-
char buff[] = new char[precision];
93-
HashMap<String, AuxItem> dctHashCount = new HashMap<>();
94-
95-
int idx = 0;
96-
for (GeoPoint ci : lstSrc) {
97-
GeoHash.encode(ci.Latitude, ci.Longitude, buff, precision);
98-
String geoHash = new String(buff);
99-
AuxItem it;
100-
if (!dctHashCount.containsKey(geoHash)) {
101-
it = new AuxItem();
102-
dctHashCount.put(geoHash, it);
103-
}
104-
it = dctHashCount.get(geoHash);
105-
if (++it.count == minPointCount)
106-
it.index = idx++;
107-
it.lat += ci.Latitude;
108-
it.lon += ci.Longitude;
109-
}
110-
111-
GeoPoint resArr[] = new GeoPoint[idx];
112-
for (Map.Entry<String, AuxItem> it : dctHashCount.entrySet()) {
113-
AuxItem val = it.getValue();
114-
if (val.index == NOT_VALID_INDEX)
115-
continue;
116-
double meanLatitude = val.lat / val.count;
117-
double meanLongitude = val.lon / val.count;
118-
GeoPoint np = new GeoPoint(meanLatitude, meanLongitude);
119-
resArr[val.index] = np;
120-
}
121-
return resArr;
122-
}
123-
12477
public static double calculateDistance(GeoPoint track[]) {
12578
double distance = 0.0;
12679
double lastLon, lastLat;

madlocationmanager/src/main/java/mad/location/manager/lib/Filters/GeoHash.java

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,53 @@
55
*/
66

77
public class GeoHash {
8+
9+
private static long interleave(long x, long y) {
10+
x = (x | (x << 16)) & 0x0000ffff0000ffffL;
11+
x = (x | (x << 8)) & 0x00ff00ff00ff00ffL;
12+
x = (x | (x << 4)) & 0x0f0f0f0f0f0f0f0fL;
13+
x = (x | (x << 2)) & 0x3333333333333333L;
14+
x = (x | (x << 1)) & 0x5555555555555555L;
15+
16+
y = (y | (y << 16)) & 0x0000ffff0000ffffL;
17+
y = (y | (y << 8)) & 0x00ff00ff00ff00ffL;
18+
y = (y | (y << 4)) & 0x0f0f0f0f0f0f0f0fL;
19+
y = (y | (y << 2)) & 0x3333333333333333L;
20+
y = (y | (y << 1)) & 0x5555555555555555L;
21+
22+
return x | (y << 1);
23+
24+
//use pdep instructions
25+
// return _pdep_u64(x, 0x5555555555555555) | _pdep_u64(y, 0xaaaaaaaaaaaaaaaa);
26+
}
27+
28+
public static long encode_u64(double lat, double lon, int prec) {
29+
lat = lat/180.0 + 1.5;
30+
lon = lon/360.0 + 1.5;
31+
long ilat = Double.doubleToRawLongBits(lat);
32+
long ilon = Double.doubleToRawLongBits(lon);
33+
ilat >>= 20;
34+
ilon >>= 20;
35+
ilat &= 0x00000000ffffffffL;
36+
ilon &= 0x00000000ffffffffL;
37+
return interleave(ilat, ilon) >> (GEOHASH_MAX_PRECISION-prec)*5;
38+
}
39+
40+
841
static final char base32Table[] = {
942
'0', '1', '2', '3', '4', '5', '6', '7',
1043
'8', '9', 'b', 'c', 'd', 'e', 'f', 'g',
1144
'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r',
1245
's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
1346
public static final int GEOHASH_MAX_PRECISION = 12;
14-
15-
public static void encode(double srcLat, double srcLon, char buff[], int precision) {
16-
class Interval {
17-
private double min, max;
18-
19-
private Interval(double min, double max) {
20-
this.min = min;
21-
this.max = max;
22-
}
23-
}
24-
25-
Interval lat = new Interval(-90.0, 90.0);
26-
Interval lon = new Interval(-180.0, 180.0);
27-
Interval ci;
28-
boolean isEven = true;
29-
double mid, cd;
30-
int idx = 0; // index into base32 map
31-
int bit = 0; // each char holds 5 bits
32-
int bi = 0; //buffer index
33-
34-
while (precision > 0) {
35-
if (isEven) {
36-
ci = lon;
37-
cd = srcLon;
38-
} else {
39-
ci = lat;
40-
cd = srcLat;
41-
}
42-
43-
mid = (ci.min + ci.max) / 2.0;
44-
idx <<= 1; //idx *= 2
45-
if (cd >= mid) {
46-
ci.min = mid;
47-
idx |= 1; //idx += 1
48-
} else {
49-
ci.max = mid;
50-
}
51-
52-
isEven = !isEven;
53-
54-
if (++bit == 5) {
55-
buff[bi++] = base32Table[idx];
56-
idx = bit = 0;
57-
--precision;
58-
}
47+
public static String geohash_str(long geohash, int prec /*hack. we don't need it, but java hasn't unsigned values*/) {
48+
StringBuffer buff = new StringBuffer(GEOHASH_MAX_PRECISION);
49+
geohash >>= 4; //cause we don't need last 4 bits. that's strange, I thought we don't need first 4 bits %)
50+
geohash &= 0x0fffffffffffffffl; //we don't need sign here
51+
while (prec-- > 0){
52+
buff.append(base32Table[(int)(geohash & 0x1f)]);
53+
geohash >>= 5;
5954
}
55+
return buff.reverse().toString();
6056
}
61-
6257
}

madlocationmanager/src/main/java/mad/location/manager/lib/Loggers/GeohashRTFilter.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public class GeohashRTFilter {
2929
private int ppCompGeoHash = 0;
3030
private int ppReadGeoHash = 1;
3131

32-
private char geoHashBuffers[][];
32+
private long geoHashBuffers[];
3333
private int pointsInCurrentGeohashCount;
3434

3535
private GeoPoint currentGeoPoint;
@@ -72,9 +72,7 @@ public double getDistanceAsIsHP() {
7272
public void reset(ILogger logger) {
7373
m_logger = logger;
7474
m_geoFilteredTrack.clear();
75-
char[] buff1 = new char[GeoHash.GEOHASH_MAX_PRECISION];
76-
char[] buff2 = new char[GeoHash.GEOHASH_MAX_PRECISION];
77-
geoHashBuffers = new char[][]{buff1, buff2};
75+
geoHashBuffers = new long[2];
7876
pointsInCurrentGeohashCount = 0;
7977
lastApprovedGeoPoint = new GeoPoint(COORD_NOT_INITIALIZED, COORD_NOT_INITIALIZED);
8078
currentGeoPoint = new GeoPoint(COORD_NOT_INITIALIZED, COORD_NOT_INITIALIZED);
@@ -99,7 +97,7 @@ public void filter(Location loc) {
9997

10098
GeoPoint pi = new GeoPoint(loc.getLatitude(), loc.getLongitude());
10199
if (isFirstCoordinate) {
102-
GeoHash.encode(pi.Latitude, pi.Longitude, geoHashBuffers[ppCompGeoHash], m_geohashPrecision);
100+
geoHashBuffers[ppCompGeoHash] = GeoHash.encode_u64(pi.Latitude, pi.Longitude, m_geohashPrecision);
103101
currentGeoPoint.Latitude = pi.Latitude;
104102
currentGeoPoint.Longitude = pi.Longitude;
105103
pointsInCurrentGeohashCount = 1;
@@ -128,8 +126,8 @@ public void filter(Location loc) {
128126
lastGeoPointAsIs.Longitude = loc.getLongitude();
129127
lastGeoPointAsIs.Latitude = loc.getLatitude();
130128

131-
GeoHash.encode(pi.Latitude, pi.Longitude, geoHashBuffers[ppReadGeoHash], m_geohashPrecision);
132-
if (!Arrays.equals(geoHashBuffers[ppCompGeoHash], geoHashBuffers[ppReadGeoHash])) {
129+
geoHashBuffers[ppReadGeoHash] = GeoHash.encode_u64(pi.Latitude, pi.Longitude, m_geohashPrecision);
130+
if (geoHashBuffers[ppCompGeoHash] != geoHashBuffers[ppReadGeoHash]) {
133131
if (pointsInCurrentGeohashCount >= m_geohashMinPointCount) {
134132
currentGeoPoint.Latitude /= pointsInCurrentGeohashCount;
135133
currentGeoPoint.Longitude /= pointsInCurrentGeohashCount;

madlocationmanager/src/test/java/mad/location/manager/test/GeoHashUnitTest.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ public void encodeTest() throws Exception {
6060
};
6161

6262
for (EncodeTestItem ti : posTests) {
63-
char buff[] = new char[ti.precision];
64-
GeoHash.encode(ti.lat, ti.lon, buff, ti.precision);
65-
assertTrue(Arrays.equals(ti.expected.toCharArray(), buff));
63+
long gh = GeoHash.encode_u64(ti.lat, ti.lon, ti.precision);
64+
String ghstr = GeoHash.geohash_str(gh, ti.precision);
65+
assertTrue(ti.expected.equals(ghstr));
6666
}
6767

6868
for (EncodeTestItem ti : negTests) {
69-
char buff[] = new char[ti.precision];
70-
GeoHash.encode(ti.lat, ti.lon, buff, ti.precision);
71-
assertFalse(Arrays.equals(ti.expected.toCharArray(), buff));
69+
long gh = GeoHash.encode_u64(ti.lat, ti.lon, ti.precision);
70+
String ghstr = GeoHash.geohash_str(gh, ti.precision);
71+
assertFalse(ti.expected.equals(ghstr));
7272
}
7373
}
7474

@@ -77,17 +77,24 @@ public void equationTest() throws Exception {
7777
GeoPoint geo1 = new GeoPoint(44.87533558, 72.5656988);
7878
GeoPoint geo2 = new GeoPoint(44.87533558, 72.5656988);
7979
GeoPoint geo3 = new GeoPoint(44.87533540, 72.5656988);
80-
8180
final int prec = GeoHash.GEOHASH_MAX_PRECISION;
82-
char buff1[] = new char[prec];
83-
char buff2[] = new char[prec];
84-
char buff3[] = new char[prec];
8581

86-
GeoHash.encode(geo1.Latitude, geo1.Longitude, buff1, prec);
87-
GeoHash.encode(geo2.Latitude, geo2.Longitude, buff2, prec);
88-
GeoHash.encode(geo3.Latitude, geo3.Longitude, buff3, prec);
82+
long gh1 = GeoHash.encode_u64(geo1.Latitude, geo1.Longitude, prec);
83+
long gh2 = GeoHash.encode_u64(geo2.Latitude, geo2.Longitude, prec);
84+
long gh3 = GeoHash.encode_u64(geo3.Latitude, geo3.Longitude, prec);
85+
86+
assertTrue(gh1 == gh2);
87+
assertFalse(gh1 == gh3);
88+
}
8989

90-
assertTrue(Arrays.equals(buff1, buff2));
91-
assertFalse(Arrays.equals(buff1, buff3));
90+
91+
@Test
92+
public void geohashU64Test() throws Exception {
93+
double lat = 27.988056;
94+
double lon = 86.925278;
95+
long exp = 0xceb7f254240fd612L;
96+
long act = GeoHash.encode_u64(lat, lon, GeoHash.GEOHASH_MAX_PRECISION);
97+
assertEquals(exp , act);
98+
//tuvz4p141zc1
9299
}
93100
}

0 commit comments

Comments
 (0)