Created
August 6, 2014 08:42
-
-
Save yeluolanyan/bc047d337f6cfeb0cb55 to your computer and use it in GitHub Desktop.
Java,Mysql-根据一个给定经纬度的点,进行附近500米地点查询–合理利用算法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
最近做一个项目:需要查询一个站点(已知该站点经纬度)500米范围内的其它站点。所以,我首先想到的是,对每条记录,去进行遍历,跟数据库中的每一个点进行距离计算,当距离小于500米时,认为匹配。这样做确实能够得到结果,但是效率极其低下,因为每条记录都要去循环匹配n条数据,其消耗的时间可想而知。 | |
于是我就想到一个先过滤出大概的经纬度范围再进行计算。比方说正方形的四个点,于是我在网上搜索,意外的,查询到了一个关于这个计算附近地点搜索初探,里面使用python实现了这个想法。所以参考了一下原文中的算法,使用JAVA进行了实现。 | |
实现原理也是很相似的,先算出该点周围的矩形的四个点,然后使用经纬度去直接匹配数据库中的记录。 | |
思路:首先算出“给定坐标附近500米”这个范围的坐标范围。 虽然它是个圆,但我们可以先求出该圆的外接正方形,然后拿正方形的经纬度范围去搜索数据库。 | |
红色部分为要求的搜索范围,绿色部分我们能间接得到的结果范围 | |
先来求东西两侧的的范围边界。在haversin公式中令φ1 = φ2,可得 | |
用Java代码写就是 | |
//先计算查询点的经纬度范围lat已知纬度,lng已知经度 | |
double r = 6371;//地球半径千米 | |
double dis = 0.5;//0.5千米距离 | |
double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(lat*Math.PI/180)); | |
dlng = dlng*180/Math.PI;//角度转为弧度 | |
double dlat = dis/r; | |
dlat = dlat*180/Math.PI; | |
最后,就可以得出四个点的坐标: | |
left-top : (lat + dlat, lng – dlng) | |
right-top : (lat + dlat, lng + dlng) | |
left-bottom : (lat – dlat, lng – dlng) | |
right-bottom: (lat – dlat, lng + dlng) | |
综合也就是这样进行筛选查询 | |
public List<Property> findNeighPosition(double longitude,double latitude){ | |
//先计算查询点的经纬度范围 | |
double r = 6371;//地球半径千米 | |
double dis = 0.5;//0.5千米距离 | |
double dlng = 2*Math.asin(Math.sin(dis/(2*r))/Math.cos(latitude*Math.PI/180)); | |
dlng = dlng*180/Math.PI;//角度转为弧度 | |
double dlat = dis/r; | |
dlat = dlat*180/Math.PI; | |
double minlat =latitude-dlat; | |
double maxlat = latitude+dlat; | |
double minlng = longitude -dlng; | |
double maxlng = longitude + dlng; | |
String hql = "from Property where longitude>=? and longitude =<? and latitude>=? latitude=<? and state=0"; | |
Object[] values = {minlng,maxlng,minlat,maxlat}; | |
List<Property> list = find(hql, values); | |
return list; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment