Отключение Postgis во время некоторых запросов - PullRequest
0 голосов
/ 16 февраля 2020

У меня есть две таблицы: одна в SRID 4326 (содержащая MULTIPOLYGON), а другая в SRID 32188 (содержащая MULTILINESTRING).

Я пытаюсь выбрать все полигоны из t1, которые находятся в 100 метров от любых линий в t2.

Я задаю этот запрос:

SELECT * FROM table1 AS t1, table2 AS t2 
WHERE ST_DWithin(
        ST_Transform(t1.geom, 3857),
        ST_Transform(t2.geom, 3857),
        100);

К сожалению, он не работает, и pgAdmin4 не дает мне полезной ошибки. Вместо этого он отключается от БД, как только я запускаю запрос (так что это не время ожидания):

enter image description here

Я также пытался с двумя таблицы в том же SRID, но у меня все еще есть проблема ... Что я здесь не так делаю?

РЕДАКТИРОВАТЬ : Чтобы попытаться сузить проблему, я взял @JGH предложив и адаптировав его для проверки ST_DWITHIN с точкой вместо многоканальных строк таблицы 2. Это прекрасно работает.

SELECT * FROM table1 t1
WHERE EXISTS (
    SELECT FROM table2 t2
    WHERE ST_DWithin(t1.geom, ST_MakePoint(-73.63,45.52)::geography,100)
);

Тем не менее, я тестировал с таблицей 2, содержащей только одну прямую линию (хотя геометрия многоканальных строк все же), и клиент падает. Может ли это быть связано с этим: https://gis.stackexchange.com/questions/31923/why-is-the-database-connection-lost-on-every-query?

1 Ответ

1 голос
/ 16 февраля 2020

У вашего клиента, вероятно, истекло время ожидания.

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

Вторая проблема, которая, к сожалению, не вызовет никаких ошибок, заключается в том, что неправильно вычислять расстояния, используя 3857. В Québe c искажение длины составляет около 40%, что огромно. Вам придется либо использовать подходящую локальную проекцию (например, MTM или UTM) для обеих геометрий, либо, если это невозможно, привести к географии, чтобы выполнить вычисление расстояния.

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

SELECT *
FROM   table1 t1
WHERE  EXISTS (
   SELECT FROM table2 t2
   WHERE  ST_DWithin(t1.geom::geography, ST_Transform(t2.geom, 4326)::geography, 100)
   );

Не забудьте создать пространственный индекс для географии (и / или для преобразованной геометрии)

CREATE INDEX t1_geog ON t1 USING gist(geography(t1.geom);

или

CREATE INDEX t1_32188 ON t1 USING gist(st_transform(geom,32188));
...