PostGIS: Tetapkan ID titik di lapisan A ke titik terdekat di Lapisan B

15

Ini seharusnya merupakan prekursor yang jelas (yang tidak saya tanyakan) untuk pertanyaan saya yang lain: Bagaimana cara membuat diagram laba-laba (garis hub) di PostGIS?

Jika saya tidak tahu hubungan antara titik di lapisan A (toko) dan titik di lapisan B (pelanggan), saya biasanya ingin mengatakan "Pelanggan 1 dilayani oleh toko terdekat." Sementara saya menyadari fakta ini mungkin tidak benar, itu bisa menjadi pengganti yang layak.

Menggunakan PostGIS, apa cara paling efisien untuk menetapkan ID titik terdekat di lapisan A (toko) ke setiap titik di lapisan B (pelanggan). Output yang saya cari adalah sesuatu seperti di bawah ini.

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

Jawaban:

6

juga:

pilih A.ID sebagai CUST_ID, (pilih B.ID dari B order dengan st_distance (A.geom, B.geom) batas 1) sebagai STORE_ID dari A

eprand
sumber
Ini adalah cara terbaik untuk menyelesaikan tugas. Lihat catatan saya di bawah ini untuk kode aktual yang saya gunakan.
RyanKDalton
8

Sepertinya jika Anda memiliki lebih banyak pelanggan daripada toko, maka mungkin akan lebih efisien untuk membuat lapisan poligon voronoi untuk toko, lalu melakukan penggabungan spasial pelanggan terhadap poligon toko.

Kirk Kuykendall
sumber
1
Saya suka pendekatan ini!
underdark
Pendekatan mana yang paling mudah untuk membuat voronoi polys? Apakah ada opsi lain yang dicatat di sini: bostongis.com/… bostongis.com/…
RyanKDalton
Saya pikir Paket Delaunay Triangulation dan Dirichlet di tutorial kedua akan sesuai, tidak yakin apakah itu yang termudah.
Kirk Kuykendall
5

Dari http://www.bostongis.com/?content_name=postgis_nearest_neighbor :

Jika Anda perlu mendapatkan tetangga terdekat untuk semua catatan dalam sebuah tabel, tetapi Anda hanya perlu tetangga terdekat pertama untuk masing-masing, maka Anda dapat menggunakan sintaks berbeda DISTINCT ON PostgreSQL. Yang akan terlihat seperti ini:

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) 

Ini akan menemukan jarak minimum hingga 300 unit. Jadi, Anda harus terlebih dahulu memeriksa data Anda dan mencari tahu seberapa besar jarak minimum Anda akan dapatkan.

underdark
sumber
3

Terima kasih atas masukan semua orang. Saya akhirnya pergi dengan kombinasi saran eprand dan underdark. Kode terakhir yang saya gunakan adalah:

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;

Saya kemudian membuat diagram voronoi pada lapisan toko untuk mengkonfirmasi hasil yang bekerja dengan benar, yang tentu saja mereka lakukan. Terima kasih atas kerja kerasnya semua!

RyanKDalton
sumber