根据一个经纬度查询附近的楼盘信息
最近做一个项目,需要查询一个门店3公里范围内的所有楼盘信息
实现原理
先算出该点周围的矩形的四个点,然后使用经纬度去直接匹配数据库中的记录。
java代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
public static Location getNearbyLocation(double longitude, double latitude, double distance) {
boolean b = LocationUtil.checkItude(longitude + "", latitude + "");
if (!b) { return null; }
double r = 6371; double dlng = 2 * Math.asin(Math.sin(distance / (2 * r)) / Math.cos(latitude * Math.PI / 180)); dlng = dlng * 180 / Math.PI; double dlat = distance / r; dlat = dlat * 180 / Math.PI; double minlat = latitude - dlat; double maxlat = latitude + dlat; double minlng = longitude - dlng; double maxlng = longitude + dlng;
Location location = new Location(); location.setLatitude(latitude); location.setLongitude(longitude); location.setMaxLatitude(maxlat + ""); location.setMinLatitude(minlat + ""); location.setMaxLongitude(maxlng + ""); location.setMinLongitude(minlng + ""); return location; }
|
经纬度格式校验
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
public static boolean checkItude(String longitude, String latitude) { String reglo = "((?:[0-9]|[1-9][0-9]|1[0-7][0-9])\\.([0-9]{0,6}))|((?:180)\\.([0]{0,6}))"; String regla = "((?:[0-9]|[1-8][0-9])\\.([0-9]{0,6}))|((?:90)\\.([0]{0,6}))"; longitude = longitude.trim(); latitude = latitude.trim(); return longitude.matches(reglo) == true ? latitude.matches(regla) : false; }
|
求两点之间的距离
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public static double getDistance(double lng1, double lat1, double lng2, double lat2) { double EARTH_RADIUS = 6371; double radiansAX = Math.toRadians(lng1); double radiansAY = Math.toRadians(lat1); double radiansBX = Math.toRadians(lng2); double radiansBY = Math.toRadians(lat2);
double cos = Math.cos(radiansAY) * Math.cos(radiansBY) * Math.cos(radiansAX - radiansBX) + Math.sin(radiansAY) * Math.sin(radiansBY); double acos = Math.acos(cos); return EARTH_RADIUS * acos; }
|
拿到4个确定范围的经纬度就可以去数据库查询了,由于数据库经纬度存的是一个字段需要切割下字段(使用的是Mysql),在 原本的条件下拼接上范围条件就完成!
条件sql
1 2 3 4
| substring( location, 1, LOCATE ( ',', location ) - 1 ) >= #{minLongitude} AND substring( location, 1, LOCATE ( ',', location ) - 1 ) <= #{maxLongitude} AND substring( location, LOCATE ( ',', location ) + 1, LENGTH ( a.location ) - 1 ) >= #{minLatitude} AND substring( location, LOCATE ( ',', location ) + 1, LENGTH ( a.location ) - 1 ) <= #{maxLatitude}
|
得到的结果进行比较删除
因为得到的结果是个正方形方位内的数据,想要在地图上显示,会发现超过了地图上圆圈外也有数据,这时候就需要再做一下处理。
1 2 3 4 5 6 7 8 9
| for (int i = 0; i < 之前查询结果的len; i++) { double distance = LocationUtil.getDistance(longitude, latitude, longitude1, latitude1); if (distance > kilometer) { list.remove(i); i--; len--; } }
|
处理之后不不会出现全外面数据显示的情况了!