Java 检查 1 公里圆内是否有长纬度

Java check if long lat in 1 km circle

我正在做一个 Java EE 项目,有一个像这样的实体:

@Entity
public class Location {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private Long messageId;

  @ManyToOne
  private User user;

  private String name;

  private Float latitude;

  private Float longitude;
}

如果这些位置在 1 公里直径的圆内,我需要用中心点过滤这些位置。

我需要这样的方法,只返回 A、B、C、E 位置。

public List<Location> findLocations(Float longitude, Float latitude) {
    List<Location> locations = 
            entityManager.createQuery("select l from Location where ???")
            .setParameter("longitude", longitude)
            .setParameter("latitude", latitude)
            .getResultList();
    return locations;
}

我找到了一些代码示例,但我必须遍历 db 上的所有位置(这将非常昂贵)

我可以直接用 createQuery() 做吗?

Note: I'm using MySQL

假设 latlong 值在赤道附近的粗略估计如下

  • 一个经度大约是 111.32 公里
  • 一个纬度大约是 110.57 公里

reference for values

由此我们可以假设

  • 经度 1 的 1km 等于 0.0089831deg
  • 纬度 1 的 1km 等于 0.009044deg

我们可以通过将以下内容添加到 Where of you sql 语句来消除大部分数据

SELECT * FROM location WHERE ( latitude BETWEEN (latValue? - 0.009044) AND (LatValue?+0.009044)) AND (longtitude BETWEEN (longValue? - 0.0089831) AND (longValue?+0.0089831));

要获得更准确的结果,您仍然需要使用 Vincenty 或 Haversine 公式过滤结果值。

编辑:

或者您也可以直接对您的查询实施 Vincenty 或 Haversine 公式。现在这样做是否更有效率,我还没有测试过。我总是将我的数据库事务保持在最低限度。以极少的计算存储和检索数据。