GeoHash II

这题是 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;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值