การสแนปเริ่มต้นและสิ้นสุดโหนดของบรรทัดไปยังบรรทัดอื่น ๆ ใน PostGIS


9

มีตัวอย่างมากมายที่แสดงวิธีการจัดเรียงบรรทัดไปยังจุด แต่ฉันไม่สามารถหาวิธีใด ๆ (เร็ว!) ของการหักล้างจุดเริ่มต้นและจุดสิ้นสุดของสายสตริงไปยังโหนดของสายอื่น ๆ

โดยพื้นฐานแล้วฉันต้องการ "ล้าง" เลเยอร์ของฉันใน postgis (2.0) ย้ายจุดที่คล้ายกันมารวมกันและตัดเย็บช่องเล็ก ๆ ระหว่างสตริงบรรทัด

มันจะไม่สำคัญมากนักถ้าฉันเพิ่มโหนดอื่นย้ายโหนดแรก / โหนดสุดท้ายของทั้งสองบรรทัดหรือย้ายจุดทั้งสองไปที่ศูนย์กลาง

ฉันพบสองตัวเลือก แต่ฉันไม่แน่ใจว่าจะเริ่มต้นอย่างไรกับตัวเลือกใดตัวเลือกหนึ่ง:

ตัวเลือกที่สองเป็นไปได้ แต่ความช่วยเหลือใด ๆ เกี่ยวกับวิธีการปฏิบัติตามวิธีนี้จะได้รับการชื่นชมอย่างมาก

คำตอบ:


6

ฉันจัดการเพื่อแก้ปัญหานี้โดยไม่ต้องใช้เครื่องมือ GRASS หรือฟังก์ชั่นทอพอโลยีที่กล่าวถึง

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

เมื่อเสร็จแล้วฉันจะย้ายจุดเริ่มต้นและจุดสิ้นสุดดั้งเดิมไปยังตำแหน่งใหม่

ง่ายกว่าที่คาดไว้และยังเร็ว แต่ฉันคาดว่า PostGIS จะมีฟังก์ชันในตัวสำหรับสิ่งนี้ - ซึ่งจะเร็วกว่า

แก้ไข: เพื่อประโยชน์ในการคืนกลับสู่ชุมชนนี่คือรหัสของฉัน (ค่อนข้างเส็งเคร็ง) ในตอนนี้

drop table if exists nodes;
drop table if exists nodes2;
drop table if exists buffers;

-- Get Start and End nodes
select ST_StartPoint(wkb_geometry) startnode,  ST_EndPoint(wkb_geometry) endnode,    ogc_fid into nodes  from sourceTable;
-- Combine all nodes into one table for easier queries
select startnode node, ogc_fid into nodes2 from nodes;
insert into nodes2 select endnode node, ogc_fid from nodes;

-- Some indexes to speed everything up
CREATE INDEX nodesstart_idx ON nodes USING gist  (startnode);
CREATE INDEX nodesend_idx ON nodes USING gist  (endnode);
CREATE INDEX nodes2_idx ON nodes2 USING gist  (node);
CREATE INDEX nodes_ogcfid_idx ON nodes USING btree (ogc_fid ASC NULLS LAST);

-- Create buffers, combine them, split combined objects again
select (ST_Dump(ST_Union(ST_Buffer(node, 1)))).geom geom into buffers from nodes2;
CREATE INDEX buffers_idx ON buffers USING gist  (geom);

-- Update start/end nodes table
UPDATE nodes SET startnode = ST_Centroid((select geom from buffers WHERE geom && startnode));
UPDATE nodes SET endnode = ST_Centroid((select geom from buffers WHERE geom && endnode));
-- Update original points
update sourceTable set wkb_geometry = ST_SetPoint(
ST_SetPoint(wkb_geometry, 0, (select startnode from nodes where ogc_fid=sourceTable.ogc_fid)), 
ST_NumPoints(wkb_geometry) - 1, (select endnode from nodes where ogc_fid=sourceTable.ogc_fid));

DROP TABLE nodes;
DROP TABLE nodes2;
DROP TABLE buffers;

คำตอบนี้ดูค่อนข้างจะเหมือนกับคำแนะนำ "ไม่ใช่ทอพอโลยี" จากคำตอบของฉัน มันจะใจดีถ้าคุณให้ upvote หรือเลือกคำตอบ สิ่งเหล่านี้คือสิ่งที่ให้อาหารแก่ชุมชนที่นี่ :)
katahdin

คุณถูก. ฉันอัปเกรดคำตอบของคุณแล้วและจะแก้ไขคำตอบของฉันเพื่อรวมรหัสของฉัน
Jelmer Baas

4

นี่คือสามตัวเลือก หวังว่าจะช่วยได้

v.clean

การใช้เครื่องมือ GRASS ใน QGIS คุณสามารถล้างโทโพโลยีของวัตถุเชิงพื้นที่ได้ User @RK ให้ชุดคำสั่งที่ดีเกี่ยวกับวิธีการทำสิ่งนี้ในคำตอบของคำถามอื่น ข้อดีที่ GRASS ให้ไว้คือมันจะอนุมานโทโพโลยีของ shapefile ข้อเสียสำหรับสถานการณ์ของคุณคือข้อมูลของคุณไม่ได้อยู่ใน shapefile แน่นอนคุณสามารถส่งออกข้อมูลจาก Postgres ไปยัง shapefile โดยใช้เครื่องมือ "เพิ่ม PostGIS Layer" แต่นั่นเป็นขั้นตอนพิเศษ

ฟังก์ชัน PostGIS ที่ไม่ใช่ทอพอโลยี

ใน PostGIS คุณสามารถใช้ฟังก์ชัน ST_EndPointและST_StartPointเพื่อรับจุดสิ้นสุดและจุดเริ่มต้นสำหรับการคืนค่า จากนั้นการใช้ชุดค่าผสมของST_D ภายใน n และST_ ระยะทางคุณสามารถค้นหาจุดเริ่มต้นหรือจุดสิ้นสุดที่ใกล้เคียงที่สุดในรูปทรงเรขาคณิตใกล้เคียง หากคุณมีคะแนนมากแล้ว ST_D ภายในนั้นจะเร่งการสืบค้นให้เร็วขึ้นโดยสมมติว่าคุณมีดัชนีอยู่ จากนั้นคุณจะต้องสร้างกฎที่กำหนดว่าจะให้แก้ไขจุดใดและแก้ไขจุดใด

ข้อดีคือคุณไม่ต้องส่งข้อมูลของคุณไปที่ GRASS เพื่อทำความสะอาด แต่มีข้อผิดพลาดบางประการที่ต้องระวัง

ฟังก์ชัน PostGIS ของทอพอโลยี

คำถามอ้างอิงถึงฟังก์ชั่นทอพอโลยี PostGIS สิ่งเหล่านี้ใช้ได้ผลดี แต่ตามที่วิกิอธิบายคุณต้องกำหนดขอบโหนดและใบหน้าอย่างชัดเจน เห็นได้ชัดว่านี่จะเป็นปัญหาสำหรับชุดข้อมูลของคุณเนื่องจากคุณทราบปัญหาเกี่ยวกับทอพอโลยี


1

PostGIS มีฟังก์ชั่นการสแนป .. บางทีพวกเขาอาจจะช่วยได้?

ST_Snap: แบ่งส่วนและจุดยอดของรูปทรงเรขาคณิตอินพุตไปยังจุดยอดของรูปทรงเรขาคณิตอ้างอิง

ST_SnapToGrid: Snap ทุกจุดของรูปทรงเรขาคณิตอินพุตเข้ากับกริดปกติ


1
ขอบคุณฉันตระหนักถึงหน้าที่เหล่านี้ ST_Snap ยึดโหนดทั้งหมดฉันต้องการเพียงโหนดเริ่มต้นและสิ้นสุดเท่านั้น ST_SnapToGrid ไม่เหมาะจริง ๆ เพราะมันปรับเปลี่ยนรูปทรงเรขาคณิตที่มีอยู่ทั้งหมดและมีโอกาสในการย้ายโหนดที่อยู่ใกล้มากขึ้นเพราะพวกเขาเพิ่งจะตกอยู่ในส่วนอื่น
Jelmer Baas
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.