根据指定的经纬度查询半径为5km的地点

根据指定的经纬度从数据库中查询半径为5km的地点

1.从数据库中一个个遍历查找,然后二者之间求距离比较大小,慢!

2.先过滤出经纬度范围,在比较大小

在这里插入图片描述
在这里插入图片描述

具体代码实现:

controller:

/**
	 * 根据经纬度找范围内的数据 jfinal
	 */
	public void findNeighPosition() {
		String longitude = getPara("lng");
		String latitude = getPara("lat");
		
		renderJson(TestProductService.SERVICE.findNeighPosition(longitude, latitude));
	}

service+dao:

/**
	 * 根据经纬度查询某一个范围内的园区
	 * @param lng 中心的经度
	 * @param lat 中心的纬度
	 * @param distance 半径大小
	 * @return
	 */
	public List<CommunityGroupManagerApplication> findNeighPosition(String lng,String lat,String distance){  
		double longitude = Double.parseDouble(lng);
		double latitude = Double.parseDouble(lat);
		double dis = Double.parseDouble(distance);
        //先计算查询点的经纬度范围   
        double r = 6371;//地球半径千米  
        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 sql = "select * from sq_community_group_manager_application where lng>=? and lng <=? and lat>=? and lat<=?";
        Object[] values = {minlng,maxlng,minlat,maxlat};
          
        List<CommunityGroupManagerApplication> list = CommunityGroupManagerApplication.dao.find(sql, values);
        int len = list.size();
        //判断两点之间的距离是否大于半径
        for(int i=0;i<len;i++) {
        	if(getDistance(longitude, latitude, list.get(i).getDouble("lng"), list.get(i).getDouble("lat"))>dis) {
        		list.remove(i);
        		i--;
        		len--;
        	}
        }
        return list;  
    }
	
	/**
	 * 求两点之间的距离
	 * @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); // 反余弦值
//		System.out.println("-------"+EARTH_RADIUS * acos);
		return EARTH_RADIUS * acos; // 最终结果

	}

注意的是,第二部分的搜索范围是外接正方形,如果想只要内接圆,需要判断比较半径大小

具体的看:

https://www.cnblogs.com/zt007/p/6373722.html
https://blog.csdn.net/sunhuaqiang1/article/details/54138817

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值