这题是 Geohash的加强版
将一个字符串用Geohash的逆运算求出latitude和longitude
Geohash细节见帮助Geohash或者wiki GeoHash
Example
样例1
输入: "wx4g0s"`
输出: lat = 39.92706299 and lng = 116.39465332
样例2
输入: "w"
输出: lat = 22.50000000 and lng = 112.50000000
思路:Geohash的逆算法;注意Integer.ToBinaryString,有时候只给0,或者100,必须补齐5位;否则精度不够。
还有收集lng lat bin的时候,交替进行,不要写for循环,否则会漏掉最后一个digit;
public class GeoHash {
/*
* @param geohash: geohash a base32 string
* @return: latitude and longitude a location coordinate pair
*/
public double[] decode(String geohash) {
if(geohash == null || geohash.length() == 0) {
return new double[0];
}
String SPACE = "0123456789bcdefghjkmnpqrstuvwxyz";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < geohash.length(); i++) {
int index = SPACE.indexOf(geohash.charAt(i));
sb.append(getFiveDigit(index));
}
StringBuilder latBinBuilder = new StringBuilder();
StringBuilder lngBinBuilder = new StringBuilder();
int i = 0;
while(i < sb.length()){
if(i % 2 == 0){
lngBinBuilder.append(sb.charAt(i));
} else {
latBinBuilder.append(sb.charAt(i));
}
i++;
}
String latBin = latBinBuilder.toString();
String lngBin = lngBinBuilder.toString();
double[] res = new double[2];
res[0] = getGeo(latBin, -90, 90);
res[1] = getGeo(lngBin, -180, 180);
return res;
}
// 注意Integer.ToBinaryString,有时候只给0,或者100,必须补齐5位;
private String getFiveDigit(int index) {
String str = Integer.toBinaryString(index);
while(str.length() < 5) {
str = "0" + str;
}
return str;
}
private double getGeo(String str, double start, double end) {
double res = 0.0;
for(int i = 0; i < str.length(); i++){
char c = str.charAt(i);
double mid = (start + end) / 2;
if(c == '0'){
end = mid;
} else {
start = mid;
}
res = (start + end) / 2;
}
return res;
}
}