Commit cc0f748c authored by Tobias Meuser's avatar Tobias Meuser
Browse files

Updated Geohash features

parent 8f511c27
...@@ -45,14 +45,14 @@ public class Geohash { ...@@ -45,14 +45,14 @@ public class Geohash {
double currentCellY = pLocation.getLatitude() - offsetY; double currentCellY = pLocation.getLatitude() - offsetY;
boolean nextBit; boolean nextBit;
if (i % 2 == 0) { if ((i + j) % 2 == 0) {
nextBit = getNextBit(currentCellX, cellSize.getSizeX()); nextBit = getNextBit(currentCellX, cellSize.getSizeX());
} else { } else {
nextBit = getNextBit(currentCellY, cellSize.getSizeY()); nextBit = getNextBit(currentCellY, cellSize.getSizeY());
} }
if (nextBit) { if (nextBit) {
if (i % 2 == 0) { if ((i + j) % 2 == 0) {
offsetX += cellSize.getSizeX() / 2.0; offsetX += cellSize.getSizeX() / 2.0;
} else { } else {
offsetY += cellSize.getSizeY() / 2.0; offsetY += cellSize.getSizeY() / 2.0;
...@@ -70,27 +70,141 @@ public class Geohash { ...@@ -70,27 +70,141 @@ public class Geohash {
} }
} }
return encode(bytes); return encode(bytes);
} }
public static String[] getAdjacentGeohashes(String pGeohash) {
String[] geohashes = new String[] { getAdjacentGeohash(pGeohash, 1, 0), getAdjacentGeohash(pGeohash, -1, 0),
getAdjacentGeohash(pGeohash, 0, 1), getAdjacentGeohash(pGeohash, 0, -1) };
return geohashes;
}
/**
* @param pGeohash
* @param pX
* @param pY
* @return
*/
public static String getAdjacentGeohash(String pGeohash, int pX, int pY) {
byte[] decode = decode(pGeohash);
if (pX != 0) {
boolean reduce = pX < 0;
outer: for (int i = decode.length - 1; i >= 0; i--) {
for (int j = 0; j < 5; j++) {
if ((i + j) % 2 == 0) {
boolean bitSet = isBitSet(decode[i], j);
if (reduce) {
decode[i] = toogleBit(decode[i], j);
if (bitSet) {
break outer;
}
} else {
decode[i] = toogleBit(decode[i], j);
if (!bitSet) {
break outer;
}
}
}
}
}
}
if (pY != 0) {
boolean reduce = pY < 0;
outer: for (int i = decode.length - 1; i >= 0; i--) {
for (int j = 0; j < 5; j++) {
if ((i + j) % 2 == 1) {
boolean bitSet = isBitSet(decode[i], j);
if (reduce) {
decode[i] = toogleBit(decode[i], j);
if (bitSet) {
break outer;
}
} else {
decode[i] = toogleBit(decode[i], j);
if (!bitSet) {
break outer;
}
}
}
}
}
}
return encode(decode);
}
private static boolean isBitSet(byte b, int offset) {
return getBit(b, offset) == 1;
}
private static byte getBit(byte b, int offset) {
return (byte) ((b % Math.pow(2, offset + 1)) / Math.pow(2, offset));
}
private static byte setBit(byte b, int offset, int value) {
return (byte) (b + Math.pow(2, offset) * (value - getBit(b, offset)));
}
private static byte toogleBit(byte b, int offset) {
if (isBitSet(b, offset)) {
return setBit(b, offset, 0);
} else {
return setBit(b, offset, 1);
}
}
private static String encode(byte[] pBytes) { private static String encode(byte[] pBytes) {
StringBuffer buffer = new StringBuffer(); StringBuffer buffer = new StringBuffer();
for (int i = 0; i < pBytes.length; i++) { for (int i = 0; i < pBytes.length; i++) {
if (pBytes[i] <= 9) { byte b = pBytes[i];
buffer.append(pBytes[i]); buffer.append(encodeByte(b));
} else if (pBytes[i] <= 16) { }
buffer.append((char) (pBytes[i] + 'b' - 10)); return buffer.toString();
} else if (pBytes[i] <= 18) { }
buffer.append((char) (pBytes[i] + 'j' - 17));
} else if (pBytes[i] <= 20) { private static char encodeByte(byte b) {
buffer.append((char) (pBytes[i] + 'j' - 19)); if (b <= 9) {
} else if (pBytes[i] <= 32) { return (char) (b + '0');
buffer.append((char) (pBytes[i] + 'p' - 21)); } else if (b <= 16) {
return (char) (b + 'b' - 10);
} else if (b <= 18) {
return (char) (b + 'j' - 17);
} else if (b <= 20) {
return (char) (b + 'm' - 19);
} else if (b <= 32) {
return (char) (b + 'p' - 21);
} else { } else {
throw new IllegalArgumentException("Must not have a value greater than 32 in Base32 encoding!"); throw new IllegalArgumentException("Must not have a value greater than 32 in Base32 encoding!");
} }
} }
return buffer.toString();
private static byte decodeByte(char c) {
if (c >= 'p') {
return (byte) (c - 'p' + 21);
} else if (c >= 'm') {
return (byte) (c - 'm' + 19);
} else if (c >= 'j') {
return (byte) (c - 'j' + 17);
} else if (c >= 'b') {
return (byte) (c - 'b' + 10);
} else if (c >= '0') {
return (byte) (c - '0' + 0);
}
return -1;
}
public static byte[] decode(String pGeohash) {
byte[] bytes = new byte[pGeohash.length()];
for (int i = 0; i < pGeohash.length(); i++) {
bytes[i] = decodeByte(pGeohash.charAt(i));
}
return bytes;
} }
private static boolean getNextBit(double currentCellPosition, double currentCellSize) { private static boolean getNextBit(double currentCellPosition, double currentCellSize) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment