package geohash.impl;
import geohash.vo.BinarySearchVO;
import geohash.vo.Config;
import geohash.vo.PointAddress;
import java.math.BigDecimal;
public class GeoHashMan {
private final static char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
/**
* 获取经纬度二进制
*
* @return
*/
public static String getBinStr(PointAddress pointAddress) {
String bin = getBinStr(pointAddress, new BinarySearchVO(Config.MAX_LNG_P, Config.MAX_LNG), new BinarySearchVO(Config.MAX_LAT_P, Config.MAX_LAT), 1, "");
System.out.println(bin);
String code = base32(Long.parseLong(bin, 2));
return code;
}
public static String getBinStr(PointAddress pointAddress, BinarySearchVO searchLng, BinarySearchVO searchLat, Integer deep, String result) {
if (deep > Config.PRECISION) {
return result;
}
// 计算经度
result += getBinStrByBinary(searchLng, pointAddress.getLng());
// 计算纬度
result += getBinStrByBinary(searchLat, pointAddress.getLat());
return getBinStr(pointAddress, searchLng, searchLat, deep + 1, result);
}
private static String getBinStrByBinary(BinarySearchVO searchVO, BigDecimal address) {
BigDecimal divide = searchVO.getLeft().add(searchVO.getRight()).divide(Config.DIV, Config.SCALE, 5);
boolean isRight = address.compareTo(divide) >= 0;
if (isRight) {
searchVO.setLeft(divide);
} else {
searchVO.setRight(divide);
}
return isRight ? "1" : "0";
}
//将经纬度合并后的二进制进行指定的32位编码
private static String base32(long i) {
char[] buf = new char[65];
int charPos = 64;
boolean negative = (i < 0);
if (!negative){
i = -i;
}
while (i <= -32) {
buf[charPos--] = digits[(int) (-(i % 32))];
i /= 32;
}
buf[charPos] = digits[(int) (-i)];
if (negative){
buf[--charPos] = '-';
}
return new String(buf, charPos, (65 - charPos));
}
public static void main(String[] args) {
String binStr = getBinStr(new PointAddress(new BigDecimal("120.1175035"), new BigDecimal("30.27716182")));
System.out.println(binStr);
}
}