最近研究了一下如何根据地址查询获得经纬度,然后再由经纬度获得两点间距离的问题。
(1)首先如何根据地址去查询经纬度
(2)获得了经纬度如何在计算两点之间的距离
(1)
首先第一个问题,如何根据地址去查询经纬度。这应该和GPS定位有关吧,GPS是美国等使用的全球定位系统;而中国的有北斗;而欧洲的也有一套定位的东西。使用定位系统的话,一般可能是根据三颗或者是4颗以上的卫星才能定位,这是GPS的方式。扯远了,还是回归查询经纬度信息上来。一般的话可以利用百度地图相关API(或者百度的)或者是Google map相关的东西进行查询。网站如百度的有一个可以在地址和经纬度双向转换查询的http://api.4vtk.com/map/baidu.html 百度拾取坐标系统 ;谷歌的http://www.gpsspg.com/maps.htm; 在说一个高德地图的http://cloud.sinyway.com/Service/amap.html 都是很好用的吧。
在使用API或者开发是,可以参考网上的一些文章,具体的如http://www.cnblogs.com/jianglan/archive/2013/05/31/3108646.html ;
http://gundumw100.iteye.com/blog/1932024 等等吧,如果觉得不好用可以继续在网上找,我这里借用一位仁兄的代码:
//-------------------------》关键代码根据地址获得坐标《--------------------------------
public void getPoint(info_rescueteam shop){
try {
String sCurrentLine;
String sTotalString;
sCurrentLine = "";
sTotalString = "";
java.io.InputStream l_urlStream;
java.net.URL l_url = new java.net.URL("http://api.map.baidu.com/geocoder/v2/?address="+shop.getRs_address().replaceAll(" ", "")+"&output=json&ak=702632E1add3d4953d0f105f27c294b9&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();
// System.out.println(str);
//用经度分割返回的网页代码
String s=","+"\""+"lat"+"\""+":";
String strs[]=str.split(s, 2);
String s1="\""+"lng"+"\""+":";
String a[]=strs[0].split(s1, 2);
//截取小数点后8位
// System.out.println(a[1]);
shop.setLongitudes(a[1].substring(0,12));
s1="}"+","+"\"";
String a1[]=strs[1].split(s1, 2);
//截取小数点后8为
shop.setLatitudes(a1[0].substring(0,11));
} catch (Exception e) {
e.printStackTrace();
}
}
这里就是向百度地图API发送一个包含有地址请求经纬度的HTTP请求,返回的数据格式为json数据格式
.......{...."lat":"37.19283949584","lng":"113.2938473849"}...一个类似这样的数据格式,具体的可以运行一下,就可以看到。
这样通过处理就可以获得相应的经纬度了。
(2)通过经纬度如何计算它们之间的距离
刚开始的想法是,将目标地点的经纬度和起始地的经纬度,两者按照坐标差的平方和的形式,即二维坐标中两点距离公式计算。汗颜啊,原谅我是个门外汉啊。
其实由球面相关计算公式,如何你也不慎了解,可以参考http://www.cnblogs.com/ycsfwhh/archive/2010/12/20/1911232.html 。根据那个计算公式,可以计算出获得两点经纬度后,其“球面距离上的大概地址”。加了引号,因为隐隐约约感觉这个叫法有点不恰当。
R*arccos(cos(lat1*pi()/180 )*cos(lat2*pi()/180)*cos(lng1*pi()/180 -lng2*pi()/180)+
sin(lat1*pi()/180 )*sin(lat2*pi()/180))
=Distance
这里经纬度为度数(单位)。(lat1,lng1)(lat2,lng2) ,pi() 是pi, R为地球半径;如果使用弧度,可以参考上面网址
如果是像导航那样计算路途距离,这里可能还是有问题的,很错落;但是如果仅仅为了计算两地一个大概的距离,还是可以的。
附上一段代码:
private final double pi = Math.PI;
private final double R=6370996.81;//地球半径 m
//事故地点经纬度
private final static BigDecimal loc_lng = new BigDecimal(111.697329);
private final static BigDecimal loc_lat = new BigDecimal(36.565719);
//由经纬度计算距离公式
/*
R*arccos(cos(lat1*pi()/180 )*cos(lat2*pi()/180)*cos(lng1*pi()/180 -lng2*pi()/180)+
sin(lat1*pi()/180 )*sin(lat2*pi()/180))
*/
//注意计算是采用度数,使用上面公式即可,(lat1,lng1)(lat2,lng2) ,pi() 是pi, R为地球半径;如果使用弧度,可以参考上面网址。
BigDecimal t_lng = new BigDecimal(Double.parseDouble(listTeam.get(i).getLongitudes()));
BigDecimal t_lat = new BigDecimal(Double.parseDouble(listTeam.get(i).getLatitudes()));
/*t_lng = t_lng.subtract(lng);
t_lat = t_lat.subtract(lat) ;
t_lng = t_lng.pow(2);
t_lat = t_lat.pow(2);*/
//BigDecimal ti_dis = t_lng.add(t_lat) ;
double tid_lng = t_lng.doubleValue();
double tid_lat = t_lat.doubleValue();
double td_lng = lng.doubleValue();
double td_lat = lat.doubleValue();
double tid_dis = R*Math.acos(Math.cos(tid_lat*pi/180 )*Math.cos(td_lat*pi/180)*Math.cos(tid_lng*pi/180 -td_lng*pi/180)+Math.sin(tid_lat*pi/180 )*Math.sin(td_lat*pi/180));
distance_team[i] = tid_dis ;
//
(tid_lat,tid_lng) (td_lat,td_lng)
刚开始用了BigDecimal类型,然后感觉用Double也可以吧。
小结,也许是用的东西久了,结果遇到个公式(由经纬度计算距离的那个)竟然研究了好久。以前自己数学还是挺好的,现在只知其然不知其所以然啊,需要加强数学功底啊。