POSTGIS, ограничивающий дистанционный запрос порогом - PullRequest
0 голосов
/ 22 ноября 2018

Я ищу парные расстояния между строками из двух таблиц и возвращаю только те пары, которые находятся в пределах порогового расстояния.В таблицах содержится большое количество объектов, поэтому производительность является проблемой.

Я нашел пример получения ближайших расстояний при минимальном расстоянии PostGIS между двумя большими наборами точек

Код там выглядит так:

SELECT 
    a.id, nn.id AS id_nn, 
    a.geom, nn.geom_closest, 
    ST_Distance_Sphere(a.geom, nn.geom_closest) AS min_dist
FROM 
    table_a AS a
    CROSS JOIN LATERAL
        (SELECT
            b.id, 
            b.geom AS geom_closest
        FROM table_b b
        ORDER BY a.geom <-> b.geom
        LIMIT 1) AS nn;

Я ужасен с SQL, и я понимаю, что LIMIT 1 берет самое близкое, когда они упорядочены.

Как мне изменить это, чтобы дать всемпары меньше порога?Я попытался использовать предложение WHERE, чтобы ограничить его значением

SELECT 
    a.id, nn.id AS id_nn, 
    a.wkb_geometry, nn.geom_closest, 
    ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) AS min_dist
FROM 
    mammography21 AS a
    CROSS JOIN LATERAL
        (SELECT
            b.gid as id, 
            b.wkb_geometry AS geom_closest
        FROM cartographic_boundary_us_zcta_2016 b
        ORDER BY a.wkb_geometry <-> b.wkb_geometry) AS nn
WHERE ST_DistanceSphere(a.wkb_geometry, nn.geom_closest) <= 10.0;

, но это выдает ошибку: Сервер обнаружил внутреннюю ошибку и не смог выполнить ваш запрос.Либо сервер перегружен, либо в приложении произошла ошибка. Даже если это сработало, я думаю, это неэффективный подход.Как мне пытаться сделать этот запрос?

1 Ответ

0 голосов
/ 22 ноября 2018

Порядок был использован только для получения ближайшего пункта.Если вам нужно более одной точки, вам больше не нужно упорядочивать точки по расстоянию.

Установка проверки расстояния - это правильная вещь ... но будьте осторожны, где вы это делаете.Ваш запрос занимает слишком много времени, потому что для каждой точки он вычисляет расстояние до каждой другой точки (боковое соединение), а затем фильтрует результаты, чтобы сохранить только ближайшие.

Поскольку вам нужно больше, чем просто1 балл, позднее соединение может быть удалено.Как предполагает @thibautg, st_Dwithin предпочтительнее, поскольку он использует пространственный индекс.

Наконец, вы, возможно, захотите привести свои данные к географии, чтобы вычислить расстояние в метрах (это зависит от ваших данных CRS).Если это так, вам также понадобится пространственный индекс для географических регионов.

SELECT 
    a.id, nn.id AS id_nn, 
    a.geom srcGeom, nn.geom nearGeom, 
    ST_DistanceSphere(a.geom, nn.geom) AS near_dist
FROM 
    mammography21 AS a,
    cartographic_boundary_us_zcta_2016 nn
WHERE ST_DWithin(a.geom, nn.geom, 10);
...