This question already has answers here:
Use MySQL spatial extensions to select points inside circle

(8个答案)


4年前关闭。




我正在一个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 km的圆中,则需要使用中心点过滤这些位置。

java - Java检查1公里以内的纬度是否很长-LMLPHP

我需要这样的方法,仅返回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()吗?

注意:我使用的是MySQL

最佳答案

假设对latlong值在赤道附近进行粗略估计,如下

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

  • reference for values

    由此我们可以假设
  • 1公里经度等于0.0089831deg
  • 1公里的纬度等于0.00944deg

  • 我们可以通过在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公式。现在这样做是否更有效,我尚未测试。我总是尽量减少数据库事务。使用非常少的计算来存储和检索数据。

    08-16 08:53