Java将GeoHash转化为对应的经纬度坐标实例代码
本文实例介绍了JAVA实现将GeoHash转化为对应的经纬度坐标的详细代码,分享给大家供大家参考,具体内容如下
packagecom.lulei.geo;
importjava.util.ArrayList;
importjava.util.Arrays;
importjava.util.HashMap;
importjava.util.List;
importcom.lulei.geo.bean.LocationBean;
importcom.lulei.util.JsonUtil;
publicclassGeoHash{
privateLocationBeanlocation;
/**
*12500km;2630km;378km;430km
*52.4km;6610m;776m;819m
*/
privateinthashLength=8;//经纬度转化为geohash长度
privateintlatLength=20;//纬度转化为二进制长度
privateintlngLength=20;//经度转化为二进制长度
privatedoubleminLat;//每格纬度的单位大小
privatedoubleminLng;//每个经度的单位大小
privatestaticfinalchar[]CHARS={'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'};
privatestaticHashMap<Character,Integer>CHARSMAP;
static{
CHARSMAP=newHashMap<Character,Integer>();
for(inti=0;i<CHARS.length;i++){
CHARSMAP.put(CHARS[i],i);
}
}
publicGeoHash(doublelat,doublelng){
location=newLocationBean(lat,lng);
setMinLatLng();
}
publicintgethashLength(){
returnhashLength;
}
/**
*@Author:lulei
*@Description:设置经纬度的最小单位
*/
privatevoidsetMinLatLng(){
minLat=LocationBean.MAXLAT-LocationBean.MINLAT;
for(inti=0;i<latLength;i++){
minLat/=2.0;
}
minLng=LocationBean.MAXLNG-LocationBean.MINLNG;
for(inti=0;i<lngLength;i++){
minLng/=2.0;
}
}
/**
*@return
*@Author:lulei
*@Description:求所在坐标点及周围点组成的九个
*/
publicList<String>getGeoHashBase32For9(){
doubleleftLat=location.getLat()-minLat;
doublerightLat=location.getLat()+minLat;
doubleupLng=location.getLng()-minLng;
doubledownLng=location.getLng()+minLng;
List<String>base32For9=newArrayList<String>();
//左侧从上到下3个
StringleftUp=getGeoHashBase32(leftLat,upLng);
if(!(leftUp==null||"".equals(leftUp))){
base32For9.add(leftUp);
}
StringleftMid=getGeoHashBase32(leftLat,location.getLng());
if(!(leftMid==null||"".equals(leftMid))){
base32For9.add(leftMid);
}
StringleftDown=getGeoHashBase32(leftLat,downLng);
if(!(leftDown==null||"".equals(leftDown))){
base32For9.add(leftDown);
}
//中间从上到下3个
StringmidUp=getGeoHashBase32(location.getLat(),upLng);
if(!(midUp==null||"".equals(midUp))){
base32For9.add(midUp);
}
StringmidMid=getGeoHashBase32(location.getLat(),location.getLng());
if(!(midMid==null||"".equals(midMid))){
base32For9.add(midMid);
}
StringmidDown=getGeoHashBase32(location.getLat(),downLng);
if(!(midDown==null||"".equals(midDown))){
base32For9.add(midDown);
}
//右侧从上到下3个
StringrightUp=getGeoHashBase32(rightLat,upLng);
if(!(rightUp==null||"".equals(rightUp))){
base32For9.add(rightUp);
}
StringrightMid=getGeoHashBase32(rightLat,location.getLng());
if(!(rightMid==null||"".equals(rightMid))){
base32For9.add(rightMid);
}
StringrightDown=getGeoHashBase32(rightLat,downLng);
if(!(rightDown==null||"".equals(rightDown))){
base32For9.add(rightDown);
}
returnbase32For9;
}
/**
*@paramlength
*@return
*@Author:lulei
*@Description:设置经纬度转化为geohash长度
*/
publicbooleansethashLength(intlength){
if(length<1){
returnfalse;
}
hashLength=length;
latLength=(length*5)/2;
if(length%2==0){
lngLength=latLength;
}else{
lngLength=latLength+1;
}
setMinLatLng();
returntrue;
}
/**
*@return
*@Author:lulei
*@Description:获取经纬度的base32字符串
*/
publicStringgetGeoHashBase32(){
returngetGeoHashBase32(location.getLat(),location.getLng());
}
/**
*@paramlat
*@paramlng
*@return
*@Author:lulei
*@Description:获取经纬度的base32字符串
*/
privateStringgetGeoHashBase32(doublelat,doublelng){
boolean[]bools=getGeoBinary(lat,lng);
if(bools==null){
returnnull;
}
StringBuffersb=newStringBuffer();
for(inti=0;i<bools.length;i=i+5){
boolean[]base32=newboolean[5];
for(intj=0;j<5;j++){
base32[j]=bools[i+j];
}
charcha=getBase32Char(base32);
if(''==cha){
returnnull;
}
sb.append(cha);
}
returnsb.toString();
}
/**
*@parambase32
*@return
*@Author:lulei
*@Description:将五位二进制转化为base32
*/
privatechargetBase32Char(boolean[]base32){
if(base32==null||base32.length!=5){
return'';
}
intnum=0;
for(booleanbool:base32){
num<<=1;
if(bool){
num+=1;
}
}
returnCHARS[num%CHARS.length];
}
/**
*@parami
*@return
*@Author:lulei
*@Description:将数字转化为二进制字符串
*/
privateStringgetBase32BinaryString(inti){
if(i<0||i>31){
returnnull;
}
Stringstr=Integer.toBinaryString(i+32);
returnstr.substring(1);
}
/**
*@paramgeoHash
*@return
*@Author:lulei
*@Description:将geoHash转化为二进制字符串
*/
privateStringgetGeoHashBinaryString(StringgeoHash){
if(geoHash==null||"".equals(geoHash)){
returnnull;
}
StringBuffersb=newStringBuffer();
for(inti=0;i<geoHash.length();i++){
charc=geoHash.charAt(i);
if(CHARSMAP.containsKey(c)){
StringcStr=getBase32BinaryString(CHARSMAP.get(c));
if(cStr!=null){
sb.append(cStr);
}
}
}
returnsb.toString();
}
/**
*@paramgeoHash
*@return
*@Author:lulei
*@Description:返回geoHash对应的坐标
*/
publicLocationBeangetLocation(StringgeoHash){
StringgeoHashBinaryStr=getGeoHashBinaryString(geoHash);
if(geoHashBinaryStr==null){
returnnull;
}
StringBufferlat=newStringBuffer();
StringBufferlng=newStringBuffer();
for(inti=0;i<geoHashBinaryStr.length();i++){
if(i%2!=0){
lat.append(geoHashBinaryStr.charAt(i));
}else{
lng.append(geoHashBinaryStr.charAt(i));
}
}
doublelatValue=getGeoHashMid(lat.toString(),LocationBean.MINLAT,LocationBean.MAXLAT);
doublelngValue=getGeoHashMid(lng.toString(),LocationBean.MINLNG,LocationBean.MAXLNG);
LocationBeanlocation=newLocationBean(latValue,lngValue);
location.setGeoHash(geoHash);
returnlocation;
}
/**
*@parambinaryStr
*@parammin
*@parammax
*@return
*@Author:lulei
*@Description:返回二进制对应的中间值
*/
privatedoublegetGeoHashMid(StringbinaryStr,doublemin,doublemax){
if(binaryStr==null||binaryStr.length()<1){
return(min+max)/2.0;
}
if(binaryStr.charAt(0)=='1'){
returngetGeoHashMid(binaryStr.substring(1),(min+max)/2.0,max);
}else{
returngetGeoHashMid(binaryStr.substring(1),min,(min+max)/2.0);
}
}
/**
*@paramlat
*@paramlng
*@return
*@Author:lulei
*@Description:获取坐标的geo二进制字符串
*/
privateboolean[]getGeoBinary(doublelat,doublelng){
boolean[]latArray=getHashArray(lat,LocationBean.MINLAT,LocationBean.MAXLAT,latLength);
boolean[]lngArray=getHashArray(lng,LocationBean.MINLNG,LocationBean.MAXLNG,lngLength);
returnmerge(latArray,lngArray);
}
/**
*@paramlatArray
*@paramlngArray
*@return
*@Author:lulei
*@Description:合并经纬度二进制
*/
privateboolean[]merge(boolean[]latArray,boolean[]lngArray){
if(latArray==null||lngArray==null){
returnnull;
}
boolean[]result=newboolean[lngArray.length+latArray.length];
Arrays.fill(result,false);
for(inti=0;i<lngArray.length;i++){
result[2*i]=lngArray[i];
}
for(inti=0;i<latArray.length;i++){
result[2*i+1]=latArray[i];
}
returnresult;
}
/**
*@paramvalue
*@parammin
*@parammax
*@return
*@Author:lulei
*@Description:将数字转化为geohash二进制字符串
*/
privateboolean[]getHashArray(doublevalue,doublemin,doublemax,intlength){
if(value<min||value>max){
returnnull;
}
if(length<1){
returnnull;
}
boolean[]result=newboolean[length];
for(inti=0;i<length;i++){
doublemid=(min+max)/2.0;
if(value>mid){
result[i]=true;
min=mid;
}else{
result[i]=false;
max=mid;
}
}
returnresult;
}
publicstaticvoidmain(String[]args){
//TODOAuto-generatedmethodstub
GeoHashg=newGeoHash(40.221227,116.24875);
StringgeoHash=g.getGeoHashBase32();
System.out.println(geoHash);
LocationBeanbean=g.getLocation(geoHash);
System.out.println(JsonUtil.parseJson(bean));
System.out.println(newGeoHash(bean.getLat(),bean.getLng()).getGeoHashBase32());
System.out.println(DistanceUtil.getDistance(bean.getLat(),bean.getLng(),bean.getLat()-g.minLat,bean.getLng()-g.minLng));
}
}
以上就是本文的详细内容,希望对大家的学习有所帮助。