Java GeoHash函数未返回正确的结果

Java GeoHash函数未返回正确的结果,java,geohashing,Java,Geohashing,我试图编写一个geohashing函数,它接受纬度/经度对并返回其base2(geohash一旦转换为base32)字符串。然而,这给了我不正确的结果。怎么了 public static void main(String[] args) { float latitude = 45.512794f; float longitude = -122.679565f; System.out.println(geoHash(latitude, longitude)); } pri

我试图编写一个geohashing函数,它接受纬度/经度对并返回其base2(geohash一旦转换为base32)字符串。然而,这给了我不正确的结果。怎么了

public static void main(String[] args) {
    float latitude = 45.512794f;
    float longitude = -122.679565f;
    System.out.println(geoHash(latitude, longitude));
}

private static String geoHash(float lat, float lng) {
    float lowLat = -90.0f;
    float highLat = 90.0f;
    float lowLng = -180.0f;
    float highLng = 180.0f;
    return geoHash(lowLng, highLng, lowLat, highLat, lat, lng, "");
}

private static String geoHash(float lowLng, float highLng, float lowLat, float highLat, float lat, float lng, String hash) {
    if (hash.length() == 30)
        return hash;

    float midLat = (lowLat + highLat) / 2;
    float midLng = (lowLng + highLng) / 2;
    if (lng <= midLng && lat <= midLat) {
        return geoHash(lowLng, midLng, lowLat, midLat, lat, lng, hash + "00");
    } else if (lng > midLng && lat <= midLat) {
        return geoHash(midLng, highLng, lowLat, midLat, lat, lng, hash + "01");
    } else if (lng <= midLng && lat > midLat) {
        return geoHash(lowLng, midLng, midLat, highLat, lat, lng, hash + "10");
    } else {
        return geoHash(midLng, highLng, midLat, highLat, lat, lng, hash + "11");
    }
}
publicstaticvoidmain(字符串[]args){
浮动纬度=45.512794f;
浮动经度=-122.679565f;
System.out.println(geoHash(纬度、经度));
}
专用静态字符串geoHash(浮动lat、浮动lng){
浮动下限=-90.0f;
浮动高度=90.0f;
浮动下限=-180.0f;
浮子高度LNG=180.0f;
返回geoHash(lowLng、highLng、lowLat、highLat、lat、lng,“”);
}
专用静态字符串geoHash(float-lowLng、float-highLng、float-lowLat、float-highLat、float-lat、float-lng、字符串哈希){
if(hash.length()==30)
返回散列;
浮动中纬度=(低纬度+高纬度)/2;
浮动中间液化天然气=(低液化天然气+高液化天然气)/2;

如果(lng无论您从何处获得预期字符串,该来源都是假的。首先,预期字符串只有29个字符长,这意味着缺少1个字符。此外,前两位必须是
01
,因为经度为负,纬度为正

但是您的代码中仍然存在一个bug:如果我正确理解了geohash的组成,那么您正在切换附加到
hash
的经度和纬度位(
geohash中的第二个和第三个
If
子句(float,float,float,float,float,float,float,float,String)
处理
lng
lat
)的方法

更新 经过进一步调查,您获得意外结果的另一个原因似乎是,显然,base32和base2之间存在不止一种可能的转换。我尝试了一些我可以找到的在线解码器/编码器,它们都给了我您在问题中提到的结果。然而,在阅读维基百科p但是,用于将Geohash从base2编码到base32的算法似乎有所不同


例如,让我们检查您实际获得的geohash(因此没有关于丢失数字的歧义)。您的方法返回
1010010001000001010110100011
,您声称将其转换为
kh0dl3
。是的,当我输入它时,我也会得到这个结果。但让我们再仔细看看。前5个字符是
10100
,或者转换为十进制符号,
12
(base2字符串中的5个字符对应于base32字符串中的一个字符,因此我们需要一次获取5个字符)。在我刚刚链接到的页面中输入
10100
,会产生
K
,这是
kh0dl3
的第一个字符,正如预期的那样。然而,根据维基百科Geohash页面中的表,
12
不会转换为
K
,而是转换为
d
。因此,显然,Geohash的base32-base2转换算法hes与用于获取预期结果的hes不同。

无论从何处获取预期字符串,该源都存在。首先,预期字符串只有29个字符长,这意味着缺少1个字符。此外,前两位必须为
01
,因为经度为负,纬度为正

但是您的代码中仍然存在一个bug:如果我正确理解了geohash的组成,那么您正在切换附加到
hash
的经度和纬度位(
geohash中的第二个和第三个
If
子句(float,float,float,float,float,float,float,float,String)
处理
lng
lat
)的方法

更新 经过进一步调查,您获得意外结果的另一个原因似乎是,显然,base32和base2之间存在不止一种可能的转换。我尝试了一些我可以找到的在线解码器/编码器,它们都给了我您在问题中提到的结果。然而,在阅读维基百科p但是,用于将Geohash从base2编码到base32的算法似乎有所不同


例如,让我们检查您实际获得的geohash(因此没有关于丢失数字的歧义)。您的方法返回
1010010001000001010110100011
,您声称将其转换为
kh0dl3
。是的,当我输入它时,我也会得到这个结果。但让我们再仔细看看。前5个字符是
10100
,或者转换为十进制符号,
12
(base2字符串中的5个字符对应于base32字符串中的一个字符,因此我们需要一次获取5个字符)。在我刚刚链接到的页面中输入
10100
,会产生
K
,这是
kh0dl3
的第一个字符,正如预期的那样。然而,根据维基百科Geohash页面中的表,
12
不会转换为
K
,而是转换为
d
。因此,显然,Geohash的base32-base2转换算法hes与您用来获取预期结果的hes不同。

当然它不会返回您预期的结果。wikipedia页面字面上说您可以从base32对所有数字进行解码,a、i、l、o除外。

当然它不会返回您预期的结果。wikipedia页面字面上说您可以ecode geohash从base32开始对所有数字(a、i、l、o除外)执行操作。

您是否尝试调试代码?我是否建议您使用一些现有库(比方说)?您是否尝试调试代码?我是否建议您使用一些现有库(比方说)?
private static String geoHash(float lowLng, float highLng, float lowLat, float highLat, float lat, float lng, String hash) {
    if (hash.length() == 30)
        return hash;

    float midLng = (lowLng + highLng) / 2.0f;
    float midLat = (lowLat + highLat) / 2.0f;
    if (lng <= midLng && lat <= midLat) {
        return geoHash(lowLng, midLng, lowLat, midLat, lat, lng, hash + "00");
    } else if (lng <= midLng && lat > midLat) {
        return geoHash(lowLng, midLng, midLat, highLat, lat, lng, hash + "01");
    } else if (lng > midLng && lat <= midLat) {
        return geoHash(midLng, highLng, lowLat, midLat, lat, lng, hash + "10");
    } else {
        return geoHash(midLng, highLng, midLat, highLat, lat, lng, hash + "11");
    }
}