Tuesday, June 18, 2019

Lintcode 530. Geohash II

This is a followup question for Geohash.
Convert a Geohash string to latitude and longitude.
Check how to generate geohash on wiki: Geohash or just google it for more details.

Example

Example1
Input: "wx4g0s"`
Output: lat = 39.92706299 and lng = 116.39465332
Example2
Input: "w"
Output: lat = 22.50000000 and lng = 112.50000000

Code (Java):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
public class GeoHash {
    /*
     * @param geohash: geohash a base32 string
     * @return: latitude and longitude a location coordinate pair
     */
    public double[] decode(String geohash) {
        // step1: get binary code
        //
        String binaryGeoHash = getBinaryGeoHash(geohash);
 
        // step 2: get binary representation of the long and latitude
        String[] binaryLongLati = getBinaryLongAndLati(binaryGeoHash);
 
        double longtitude = getLocation(binaryLongLati[0], -180, 180);
        double latitude = getLocation(binaryLongLati[1], -90, 90);
 
        double[] ans = new double[2];
        ans[0] = latitude;
        ans[1] = longtitude;
 
        return ans;
    }
 
    private double getLocation(String code, double start, double end) {
        double mid = start + (end - start) / 2;
        for (int i = 0; i < code.length(); i++) {
            if (code.charAt(i) == '0') {
                end = mid;
            } else {
                start = mid;
            }
 
            mid = start + (end - start) / 2;
        }
 
        return mid;
    }
 
    private String[] getBinaryLongAndLati(String binaryGeoHash) {
        String[] ans = new String[2];
        StringBuilder longtitude = new StringBuilder();
        StringBuilder latitude = new StringBuilder();
 
        for (int i = 0; i < binaryGeoHash.length(); i += 2) {
            longtitude.append(binaryGeoHash.charAt(i));
            if (i + 1 < binaryGeoHash.length()) {
                latitude.append(binaryGeoHash.charAt(i + 1));
            }
        }
 
        ans[0] = longtitude.toString();
        ans[1] = latitude.toString();
 
        return ans;
    }
 
    private String getBinaryGeoHash(String geohash) {
        String dict = "0123456789bcdefghjkmnpqrstuvwxyz";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < geohash.length(); i++) {
            int base32 = dict.indexOf(geohash.charAt(i));
            sb.append(toBase2(base32));
        }
 
        return sb.toString();
    }
 
    private String toBase2(int num) {
        StringBuilder sb = new StringBuilder();
        while (num > 0) {
            sb.insert(0, num % 2);
            num /= 2;
        }
         
        // pad with zeros
        while (sb.length() < 5) {
            sb.insert(0, '0');
        }
 
        return sb.toString();
    }
}

No comments:

Post a Comment