ฉันคิดว่ามันค่อนข้างยุ่งยากเพราะชุดโหนดที่แตกต่างกันของรูปหลายเหลี่ยมทั้งสองของคุณ (รูปหลายเหลี่ยมสีเขียว A, ส่วนที่แตกต่างกันสีแดงของรูปหลายเหลี่ยม B) การเปรียบเทียบเซ็กเมนต์ของรูปหลายเหลี่ยมทั้งสองให้เบาะแสว่าส่วนใดของรูปหลายเหลี่ยม B ที่จะถูกแก้ไข
โหนดรูปหลายเหลี่ยม
โหนดของเซ็กเมนต์ "แตกต่าง" รูปหลายเหลี่ยม B
โชคไม่ดีที่การแสดงนี้มีความแตกต่างในโครงสร้างเซกเมนต์เท่านั้น แต่ฉันหวังว่ามันจะเป็นจุดเริ่มต้นและใช้งานได้เช่นนี้:
หลังจากกระบวนการดาวน์โหลดและคลายซิปฉันได้นำเข้าชุดข้อมูลโดยใช้ PostgrSQL 9.46, PostGIS 2.1 ภายใต้ Debian Linux Jessie พร้อมคำสั่ง
$ createdb gis-se
$ psql gis-se < /usr/share/postgis-2.1/postgis.sql
$ psql gis-se < /usr/share/postgis-2.1/spatial_ref_sys.sql
$ shp2pgsql -S polygon_a | psql gis-se
$ shp2pgsql -S polygon_b | psql gis-se
สมมติว่าเซ็กเมนต์ของรูปหลายเหลี่ยม A ไม่ได้อยู่ใน B และรองจาก vera ฉันพยายามสร้างความแตกต่างระหว่างเซ็กเมนต์ของชุดรูปหลายเหลี่ยมทั้งสองโดยไม่สนใจสมาชิกภาพเซ็กเมนต์กับรูปหลายเหลี่ยมในแต่ละกลุ่ม สำหรับเหตุผลเกี่ยวกับการสอนฉันกำหนดสิ่ง SQL ในหลายมุมมอง
ที่สอดคล้องกับโพสต์ GIS-SEนี้ฉันแยกส่วนรูปหลายเหลี่ยมออกเป็นตารางเซ็กเมนต์segments_a
และsegments_b
-- Segments of the polygon A
CREATE VIEW segments_a AS SELECT sp, ep
FROM
-- extract the endpoints for every 2-point line segment for each linestring
(SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM
-- extract the individual linestrings
(SELECT (ST_Dump(ST_Boundary(geom))).geom
FROM polygon_a
) AS linestrings
-- be sure that nothing is scrambled
ORDER BY sp, ep
) AS segments;
ตารางส่วนรูปหลายเหลี่ยม A:
SELECT
st_astext(sp) AS sp,
st_astext(ep) AS ep
FROM segments_a
LIMIT 3;
sp | ep
-------------------------------------------+--------------------------------------------
POINT(-292.268907321861 95.0342877387557) | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195) | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.03428773875
ขั้นตอนเดียวกันถูกนำไปใช้กับรูปหลายเหลี่ยม B.
-- Segments of the polygon B
CREATE VIEW segments_b AS SELECT sp, ep
FROM
-- extract the endpoints for every 2-point line segment for each linestring
(SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM
-- extract the individual linestrings
(SELECT (ST_Dump(ST_Boundary(geom))).geom
FROM polygon_b
) AS linestrings
-- be sure that nothing is scrambled
ORDER BY sp, ep
) AS segments;
ตารางส่วนรูปหลายเหลี่ยม B
SELECT
st_astext(sp) AS sp,
st_astext(ep) AS ep
FROM segments_b
LIMIT 3;
sp | ep
-------------------------------------------+-------------------------------------------
POINT(-292.268907321861 95.0342877387557) | POINT(-287.118411917425 99.4165242769195)
POINT(-287.118411917425 99.4165242769195) | POINT(-264.62129248575 93.2470010145007)
POINT(-277.459563916327 -44.5629543976138) | POINT(-292.268907321861 95.0342877387557)
...
segments_diff_{a,b}
ฉันสามารถสร้างมุมมองตารางความแตกต่างที่มีชื่อว่า ความแตกต่างได้มาจากการไม่เกิดขึ้นของจุดเริ่มต้นหรือจุดสิ้นสุดที่เรียงลำดับในชุดเซกเมนต์ A และ B
CREATE VIEW segments_diff_a AS
SELECT st_makeline(b.sp, b.ep) as geom
FROM segments_b as b
LEFT JOIN segments_a as a ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon A
WHERE a.sp IS NULL;
และสิ่งที่สมบูรณ์:
CREATE VIEW segments_diff_b AS
SELECT st_makeline(a.sp, a.ep) as geom
FROM segments_a as a
LEFT JOIN segments_b as b ON (a.sp=b.sp and a.ep = b.ep)
-- filter segments without corresponding stuff in polygon B
WHERE b.sp IS NULL;
สรุป: เพื่อให้ได้ผลลัพธ์ที่เหมาะสมสำหรับกลุ่มเล็ก ๆ น้อย ๆ ที่คุณทำเครื่องหมายด้วยลูกศรสีแดงรูปหลายเหลี่ยมทั้งคู่จะต้องมีโครงสร้างและโหนดที่เหมือนกันและขั้นตอนการแยกในระดับโหนด (จำเป็นต้องใส่จุดยอดของรูปหลายเหลี่ยม สี่แยกสามารถทำได้โดย:
CREATE VIEW segments_bi AS
SELECT distinct sp, ep
FROM (
SELECT
ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) as sp,
ST_PointN(geom, generate_series(2, ST_NPoints(geom) )) as ep
FROM (
SELECT st_difference(b.seg, a.seg) as geom FROM
segments_diff_a as a, segments_diff_b as b
WHERE st_intersects(a.seg, b.seg)
) as cut
) as segments
WHERE sp IS NOT NULL AND ep IS NOT NULL
ORDER BY sp, ep;
แต่ด้วยผลลัพธ์ที่แปลก ...