根据一个经纬度查询附近的楼盘信息

最近做一个项目,需要查询一个门店3公里范围内的所有楼盘信息

实现原理

先算出该点周围的矩形的四个点,然后使用经纬度去直接匹配数据库中的记录。

java代码

/**
     * 根据传入的经纬度和半径范围确定附近的经纬度范围
     *
     * @param longitude 经度
     * @param latitude 纬度
     * @param distance 距离 多少千米
     * @return */ 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; } 

经纬度格式校验

/**
     * 经纬度校验
     * 经度longitude: (?:[0-9]|[1-9][0-9]|1[0-7][0-9]|180)\\.([0-9]{6})
     * 纬度latitude:  (?:[0-9]|[1-8][0-9]|90)\\.([0-9]{6})
     *
     * @return
     */
    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; } 

求两点之间的距离

    /**
     * 求两点之间的距离
     * @param lng1 A点经度
     * @param lat1 A点纬度
     * @param lng2 B点经度
     * @param lat2 B点纬度 * @return 两点距离 */ public static double getDistance(double lng1, double lat1, double lng2, double lat2) { double EARTH_RADIUS = 6371; double radiansAX = Math.toRadians(lng1); // A经弧度 double radiansAY = Math.toRadians(lat1); // A纬弧度 double radiansBX = Math.toRadians(lng2); // B经弧度 double radiansBY = Math.toRadians(lat2); // B纬弧度 // 公式中“cosβ1cosβ2cos(α1-α2)+sinβ1sinβ2”的部分,得到∠AOB的cos值 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

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} 

得到的结果进行比较删除

因为得到的结果是个正方形方位内的数据,想要在地图上显示,会发现超过了地图上圆圈外也有数据,这时候就需要再做一下处理。

//判断两点之间的距离是否大于半径,大于的删除
for (int i = 0; i < 之前查询结果的len; i++) {
	double distance = LocationUtil.getDistance(longitude, latitude, longitude1, latitude1); if (distance > kilometer) { list.remove(i); i--; len--; } } 

处理之后不不会出现全外面数据显示的情况了!

猜你喜欢

转载自www.cnblogs.com/1994jinnan/p/13369502.html