黄尾屿地理坐标标转化成经纬度

地址到经纬度坐标转化的JAVA代码
字体:[ ] 类型:转载 时间:
这篇文章介绍了地址到经纬度坐标转化的JAVA代码,有需要的朋友可以参考一下
任务:有1000多条门店信息(放在excel中,包括地址,店名,电话等,但是没有经纬度坐标),老大让我用地址通过百度地图拾取坐标系统找到相应的坐标,然后加上坐标后更新到公司的数据库。
失败的方案:1、使用按键精灵,按键精灵是一个模仿键盘鼠标操作的软件,用来写动作脚本的,由于时间紧,没怎么研究,因为整套动作太复杂了按键精灵尝试了下不行就放弃了。
2、表单填充工具(就是把exel表格批量提交到网页),什么风越、乌溜漆(特别是这乌溜漆,还要钱,坑货)都尝试了下,结果都不满意。因为我要把excel中的内容提交到网页还要从网页获得相应的内容,所以这些用于批量注册的软件用不上。
解决方案:最后还是干起了我本行---写代码,把问题解决了。思路是:通过传入地址作为参数拼接url调用百度地图,然后解析返回的页面,提取经纬度坐标。
以下为具体步骤
1、修改excel表中的属性名(方便后面用查询读取)然后倒入到数据库。
2、代码实现
代码如下:public class ShopInfo {& &&& private S& &&& private S& &&& private S& &&& private S//手机&& &&& private S//座机&& &&& private S& &&& private S//经度&& &&& private S//纬度&& &&& public ShopInfo() {& &&& }& //....get和set方法&
关键代码& 模拟http和解析返回的数据:
代码如下:/* &* 管理数据库连接的类 &*/& public class DbManager{& &&& private Connection con =& &&& private Statement sta =& &&& private ResultSet rs =& &&& private PreparedStatement ps =& &&&&& &&& private Connection cons =& &&& private Statement stas =& &&& private ResultSet rss =& &&& private PreparedStatement pss =& &&&&& &&&&& &&& //连接本地mysql参数 ?后面的参数是解决中文乱码的&& &&& private String MYSQLDRIVER="com.mysql.jdbc.Driver" ;& &&& private String CONTENT="jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8";& &&& private String UN="***";& &&& private String UP="****";& &&& //连接服务器mysql参数&& &&& private String MYSQLDRIVER1="com.mysql.jdbc.Driver" ;& &&& private String CONTENT1="jdbc:mysql://***********:3306/test?useUnicode=true&characterEncoding=utf8";& &&& private String UN1="*******";& &&& private String UP1="****";& & &&& public DbManager()& &&& {& &&&&&&& try {& &&&&&&&&&&& Class.forName(MYSQLDRIVER);& &&&&&&&&&&& System.out.println("加载MySQL驱动...");& &&&&&&&&&&& con = DriverManager.getConnection(CONTENT,UN,UP);& &&&&&&&&&&& sta = con.createStatement();& &&&&&&&&&&& System.out.println("连接本地数据库成功!!");& &&&&&&&&&&& Class.forName(MYSQLDRIVER1);& &&&&&&&&&&& System.out.println("加载MySQL驱动...");& &&&&&&&&&&& cons = DriverManager.getConnection(CONTENT1,UN1,UP1);& &&&&&&&&&&& stas = cons.createStatement();& &&&&&&&&&&& System.out.println("连接服务器成功!!");& &&&&&&& } catch (Exception e) {& &&&&&&&&&&& e.printStackTrace();&&&&& &&&&&&& }& &&& }& & &&& public ArrayList&ShopInfo& getAll(String tablename) throws SQLException{& &&&&&&& ArrayList&ShopInfo& allShops=new ArrayList();& &&&&&&& ShopI& &&&&&&& String sql="select * from "+& &&&&&&& System.out.println(sql);& &&&&&&& rs=sta.executeQuery(sql);& &&&&&&& while(rs.next()){& &&&&&&&&&&& si=new ShopInfo();& &&&&&&&&&&& si.setAddress(rs.getString("address"));& &&&&&&&&&&& si.setDescription(rs.getString("names")+"欢迎您的光临");& &&&&&&&&&&& si.setMobile(rs.getString("keeperphone"));& &&&&&&&&&&& si.setScope(tablename);& &&&&&&&&&&& si.setPhone(rs.getString("shoptel"));& &&&&&&&&&&& getPoint(si);& &&&&&&&&&&& allShops.add(si);& &&&&&&&&&&& System.out.println("经度:"+si.getLat()+"& 纬度:"+si.getLng());& &&&&&&& }& &&&&&&& return allS& &&& }& &&& //-------------------------》关键代码根据地址获得坐标《--------------------------------&& &&& public void getPoint(ShopInfo shop){& &&&&&&&& try {&&& &&&&&&&&&&&&&&& String sCurrentL&&& &&&&&&&&&&&&&&& String sTotalS&&& &&&&&&&&&&&&&&& sCurrentLine = "";&&& &&&&&&&&&&&&&&& sTotalString = "";&&& &&&&&&&&&&&&&&& java.io.InputStream l_urlS&&& &&&&&&&&&&&&&&& java.net.URL l_url = new java.net.URL("http://api./geocoder/v2/?address="+shop.getAddress().replaceAll(" ", "")+"&output=json&ak=add3df27c294b9&callback=showLocation");&&& &&&&&&&&&&&&&&& java.net.HttpURLConnection l_connection = (java.net.HttpURLConnection) l_url.openConnection();&&& &&&&&&&&&&&&&&& l_connection.connect();&&& &&&&&&&&&&&&&&& l_urlStream = l_connection.getInputStream();&&& &&&&&&&&&&&&&&& java.io.BufferedReader l_reader = new java.io.BufferedReader(new java.io.InputStreamReader(l_urlStream));&&&& &&&&&&&&&&&&&&& String str=l_reader.readLine();& &&&&&&&&&&&&&&& //用经度分割返回的网页代码&& &&&&&&&&&&&&&&& String s=","+"\""+"lat"+"\""+":";& &&&&&&&&&&&&&&& String strs[]=str.split(s, 2);& &&&&&&&&&&&&&&& String s1="\""+"lng"+"\""+":";& &&&&&&&&&&&&&& String a[]=strs[0].split(s1, 2);& &&&&&&&&&&&&&& shop.setLng(a[1]);& &&&&&&&&&&&&&& s1="}"+","+"\"";& &&&&&&&&&&&&& String a1[]=strs[1].split(s1, 2);& &&&&&&&&&&&&&& shop.setLat(a1[0]);& &&&&&&&&&&& } catch (Exception e) {&&& &&&&&&&&&&&&&&& e.printStackTrace();&&& &&&&&&&&&&& }&&& &&& }& &&& //存入数据库&& &&& public void inputAll(ArrayList&ShopInfo& allShops){& &&&&&&& System.out.println("开始向服务器中写入");& &&&&&&& String sql2="insert into test.dc_shop (name,scope,address,phone,description,image,createtime,lat,lng) values (?,?,?,?,?,?,?,?,?)";& &&&&&&& try {& &&&&&&&&&&& pss=cons.prepareStatement(sql2);& &&&&&&&&&&& System.out.println("-------------------------等待写入数据条数: "+allShops.size());& &&&&&&&&&&& for(int i=0;i&allShops.size();i++){& &&&&&&&&&&&&&&&&&& pss.setString(1,allShops.get(i).getName());& &&&&&&&&&&&&&&& pss.setString(2, allShops.get(i).getScope());& &&&&&&&&&&&&&&& pss.setString(3, allShops.get(i).getAddress());& &&&&&&&&&&&&&&& pss.setString(4, allShops.get(i).getPhone());& &&&&&&&&&&&&&&& pss.setString(5, allShops.get(i).getDescription());& &&&&&&&&&&&&&&& pss.setString(6, null);//图片路径&& &&&&&&&&&&&&&&& pss.setString(7, allShops.get(i).getMobile());& &&&&&&&&&&&&&&& pss.setString(8, allShops.get(i).getLat());& &&&&&&&&&&&&&&& pss.setString(9, allShops.get(i).getLng());& &&&&&&&&&&&&&&& pss.executeUpdate();& &&&&&&&&&&& }& &&&&&&&&&&& pss.close();& &&&&&&&&&&& cons.close();& &&&&&&&&&&& System.out.println("---&OK");& &&&&&&& } catch (SQLException e) {& &&&&&&&&&&& // TODO Auto-generated catch block&& &&&&&&&&&&& System.out.println("向mysql中更新数据时发生异常!");& &&&&&&&&&&& e.printStackTrace();&&&&& &&&&&&& }& &&& }&
在搞个main函数调用就ok了。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具《大数据-机器学习脱产培训班》第2期,4个月成就高薪梦想,培养数据挖掘工程师,签订就业服务协议,对接50多家大数据企业 !理论+工具+实习,培养实战型数据挖掘人才!
3月27号开课(深圳),仅20席名额,报名速度!/Answer/page/dashujujiqixuexi
> R实现地理位置与经纬度相互转换
实际业务中,特别是基于LBS的服务中,后台存储了很多经纬度数据,比如车辆行驶轨迹、快餐配送地址、上门按摩地址等,所以需要批 量地理位置与经纬度的相互转换,一方面满足业务分布可视化的实现,另一方面满足实际地址的统计分析,两方面结合即可对整体业务热力区域进行把握,有针对性 的指导线下运营细化到街道、小区。
对于单个或者少数地址位置的查询,线上一些免费工具可以使用,如果批量转换则需要特殊工具或者自行编写程序转换,本文重在在于介绍如何使用R进行批量的地 理位置与经纬度相互转换(基于百度地图api的地址位置的经纬度解析与反解析,地理位置可精确到街道门牌号),第一部分会简单说明线上单个或少数地理位置 的转换。
一、单个或少数地理位置转换
1、百度地图开放平台:
想到地址位置查询第一当然想到地图,在国内当然第一想到的是百度地图,具体路径如下描述,可实现单一位置与经纬度的相互转换,满足了少量位置的需求。路 径:百度→地图→地图开放平台→地图拾取工具。通过鼠标移动点选,或者直接输入查询均可返回指定位置的经纬度。勾选“坐标反查”,输入经纬度数据(英文逗 号隔开),可反查具体地址信息。具体操作说明页面上也有详细说明。
2、其他网站:
有很多在线查询网站,其中/maps.htm可方便查询各种地图下的经纬度。
3、R软件实现城市经纬度查询:
加载REmap包,调用get_city_coord( )返回经纬度,get_geo_position( )返回批量城市的经纬度。
library(REmap)
get_city_coord(‘贵阳’)
[1] 106.675
get_geo_position(c(‘贵阳’,’益阳’,’成都’))
112..559818 益阳
13 106..652747 贵阳
104..576279 成都
二、批量地理位置转换
基于百度地图的地理位置转换需要R加载RCurl包和rjson包,使用url转换函数及结果解析函数,大概了解Geocoding API说明文档(/index.php?title=webapi/guide/webservice- geocoding)进行参数调整。步骤相对明确,代码具体如下。此方法的好处在于地理位置可以具体到街道、小区,甚至门牌单元。以下思路方法主要吸收知 乎上一用户的回帖并加以改进。
操作步骤及方法:
第一步:申请百度地图ak(即获取密钥),若无百度账号则首先需要注册百度账号。
第二步,拼写发送http请求的url,注意需使用第一步申请的ak。
第三步,接收http请求返回的数据(支持json和xml格式)。
第四步,解析返回的数据(此处使用json格式)。
第五步,转换并保存所需数据。
实例1、地理位置→经纬度(如:山西省太原市小店区亲贤北街77号→112.13)
测试数据如下(输入了一些非正常值用作测试),可自行建立txt文件(注意最后一行多打个回车),存放在R的系统文件夹中:
address_list.txt
山西省太原市小店区亲贤北街77号
贵州省贵阳市云岩区书香门第B栋3单元
北京市通州区神树商业街168号
贵州省贵阳市南明区兴关路51
北京市东城区长巷二条乙5号
山西省太原市杏花岭区北肖墙12号
北京市通州区
北京市的的的的的
天津市武清区
#导入地址列表
address &- read.table(‘address_list.txt’,header = F, col.names=c(‘address’),as.is = c(1))
address &- address$address
#转化为向量格式,备for循环使用
head(address)
[1] “山西省太原市小店区亲贤北街77号”
“贵州省贵阳市云岩区书香门第B栋3单元”
[3] “北京市通州区神树商业街168号”
“贵州省贵阳市南明区兴关路51”
[5] “北京市东城区长巷二条乙5号”
“山西省太原市杏花岭区北肖墙12号”
#建立备用向量,包括空向量及百度地图api秘钥
baidu_lng &- c()
baidu_lat &- c()
ak &- ‘HuwUWPmzvZmErI4Wnbe*************’
#百度地图api的秘钥,需自己申请
library(rjson)
library(RCurl)
#循环解析过程
for (location in address) {
#生成规则的url地址(具体参数可参考Geocoding API文档)
url &- paste(‘http://api./geocoder/v2/?ak=’,ak,’&callback=renderOption&output=json&address=’,location,sep=”)
#利用URLencode()转换为可解析的URL地址
url_string &- URLencode(url)
#通过readLines读取URL地址,并解析JSON格式的结果
json&- readLines(url_string, warn=F)
geo &- fromJSON(substr(json,regexpr(‘\\(‘,json)+1,nchar(json)-1))
#在解析结果中提取经纬度
lng&-geo$result$location$lng
lat&-geo$result$location$lat
#存储到已经建好的字段中
baidu_lng &- c(baidu_lng,lng)
baidu_lat &- c(baidu_lat,lat)
result &- data.frame(address=address,longitude=baidu_lng,latitude=baidu_lat)
address longitude latitude
山西省太原市小店区亲贤北街77号
贵州省贵阳市云岩区书香门第B栋3单元
北京市通州区神树商业街168号
贵州省贵阳市南明区兴关路51
北京市东城区长巷二条乙5号
山西省太原市杏花岭区北肖墙12号
北京市通州区
北京市的的的的的
天津市武清区
解读:地址列表必须转换成向量形式,因为数据框格式的直接参与for循环只取第一个值。经测试返回的json是带回调函数的(即不 仅仅是纯json数据,可复制url_string的结果到浏览器打开观察数据格式),所以需要substr截取json格式内容,然后传递给 fromJSON进行解析,解析的结果以列表形式存放(见geo),字段意义如下表。另外通过测试结果发现一些非正常格式数据会返回可识别内容的经纬度, 但是如果输入的地址完全没有地名对应,则程序报错,无法执行,这点要求把握原始地址数据质量。根据百度文档说明API接口默认配额6000次/天,若需更 高配额,需申请百度开发者认证(每天限额30万次)。
参考字段:
返回结果状态值, 成功返回0,其他值请查看下方返回码状态表。
经纬度坐标
位置的附加信息,是否精确查找。1为精确查找,即准确打点;0为不精确,即模糊打点。
confidence
可信度,描述打点准确度
实例2、经纬度→地理位置(如:37.2,112.→山西省太原市小店区产业路21号)
经纬度到地理位置的转换为以上过程的逆过程,在于输入内容与输出内容的互逆,解析过程是一致的。
测试数据如下,可自行建立txt文件(注意最后一行多打个回车),存放在R的系统文件夹中:
lon_lat_list.txt
112.38 37.203
112.56 37.031
112.69 37.750
112.88 37.906
112.16 37.531
112.50 37.859
112.09 37.000
112.12 37.875
112.97 37.953
112.88 37.516
#导入经纬度列表,整理成纬度在前,经度在后,英文逗号隔开的格式
lat_lng &- read.table(‘lng_lat_list.txt’, header = F, as.is=c(1,2))
lat_lng &- paste(lat_lng[,2], lat_lng[,1], sep=’,’)
head(lat_lng)
[1] “37.2,112.” “37.7,112.”
[3] “37.1,112.”
“37.1,112.”
[5] “37.4,112.” “37.7,112.”
#建立备用字段,包括空字段及百度地图api秘钥
baidu_address &- c()
ak &- ‘HuwUWPmzvZmErI4Wnbe*************’
#百度地图api的秘钥,需自己申请
library(rjson)
library(RCurl)
#循环反解析过程
for (location in lat_lng) {
#生成规则的url地址(具体参数可参考Geocoding API文档)
url &- paste(‘http://api./geocoder/v2/?ak=’,ak,’&callback=renderReverse&location=’,location,’&output=json’,sep=”)
#利用URLencode()转换为可解析的URL地址
url_string &- URLencode(url)
#通过readLines读取转换后的URL地址,并解析JSON格式的结果
json&- readLines(url_string, warn=F, encoding = ‘UTF-8’)
geo &- fromJSON(substr(json,regexpr(‘\\(‘,json)+1,nchar(json)-1))
#结果中提取格式化位置
address&-geo$result$formatted_address
#存储到已经建好的字段中
baidu_address
&-c(baidu_address,address)
result &- data.frame(lat_lng, address=baidu_address)
山西省太原市小店区产业路21号
山西省太原市杏花岭区新建路224号
山西省太原市迎泽区建设南路66号
山西省太原市小店区师范街23号
37.5,112. 山西省太原市万柏林区晋祠路1段-118
山西省太原市迎泽区迎泽大街92号
山西省太原市杏花岭区五龙口街
山西省太原市小店区北园街23-4
山西省太原市小店区电子街
10 37.5,112.
山西省太原市晋源区晋祠路
#数据导出到本地
write.table(result, ‘lat_lng_to_address.txt’)
解读:除了上面解读需要注意的,此处特殊强调几点:一是输入数据顺序为[纬度,经度],注意是纬度在前。二是生成规则的url地址 时需要设置参数output=json,否则默认生成的是XML格式。三是上例中返回的是最全的结构化地址信息,也可以取区县或者街道(具体见下表参考字 段),比如$result$addressComponent$district,对应到区县的后即可统计不同区的业务量,结合地图工具(比如与 remapC函数)可呈现业务热力图,这也是应用之一。再次强调普通用户每天每个ak配额是6000次,超过6000程序会报错。
参考字段:
返回结果状态值, 成功返回0,其他值请查看。
formatted_address
结构化地址信息
所在商圈信息,如 “人民大学,中关村,苏州街”
addressComponent
street_number
街道门牌号
行政区划代码
country_code
和当前坐标点的方向,当有门牌号的时候返回数据
和当前坐标点的距离,当有门牌号的时候返回数据
pois(周边poi数组)
和当前坐标点的方向
离坐标点距离
poi类型,如’ 办公大厦,商务大厦’
poi坐标{x,y}
poi唯一标识
sematic_description
当前位置结合POI的语义化结果描述。
特别说明:因为百度地图Geocoding和反Geocoding使用的门址数据以及算法都不是一样的,所以会出现不能一一对应的现象。
作者:金小贝
转载请注明: &
or分享 (0)君,已阅读到文档的结尾了呢~~
地理坐标、经纬度坐标与屏幕坐标的转换 内容详尽,但请以实际操作为准,欢迎下载使用
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
地理坐标、经纬度坐标与屏幕坐标的转换
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口JAVA实现将GeoHash转化为对应的经纬度坐标
在博客JAVA实现空间索引编码(GeoHash)中介绍了什么是GeoHash以及如何将坐标转化为GeoHash,这篇博客就介绍下,如何将GeoHash转化为对应区域中心点的坐标。
Base32的对应关系
在上次实现中介绍了数值和base32的对应关系,用数组保存这种对应关系;现在我们需要找到一个数据结构,可以快速的查找base32字符和数值对应关系,这样我们可以用map来保存这种关系。
private static final char[] 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'};
private static HashMap CHARSMAP;
CHARSMAP = new HashMap();
for (int i = 0; i & CHARS. i++) {
CHARSMAP.put(CHARS[i], i);
将数值转化为二进制字符串
当我们获取每个字符对应的数字之后,需要将数字转化为二进制字符串,我们可以直接调用Integer.toBinaryString方法来实现,由于我们要保证转换之后的二进制要是5位,对于小于16的,我们需要在前部补0,为了实现这个功能,我们对数字统一加上32,在转化成二进制字符串之后,再把第一位的1移除即可。
private String getBase32BinaryString(int i) {
if (i & 0 || i & 31) {
String str = Integer.toBinaryString(i + 32);
return str.substring(1);
将GeoHash转化为二进制字符串
上一步是将数值转化为五位的二进制字符串,下面我们就介绍下如何将GeoHash字符串转化为对应的二进制字符串。通过上面介绍的Base32字符和数字的对应关系,我们可以知道每个字符对应的数字,然后将这个数字转化为对应的五位二进制字符串,我们再把这些字符串拼接起来,就构成了一个完整的二进制字符串。
private String getGeoHashBinaryString(String geoHash) {
if (geoHash == null || &&.equals(geoHash)) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i & geoHash.length(); i++) {
char c = geoHash.charAt(i);
if (CHARSMAP.containsKey(c)) {
String cStr = getBase32BinaryString(CHARSMAP.get(c));
if (cStr != null) {
sb.append(cStr);
return sb.toString();
将GeoHash二进制字符串拆分成经纬度二进制字符串
在上次博客中介绍了GeoHash二进制字符串是由经纬度的二进制字符串整合而成的,其中奇数为是纬度,偶数为是经度,从而我们只需要再把GeoHash字符串拆开即可。
StringBuffer lat = new StringBuffer();
StringBuffer lng = new StringBuffer();
for (int i = 0; i & geoHashBinaryStr.length(); i++) {
if (i % 2 != 0) {
lat.append(geoHashBinaryStr.charAt(i));
lng.append(geoHashBinaryStr.charAt(i));
将经纬度二进制转化为中点对应的经纬度
上次博客介绍如何将一个经纬度转化为对应的二进制,就是看经纬度在对应的那个区域,这里我们也来对其做你运算,如果二进制字符串第一位为1,则说明经纬度在大的区域,如果为0,则在小的区域,然后我们再对所在的区域进行分割,再来判断二进制字符串的第二位是1还是0,以此类推,最后返回最后一个区域中点的值。
private double getGeoHashMid(String binaryStr, double min, double max) {
if (binaryStr == null || binaryStr.length() & 1) {
return (min + max) / 2.0;
if (binaryStr.charAt(0) == '1') {
return getGeoHashMid(binaryStr.substring(1), (min + max) / 2.0, max);
return getGeoHashMid(binaryStr.substring(1), min, (min + max) / 2.0);
运行结果检验
对于DistanceUtil 和 LocationBean几乎没有做改变,这里就不再介绍他们的。
*@Description: GeoHash实现经纬度的转化
package com.lulei.
import java.util.ArrayL
import java.util.A
import java.util.HashM
import java.util.L
import com.lulei.geo.bean.LocationB
import com.lulei.util.JsonU
public class GeoHash {
private LocationB
* 5 2.4 6 610m; 7 76m; 8 19m
private int hashLength = 8; //经纬度转化为geohash长度
private int latLength = 20; //纬度转化为二进制长度
private int lngLength = 20; //经度转化为二进制长度
private double minL//每格纬度的单位大小
private double minL//每个经度的单位大小
private static final char[] 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'};
private static HashMap CHARSMAP;
CHARSMAP = new HashMap();
for (int i = 0; i & CHARS. i++) {
CHARSMAP.put(CHARS[i], i);
public GeoHash(double lat, double lng) {
location = new LocationBean(lat, lng);
setMinLatLng();
public int gethashLength() {
return hashL
* @Author:lulei
* @Description: 设置经纬度的最小单位
private void setMinLatLng() {
minLat = LocationBean.MAXLAT - LocationBean.MINLAT;
for (int i = 0; i & latL i++) {
minLat /= 2.0;
minLng = LocationBean.MAXLNG - LocationBean.MINLNG;
for (int i = 0; i & lngL i++) {
minLng /= 2.0;
* @Author:lulei
* @Description: 求所在坐标点及周围点组成的九个
public List getGeoHashBase32For9() {
double leftLat = location.getLat() - minL
double rightLat = location.getLat() + minL
double upLng = location.getLng() - minL
double downLng = location.getLng() + minL
List base32For9 = new ArrayList();
//左侧从上到下 3个
String leftUp = getGeoHashBase32(leftLat, upLng);
if (!(leftUp == null || &&.equals(leftUp))) {
base32For9.add(leftUp);
String leftMid = getGeoHashBase32(leftLat, location.getLng());
if (!(leftMid == null || &&.equals(leftMid))) {
base32For9.add(leftMid);
String leftDown = getGeoHashBase32(leftLat, downLng);
if (!(leftDown == null || &&.equals(leftDown))) {
base32For9.add(leftDown);
//中间从上到下 3个
String midUp = getGeoHashBase32(location.getLat(), upLng);
if (!(midUp == null || &&.equals(midUp))) {
base32For9.add(midUp);
String midMid = getGeoHashBase32(location.getLat(), location.getLng());
if (!(midMid == null || &&.equals(midMid))) {
base32For9.add(midMid);
String midDown = getGeoHashBase32(location.getLat(), downLng);
if (!(midDown == null || &&.equals(midDown))) {
base32For9.add(midDown);
//右侧从上到下 3个
String rightUp = getGeoHashBase32(rightLat, upLng);
if (!(rightUp == null || &&.equals(rightUp))) {
base32For9.add(rightUp);
String rightMid = getGeoHashBase32(rightLat, location.getLng());
if (!(rightMid == null || &&.equals(rightMid))) {
base32For9.add(rightMid);
String rightDown = getGeoHashBase32(rightLat, downLng);
if (!(rightDown == null || &&.equals(rightDown))) {
base32For9.add(rightDown);
return base32For9;
* @param length
* @Author:lulei
* @Description: 设置经纬度转化为geohash长度
public boolean sethashLength(int length) {
if (length & 1) {
hashLength =
latLength = (length * 5) / 2;
if (length % 2 == 0) {
lngLength = latL
lngLength = latLength + 1;
setMinLatLng();
* @Author:lulei
* @Description: 获取经纬度的base32字符串
public String getGeoHashBase32() {
return getGeoHashBase32(location.getLat(), location.getLng());
* @param lat
* @param lng
* @Author:lulei
* @Description: 获取经纬度的base32字符串
private String getGeoHashBase32(double lat, double lng) {
boolean[] bools = getGeoBinary(lat, lng);
if (bools == null) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i & bools. i = i + 5) {
boolean[] base32 = new boolean[5];
for (int j = 0; j & 5; j++) {
base32[j] = bools[i + j];
char cha = getBase32Char(base32);
if (' ' == cha) {
sb.append(cha);
return sb.toString();
* @param base32
* @Author:lulei
* @Description: 将五位二进制转化为base32
private char getBase32Char(boolean[] base32) {
if (base32 == null || base32.length != 5) {
return ' ';
int num = 0;
for (boolean bool : base32) {
num &&= 1;
if (bool) {
return CHARS[num % CHARS.length];
* @param i
* @Author:lulei
* @Description: 将数字转化为二进制字符串
private String getBase32BinaryString(int i) {
if (i & 0 || i & 31) {
String str = Integer.toBinaryString(i + 32);
return str.substring(1);
* @param geoHash
* @Author:lulei
* @Description: 将geoHash转化为二进制字符串
private String getGeoHashBinaryString(String geoHash) {
if (geoHash == null || &&.equals(geoHash)) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i & geoHash.length(); i++) {
char c = geoHash.charAt(i);
if (CHARSMAP.containsKey(c)) {
String cStr = getBase32BinaryString(CHARSMAP.get(c));
if (cStr != null) {
sb.append(cStr);
return sb.toString();
* @param geoHash
* @Author:lulei
* @Description: 返回geoHash 对应的坐标
public LocationBean getLocation(String geoHash) {
String geoHashBinaryStr = getGeoHashBinaryString(geoHash);
if (geoHashBinaryStr == null) {
StringBuffer lat = new StringBuffer();
StringBuffer lng = new StringBuffer();
for (int i = 0; i & geoHashBinaryStr.length(); i++) {
if (i % 2 != 0) {
lat.append(geoHashBinaryStr.charAt(i));
lng.append(geoHashBinaryStr.charAt(i));
double latValue = getGeoHashMid(lat.toString(), LocationBean.MINLAT, LocationBean.MAXLAT);
double lngValue = getGeoHashMid(lng.toString(), LocationBean.MINLNG, LocationBean.MAXLNG);
LocationBean location = new LocationBean(latValue, lngValue);
location.setGeoHash(geoHash);
* @param binaryStr
* @param min
* @param max
* @Author:lulei
* @Description: 返回二进制对应的中间值
private double getGeoHashMid(String binaryStr, double min, double max) {
if (binaryStr == null || binaryStr.length() & 1) {
return (min + max) / 2.0;
if (binaryStr.charAt(0) == '1') {
return getGeoHashMid(binaryStr.substring(1), (min + max) / 2.0, max);
return getGeoHashMid(binaryStr.substring(1), min, (min + max) / 2.0);
* @param lat
* @param lng
* @Author:lulei
* @Description: 获取坐标的geo二进制字符串
private boolean[] getGeoBinary(double lat, double lng) {
boolean[] latArray = getHashArray(lat, LocationBean.MINLAT, LocationBean.MAXLAT, latLength);
boolean[] lngArray = getHashArray(lng, LocationBean.MINLNG, LocationBean.MAXLNG, lngLength);
return merge(latArray, lngArray);
* @param latArray
* @param lngArray
* @Author:lulei
* @Description: 合并经纬度二进制
private boolean[] merge(boolean[] latArray, boolean[] lngArray) {
if (latArray == null || lngArray == null) {
boolean[] result = new boolean[lngArray.length + latArray.length];
Arrays.fill(result, false);
for (int i = 0; i & lngArray. i++) {
result[2 * i] = lngArray[i];
for (int i = 0; i & latArray. i++) {
result[2 * i + 1] = latArray[i];
* @param value
* @param min
* @param max
* @Author:lulei
* @Description: 将数字转化为geohash二进制字符串
private boolean[] getHashArray(double value, double min, double max, int length) {
if (value & min || value & max) {
if (length & 1) {
boolean[] result = new boolean[length];
for (int i = 0; i & i++) {
double mid = (min + max) / 2.0;
if (value & mid) {
result[i] =
result[i] =
public static void main(String[] args) {
// TODO Auto-generated method stub
GeoHash g = new GeoHash(40.6.24875);
String geoHash = g.getGeoHashBase32();
System.out.println(geoHash);
LocationBean bean = g.getLocation(geoHash);
System.out.println(JsonUtil.parseJson(bean));
System.out.println(new GeoHash(bean.getLat(), bean.getLng()).getGeoHashBase32());
System.out.println(DistanceUtil.getDistance(bean.getLat(), bean.getLng(), bean.getLat() - g.minLat, bean.getLng() - g.minLng));
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'}

我要回帖

更多关于 黄尾屿地理坐标 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信