การค้นหารูปทรงเรขาคณิตที่ใกล้เคียงที่สุดใน PostGIS


16

ฉันได้ดูฟังก์ชั่น PostGIS "API" และฉันสังเกตว่าส่วนใหญ่ใช้องค์ประกอบสองอย่างเพื่อเปรียบเทียบ ตัวอย่างเช่นฟังก์ชัน 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


นี่เป็นข้อมูลที่ดี - ขอบคุณ ... ฉันเข้าใจฟังก์ชั่นการรวมขั้นต่ำ (.. ) ตามคำจำกัดความ แต่ฉันสับสนว่ามันถูกใช้ในตัวอย่างของคุณอย่างไร st_distance (X, Y) ใช้รูปทรงเรขาคณิตสองแบบและส่งคืนระยะทางระหว่างพวกเขาซึ่งเป็นค่าเดียว เหตุใดคุณจึงเรียกฟังก์ชันรวมบนผลลัพธ์ค่าเดียว? บางทีฉันอาจตีความคำสั่ง select ด้านในผิด ...
Jmoney38

กลุ่มที่อยู่บนga geometry ซึ่งเป็นค่าคงที่สำหรับชุดผลลัพธ์ทั้งหมด (โปรดจำไว้ว่าgaถูกเลือกโดย id = 3) ดังนั้นโดยพื้นฐานแล้วมันไม่ทำอะไรเลย นั่นเป็นเพียงกลลวงที่จะมีเรขาคณิตgaอยู่ในst_distanceของข้อความค้นหาภายนอกโดยไม่ต้องเข้าร่วมตารางอีกครั้ง วันนี้ฉันคิดว่าบางทีฉันอาจจะได้ไปกับแบบสอบถาม Innner ทั้งหมดโดยใช้ข้อพาร์ทิชัน ที่ควรปรับปรุงประสิทธิภาพ ฉันจะลองและแจ้งให้คุณทราบ
unicoletti

น่าเสียดายที่ฟังก์ชั่นหน้าต่างถูกนำมาใช้ใน 8.4 และตอนนี้ฉันไม่สามารถเข้าถึงเซิร์ฟเวอร์ที่มีทั้ง postgis และรุ่นนั้นดังนั้นฉันจึงไม่สามารถทดสอบแบบสอบถามที่เขียนใหม่ด้วยประโยคพาร์ทิชัน
unicoletti

7

George MacKerron ได้เขียนฟังก์ชั่น Neighbor Neighbor แบบเรียบง่ายซึ่งฉันพบว่ามีประโยชน์ทีเดียว ฟังก์ชั่นนี้จะส่งคืน ID ของเพื่อนบ้านที่ใกล้ที่สุดไปยังคุณลักษณะที่กำหนด:

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

นอกจากนี้ยังมีฟังก์ชั่นทั่วไปมากขึ้นบนเว็บไซต์ GIS บอสตัน


ฉันกังวลมากขึ้นเกี่ยวกับวิธีสร้างคิวรี 1: N ข้อความค้นหาในแง่ทั่วไปมากขึ้น ตัวอย่างเช่นแทนที่จะค้นหาองค์ประกอบที่ใกล้เคียงที่สุดกับเรขาคณิต G ฉันอาจต้องการค้นหาองค์ประกอบแรกที่ทับซ้อน G ขอบคุณสำหรับข้อมูลโดยไม่คำนึงถึง ลิงค์ไปยัง Boston GIS นั้นมีประโยชน์มาก! ฉันพิมพ์แผ่นโกงบางส่วนแล้ว :-)
Jmoney38

บางทีคุณอาจใช้ถ้อยคำใหม่อีกครั้งเพื่อให้ชัดเจนยิ่งขึ้น @ Jmoney48 ดังนั้นคุณไม่สนใจปัญหาเพื่อนบ้านที่ใกล้ที่สุดโดยเฉพาะ แต่จะเปรียบเทียบเรขาคณิตหนึ่งรูปกับเรขาคณิตทั้งหมดในตารางได้อย่างไร
underdark

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