Пошук найближчої геометрії в PostGIS


16

Я переглядав функції "API" PostGIS, і помічаю, що більшість з них використовують два елементи для порівняння. Наприклад, функція ST_Distance займає два елементи геометрії / географії, щоб знайти відстань.

Немає функції робити щось на кшталт: "Враховуючи геометрію G, дайте мені найближчу геометрію GClosest в Таблиці T, де G.id <> GClosest.id"

Я усвідомлюю, що можу написати функцію PL / PgSQL, щоб повторити таблицю та викликати ST_Distance на кожному елементі, але я сподіваюся, що є краще, ефективніше рішення.


1
Якщо вас цікавить відстань до найближчої геометрії, перевірте gis.stackexchange.com/questions/11979/…
underdark

дайте мені знати, якщо я правильно зрозумів ... ви хочете, щоб наступна функція, що має таку ж відстань, як найбільш близька?
falcacibar

Відповіді:


7

На ваше запитання також можна відповісти на один (хоч і складний) запит на зразок наступного, який повертає весь запис та відстань до еталонної геометрії. Зверніть увагу, що якщо більше одного запису відповідає мінімальній відстані, вони всі повертаються.

SELECT 
  i.*,
  md.min_distance
FROM
  address AS i, 
  (SELECT 
     ga.address_geom,
     min( ST_Distance(
            ga.address_geom,
            gb.address_geom)
        ) AS min_distance
   FROM
     address AS ga,
     address AS gb 
   WHERE 
     ga.id <> gb.id 
   AND 
     ga.id = 3
   GROUP BY 
     ga.address_geom
  ) AS md 
WHERE 
  ST_Distance( i.address_geom, md.address_geom) = md.min_distance;

Я перевірив цей запит на таблиці адрес, і він працює. У вищезазначеному запиті я шукаю найближчу точку до цього з id = 3.


Це гарна інформація - дякую ... Я розумію функцію сукупності min (..) за визначенням, але я плутаюсь, як це використовується у вашому прикладі. st_distance (X, Y) приймає два типи геометрії і повертає між ними відстань, що є єдиним значенням. Чому ви тоді викликаєте сукупну функцію на цьому єдиному результаті? Можливо, я неправильно
трактую

Група by знаходиться на геометрії ga, яка є константою для всього набору результатів (пам'ятайте, що ga обрано id = 3), тому в принципі нічого не робить. Це лише хитрість, щоб геометрія ga була доступна у st_distance зовнішнього запиту, не приєднуючись до таблиці ще раз. Сьогодні я думав, що, можливо, я можу взагалі піти із запиту про внутрішню, скориставшись розділом розділу . Це також повинно покращити продуктивність. Я спробую і дам вам знати.
unicoletti

На жаль, функції вікон були введені в 8.4, і тепер я не маю доступу до сервера, який має і postgis, і цю версію, тому я не можу перевірити запит, переписаний з розділом.
unicoletti

7

Джордж Маккеррон написав просту функцію "Найближчий сусід", яку я вважаю досить корисною. Ця функція повертає ідентифікатор найближчого сусіда даній функції:

create or replace function 
  nn(nearTo                   geometry
   , initialDistance          real
   , distanceMultiplier       real 
   , maxPower                 integer
   , nearThings               text
   , nearThingsIdField        text
   , nearThingsGeometryField  text)
 returns integer as $$
declare 
  sql     text;
  result  integer;
begin
  sql := ' select ' || quote_ident(nearThingsIdField) 
      || ' from '   || quote_ident(nearThings)
      || ' where st_dwithin($1, ' 
      ||   quote_ident(nearThingsGeometryField) || ', $2 * ($3 ^ $4))'
      || ' order by st_distance($1, ' || quote_ident(nearThingsGeometryField) || ')'
      || ' limit 1';
  for i in 0..maxPower loop
     execute sql into result using nearTo              -- $1
                                , initialDistance     -- $2
                                , distanceMultiplier  -- $3
                                , i;                  -- $4
    if result is not null then return result; end if;
  end loop;
  return null;
end
$$ language 'plpgsql' stable;

Приклад використання:

SELECT id, nn(pt_geom,0.00001,2,100,'nw_node','node_id','node_geom') FROM my_point_table;

... вибирає найближчий вузол таблиці nw_node для кожного запису в my_point_table.

Існує також більш загальна функція на бостонському ГІС-сайті .


Мене більше хвилює питання створення запитів 1: N запитів у більш загальному розумінні. Наприклад, замість того, щоб знайти найближчий до геометрії елемент G, я, можливо, захочу знайти перший елемент, який перекриває G. Дякую за інформацію, незалежно. Посилання на GIS в Бостоні було дуже корисним! Я вже надрукував деякі шпаргалки :-)
Jmoney38

Можливо, ви можете перефразувати своє запитання, щоб зробити його трохи зрозумілішим, @ Jmoney48. Тож вас конкретно не цікавить проблема найближчого сусіда, а скоріше, як порівняти одну геометрію з усіма геометріями в таблиці?
андеркард

ЗАВЖДИ використовуйте загальну функцію бостонського ГІС-сайту, простий - надзвичайно повільний для великих таблиць, а зусилля по застосуванню його не більше.
Владтн
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.