在 java 或一些高级 postgis 查询中使用 haversine 公式?

Use haversine formula in java or some advanced postgis queries?

假设我们有一个 table,其中包含纬度和经度(数字)列、范围列、名称列等。

我们有一个输入 - 坐标纬度和经度

我想构建一个查询以仅获取此 table 中的行,与 输入坐标 的距离(以米为单位)小于 范围列.

问题是,如何最有效地做到这一点?

我可以想象这样做: 首先,对百万条记录进行一些“第一次切割”(driver_users) - 我将对 select 坐标 BETWEEN 和 max 应用经典查询...因此,我们将减少收集的行数,然后我们将对每一行应用 haversine 公式并将其与 范围列 中的值进行比较。问题还在于如何计算截止值的最小值和最大值。假设距 输入坐标 最多 50 公里 - 我认为也可能是正方形,因为它只是初始 select 以减少半正弦公式的使用次数。

但我不确定,这是否真的有效。我正在使用 java(spring 引导)、hibernate/jpa 和 postgresql。 SQL table 不好也可以完全重制。谢谢。

CREATE TABLE public.driver_users
(
    username character varying(100) NOT NULL,
    longitude numeric,
    latitude numeric,
    range integer NOT NULL,
    UNIQUE (username),
    FOREIGN KEY (username)
        REFERENCES public.users (username) MATCH SIMPLE
        ON UPDATE CASCADE
        ON DELETE CASCADE,
    CONSTRAINT driver_users_pkey PRIMARY KEY (username)
);

使用PostGIS可以让您使用很多功能,包括距离计算、投影处理、空间索引等

对于您的任务,您将创建一个 geography 列并在其上放置一个空间索引。

SELECT * 
FROM myTable
WHERE ST_DWITHIN(geog, ST_SetSRID(ST_Point(-70.123, 40.456), 4326)::geography,50000)

或使用存储在 driver_range 列中的可变距离

SELECT * 
FROM myTable
WHERE ST_DWITHIN(geog, ST_SetSRID(ST_Point(-70.123, 40.456), 4326)::geography,driver_range)