小东Freeman + 关注

签名:我们爱我们的倒霉工作,也爱这千疮百孔的世界。

Java通过算法计算当前位置附近几公里经纬度

发表于 1个月前   235次查看    1评论  4 赞

最近做项目,经常要基于当前位置查找附近的人或店铺,之前写过一种关于数据库的查询方式,但是感觉数据上几百万条后查询速度很慢,所以研究了下算法,把当前位置的几公里内的外接正方形的经纬度求出来,如下图所示,然后再对数据库进行范围搜索即可,加上BTREE索引就能实现很快的查询了,下面把源码贴一下。


20150727204614746.png

Java源码

/**
    * 附近选择
    * @param longitude    经度
    * @param latitude 纬度
    * @param distance 搜索范围
    * @return 经纬度范围
    */
   public static Map findNeighDrugstore(double longitude,double latitude, double distance) {

      double minlat = 0;
      double maxlat = 0;
      double minlng = 0;
      double maxlng = 0;

      // 先计算查询点的经纬度范围
      double r = 6371;// 地球半径千米
      double dis = distance;// 距离(单位:千米)
      double dlng = 2 * Math.asin(Math.sin(dis / (2 * r))
            / Math.cos(longitude * Math.PI / 180));
      dlng = dlng * 180 / Math.PI;// 角度转为弧度
      double dlat = dis / r;
      dlat = dlat * 180 / Math.PI;
      if (dlng < 0) {
         minlng = longitude + dlng;
         maxlng = longitude - dlng;
      } else {
         minlng = longitude - dlng;
         maxlng = longitude + dlng;
      }
      if (dlat < 0) {
         minlat = latitude + dlat;
         maxlat = latitude - dlat;
      } else {
         minlat = latitude - dlat;
         maxlat = latitude + dlat;
      }
Map<String,Object> params=new HashMap<>();
      params.put("minlat",minlat);//纬度底
      params.put("maxlat",maxlat);//纬度顶
      params.put("minlng",minlng);//经度底
      params.put("maxlng",maxlng);//经度顶


      return params;
   }


测试下数据

public static void main(String[] args){
   double lng=120.396592;
   double lat=36.309051;
   double distance=5;
   System.out.println(NearbyUtils.findNeighDrugstore(lng,lat,distance));
}

得到的结果:

{maxlat=36.35401708029593, minlat=36.26408491970406, minlng=120.30772314151989, maxlng=120.48546085848011}


然后就可以进行数据库的查询了

SELECT
	id,
	shop_name
FROM
	qp_shop
WHERE
lng > 120.30772314151989
AND lng < 120.48546085848011
AND lat > 36.26408491970406
AND lat < 36.35401708029593

这样就可以了,给经纬度加上索引就能实现快速的查询了。

4人已赞


本文由Fun言网 – 小东Freeman创作,转载请务必附上本文链接和出处,欢迎参与我们的付费投稿计划


你还没有登录,请先 登录注册!
文章评论1