PostGIS: Katman A'daki noktanın kimliğini Katman B'deki en yakın noktaya atayın


15

Bu benim diğer sorumun (sormadım) bariz bir öncüsü olmalıydı: PostGIS'te örümcek diyagramları (hub hatları) nasıl oluşturulur?

A katmanındaki (mağazalar) bir nokta ile B katmanındaki (müşteriler) bir nokta arasındaki ilişkiyi bilmiyorsam, genellikle "Müşteri 1'e en yakın mağaza tarafından hizmet verilir" demek istiyorum. Bu gerçeğin doğru olmayabileceğini fark etsem de, iyi bir vekil olabilir.

PostGIS kullanarak, katman A'daki (depolar) en yakın noktanın kimliğini katman B'deki (müşteriler) her noktaya atamanın en etkili yolu nedir? Aradığım çıktı aşağıdaki gibi bir şey.

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

Yanıtlar:


6

aynı şekilde:

CUST_ID olarak A.ID'yi seçin, (st_distance tarafından B siparişinden B.ID'yi (A.geom, B.geom) limit 1) A'dan STORE_ID olarak seçin


Görevi gerçekleştirmenin en iyi yolu buydu. Kullandığım gerçek kod için aşağıdaki notuma bakın.
RyanKDalton

8

Mağazalardan çok daha fazla müşteriniz varsa, mağazalar için bir voronoi çokgenleri katmanı oluşturmak , daha sonra mağaza çokgenlerine karşı müşterilerin mekansal bir birleşimini yapmak daha verimli olabilir .


1
Bu yaklaşımı seviyorum!
underdark

Voronoi polisi oluşturmak için en kolay yaklaşım hangisidir? Burada belirtilmiş olan başka seçenekler var mı: bostongis.com/… bostongis.com/…
RyanKDalton

Bence ikinci öğreticideki Delaunay Nirengi ve Dirichlet Paketi uygun olurdu, ama en kolay olsa emin değilim.
Kirk Kuykendall


5

Gönderen http://www.bostongis.com/?content_name=postgis_nearest_neighbor :

Bir tablodaki tüm kayıtlar için en yakın komşuyu almanız gerekiyorsa, ancak her biri için yalnızca en yakın komşuya ihtiyacınız varsa, PostgreSQL'in kendine özgü DISTINCT ON sözdizimini kullanabilirsiniz. Hangi böyle bir şey olurdu:

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) 

Bu, 300 birime kadar minimum mesafeleri bulacaktır. Bu nedenle, önce verilerinizi kontrol etmeniz ve minimum mesafelerinizin ne kadar büyük olacağını bulmanız gerekir.



3

Herkesin katkısı için teşekkürler. Sonunda eprand ve underdark'ın önerilerinin bir kombinasyonu ile gittim. Kullandığım son kod:

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;

Daha sonra sonuçların doğru çalıştığını doğrulamak için mağaza katmanında bir voronoi diyagramı oluşturdum, tabii ki yaptılar. Harika çalışmalar için teşekkürler!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.