Подтвердить что ты не робот

Найдите n ближайших соседей для данной точки, используя PostGIS?

Я пытаюсь решить проблему поиска n ближайших соседей с помощью PostGIS:

Начальная точка:

  • Таблица geoname с geonames (от geonames.org), содержащий широта/долгота (WSG-84)
  • Добавлена ​​геометрия GeometryColumn с srid = 4326 и datatype = POINT
  • Заполненная геометрия со значениями: UPDATE geoname SET geom = ST_SetSRID (ST_Point (долгота, широта), 4326);
  • Создан индекс GIST для геометрии (CREATE INDEX geom_index ON geoname ИСПОЛЬЗОВАНИЕ GIST (geom);)/Clustered geom_index: CLUSTER geom_index ON geoname;)
  • Создан PRIMARY KEY UNIQUE BTREE index для geonameid

Проблема: Найдите n (например, 5) ближайших соседей для данной точки в таблице geoname, представленной id (geoname.geonameid.

Возможное решение:

Вдохновленный http://www.bostongis.com/PrinterFriendly.aspx?content_name=postgis_nearest_neighbor, я попробовал следующий запрос:

"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " +
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid " +
"AND ST_DWithin(start.geom, ende.geom, 300) order by distance limit 5"

Время обработки: около 60 с

Также попытался подход, основанный на EXPAND:

"SELECT start.asciiname, ende.asciiname, distance_sphere(start.geom, ende.geom) as distance " +
"FROM geoname As start, geoname As ende WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND expand(start.geom, 300) && ende.geom " +
"order by distance limit 5"

Время обработки: около 120 с

Запланированное приложение - это своего рода автозаполнение. Таким образом, любой подход, принимающий дольше > 1s, неприменим. Можно ли вообще достичь времени отклика < 1 с PostGIS?

4b9b3361

Ответ 1

Теперь, начиная с PostGIS 2.0, существует индекс KNN для доступных типов геометрии. Это дает вам ближайшие 5 записей, не учитывая, насколько далеко от "вашего местоположения...".

SELECT *
FROM your_table 
ORDER BY your_table.geom <-> "your location..."
LIMIT 5;

См. <-> operator в руководстве по PostgreSQL.

Ответ 2

Как я думаю, на вас ответили в списке, единица находится в градусах, поэтому вы почти просматриваете весь мир с 300 градусами в st_dwithin.

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

Делайте вещи быстрее, я должен просто создать новую таблицу с геометрией, преобразованной в географию.

Но просто проверить его можно на лету:

SELECT start.asciiname, ende.asciiname, 
ST_Distance(start.geom::geography, ende.geom::geography) as distance 
FROM geoname As start, geoname As ende 
WHERE start.geonameid = 2950159 AND start.geonameid <> ende.geonameid AND
ST_DWithin(start.geom::geography, ende.geom::geography, 300) 
order by distance 
limit 5;

НТН Никлас