PostGIS: กำหนด ID ของจุดในเลเยอร์ A ไปยังจุดที่ใกล้เคียงที่สุดในชั้น B


15

นี่น่าจะเป็นสารตั้งต้นที่ชัดเจน (ที่ฉันไม่ได้ถาม) กับคำถามอื่น ๆ ของฉัน: วิธีสร้างไดอะแกรมเดอร์ (ฮับไลน์) ใน PostGIS ได้อย่างไร

หากฉันไม่ทราบความสัมพันธ์ระหว่างจุดในเลเยอร์ A (ร้านค้า) และจุดในเลเยอร์ B (ลูกค้า) ฉันมักจะพูดว่า "ลูกค้า 1 เป็นร้านที่ใกล้ที่สุด" แม้ว่าฉันจะรู้ว่าความจริงข้อนี้อาจไม่เป็นความจริง แต่มันก็เป็นตัวแทนที่ดี

การใช้ PostGIS เป็นวิธีที่มีประสิทธิภาพที่สุดในการกำหนด ID ของจุดที่ใกล้ที่สุดในชั้น A (ร้านค้า) ให้กับแต่ละจุดในชั้น 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

ฉันคิดว่า Delaunay Triangulation และ Dirichlet Package ในบทช่วยสอนที่สองน่าจะเหมาะสมไม่แน่ใจว่าเป็นวิธีที่ง่ายที่สุดหรือไม่
Kirk Kuykendall


5

จากhttp://www.bostongis.com/?content_name=postgis_nearest_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 บนเลเยอร์ร้านค้าเพื่อยืนยันผลลัพธ์การทำงานอย่างถูกต้องซึ่งแน่นอนว่าพวกเขาทำ ขอบคุณสำหรับการทำงานที่ยอดเยี่ยมทุกคน!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.