PostGIS: призначте ідентифікатор точки в шарі A найближчій точці шару B


15

Це мало бути очевидним попередником (якого я не задавав) моєму іншому запитанню: як створити павукові діаграми (лінії концентраторів) у PostGIS?

Якщо я не знаю взаємозв'язку між точкою в шарі A (магазини) і точкою в шарі B (клієнти), я б хотів взагалі сказати «Клієнт 1 обслуговується найближчим магазином». Хоча я усвідомлюю, що цей факт може бути неправдою, він може бути гідним сурогатом.

Використовуючи PostGIS, найефективніший спосіб присвоїти ідентифікатор найближчої точки в шарі А (магазини) кожній точці рівня B (замовники). Вихід, який я шукаю, є чимось на кшталт нижче.

Customer | Store
    1    |   A
    2    |   A
    3    |   B
    4    |   C

Відповіді:


6

так само:

виберіть A.ID як CUST_ID, (виберіть B.ID з B порядку за допомогою st_distance (A.geom, B.geom) межа 1) як STORE_ID від A


Це був найкращий спосіб виконати завдання. Дивіться мою примітку нижче про фактичний код, який я використав.
RyanKDalton

8

Схоже, якщо у вас набагато більше клієнтів, ніж у магазинів, тоді може бути ефективніше створити шар багатокутників voronoi для магазинів, а потім зробити просторове з'єднання покупців проти багатокутників магазину.


1
Мені подобається такий підхід!
underdark

Який підхід був би найпростішим для створення вороних полісів? Чи є інші варіанти, що тут зазначається: bostongis.com/… bostongis.com/…
RyanKDalton

Я думаю, що пакет триангуляції Делоне та Діріхле у другому навчальному посібнику був би доречним, але не впевнений, чи є найпростішим.
Кірк Куйкендалл


5

Від http://www.bostongis.com/?content_name=postgis_nevable_neighbor :

Якщо вам потрібно було отримати найближчого сусіда для всіх записів у таблиці, але вам потрібен лише перший найближчий сусід для кожного, тоді ви можете використовувати відмінний синтаксис DISTINCT ON PostgreSQL. Що б виглядало приблизно так:

SELECT DISTINCT ON(g1.gid)  g1.gid As gref_gid, 
       g1.description As gref_description, 
       g2.gid As gnn_gid, 
       g2.description As gnn_description  
FROM sometable As g1, sometable As g2   
WHERE g1.gid <> g2.gid 
      AND ST_DWithin(g1.the_geom, g2.the_geom, 300)   
ORDER BY g1.gid, ST_Distance(g1.the_geom,g2.the_geom) 

Це знайде мінімальні відстані до 300 одиниць. Отже, ви повинні спочатку перевірити свої дані та дізнатися, наскільки великі будуть ваші мінімальні відстані.



3

Дякуємо за внесок усіх Я врешті-решт пішов із поєднанням пропозицій eprand та underdark. Кінцевий код, який я використав, був:

CREATE TABLE closest_point as
SELECT DISTINCT ON (A.GID) A.GID AS CUST_ID, 
      (SELECT B.GID FROM "STORES" as B 
       ORDER BY ST_Distance(A.the_geom, B.the_geom) limit 1) as STORE_ID, 
       A.the_geom 
FROM "CUSTOMERS" as A, "STORES" as B;

Потім я створив діаграму voronoi на шарі магазинів, щоб підтвердити, що результати працювали правильно, що, звичайно, вони і зробили. Дякую за велику роботу всім!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.