加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 找到与所选点特定距离的所有地址的最佳方法是什么?

发布时间:2020-12-14 05:10:50 所属栏目:Java 来源:网络整理
导读:我正在开发一个应用程序,该应用程序应该显示位于特定位置的地址.我知道如何找到两点之间的距离,但问题是我不知道在性能方面是什么最好的方法. 一种方法是检索所有地址并逐个检查它们到后端的所选地址,但是有没有办法最小化从数据库检索的项目数量,而不是使用
我正在开发一个应用程序,该应用程序应该显示位于特定位置的地址.我知道如何找到两点之间的距离,但问题是我不知道在性能方面是什么最好的方法.

一种方法是检索所有地址并逐个检查它们到后端的所选地址,但是有没有办法最小化从数据库检索的项目数量,而不是使用内存?最好的做法是什么?

想象一下,我有30万条记录,我必须检索它们,并计算他们到所选点的距离?正如詹姆斯所建议的,我可以在不同地区记录记录,并计算距离,那么哪种方法可以很好地跟踪,通过查询或Java进行距离计算?

public class Address{
    long Id;
    Double latitude;
    Double longitude;
    ..
  }

Calculation

public static double distFrom(double lat1,double lng1,double lat2,double lng2) {
  double earthRadius = 3958.75;
  double dLat = Math.toRadians(lat2-lat1);
  double dLng = Math.toRadians(lng2-lng1);
  double sindLat = Math.sin(dLat / 2);
  double sindLng = Math.sin(dLng / 2);
  double a = Math.pow(sindLat,2) + Math.pow(sindLng,2)
        * Math.cos(Math.toRadians(lat1)) *     Math.cos(Math.toRadians(lat2));
  double c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a));
  double dist = earthRadius * c;

  return dist;
}

This question和this one提供了通过mysql计算距离的方法,但哪个方法是更好的Java或mysql我很困惑.

解决方法

当我在MySQL中实现这个(在一个扁平的球体上存储的地方,这基本上是什么(我假设你正在谈论地球!)),我已经在数据库中存储了尽可能多的预先计算的信息.所以,对于存储纬度和经度的行,我也在插入时计算以下字段:

>弧度长度(Math.toRadians(经度))
> sinRadiansLatitude(Math.sin(Math.toRadians(纬度))
> cosRadiansLatitude(Math.cos(Math.toRadians(latitude))

那么当我搜索有关纬度/经度X单位内的地方时,我的准备声明如下:

from Location l where
    acos(
        sin(:latitude) * sinRadiansLatitude + 
        cos(:latitude) * cosRadiansLatitude * 
        cos(radiansLongitude - :longitude) 
        ) * YYYY < :distance
    and l.latitude>:minimumSearchLatitude
    and l.latitude<:maximumSearchLatitude 
    and l.longitude>:minimumSearchLongitude 
    and l.longitude<:maximumSearchLongitude 
    order by acos(
                sin(:latitude) * sinRadiansLatitude + 
                cos(:latitude) * cosRadiansLatitude * 
                cos(radiansLongitude - :longitude)  
        ) * YYYY asc

其中YYYY = 3965可以给出距离以英里或YYYY = 6367可以用于距离公里.

最后,在数据库执行任何计算之前,我已经使用maximumSearchLatitude / maximumSearchLongitude / minimumSearchLongitude / maximumSearchLongitude参数来排除结果集中的大部分点.你可能会也可能不需要这个.如果你这样做,这将取决于你为这些参数选择什么值,因为它将取决于你正在搜索的内容.

显然,数据库中索引的明智应用是必要的.

使用这种方法的好处是,每次都不需要更改的信息只能计算一次,而每次执行搜索时计算每行的弧度长度,sinRadiansLatitude,cosRadiansLatitude的值将非常快速地计算.

另一个选项是使用geospatial index,这意味着所有这些都由数据库为您处理.我不知道Hibernate如何整合.

免责声明:自从我看了这么久以后,我不是GIS专家!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读