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)); } }
以上就是本文的详细内容,希望对大家的学习有所帮助。