SQL Server - เลือกรูปหลายเหลี่ยมซ้อนกันภายในรูปหลายเหลี่ยมที่ใหญ่กว่า


9

นี่เป็นคำถามเชิงเรขาคณิตของ SQL Server ที่ดูเหมือนง่ายที่ฉันคิดว่าน่าจะมีโซลูชันนอกกรอบ แต่ฉันไม่มีโชคในการค้นหา

ความตั้งใจของฉันคือการเลือกระเบียนทั้งหมดภายในหนึ่งตารางที่มีรูปหลายเหลี่ยมที่ซ้อนกัน (มีอยู่) ภายในรูปหลายเหลี่ยมที่มีขนาดใหญ่กว่าจากตารางอื่น ฉันคาดหวังการทำงานSTWithinและSTContainsการแก้ปัญหาที่ฉันต้องการ แต่น่าเสียดายที่ทั้งคู่ระบุเฉพาะรูปหลายเหลี่ยมด้านในภายในรูปหลายเหลี่ยมขนาดใหญ่ไม่ใช่รูปหลายเหลี่ยมซ้อนกันที่สัมผัสกับขอบเขตของรูปหลายเหลี่ยมขนาดใหญ่ ดูภาพตัวอย่างเป็นผลมาจากทั้งฟังก์ชั่น STWithin และ STContains

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

STWithin:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STWithin(b.shape) = 1
where b.mktname = 'Loop'

STContains:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on b.shape.STContains(a.shape) = 1
where b.mktname = 'Loop'

STIntersection:

select a.shape.STIntersection(b.shape)
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

แก้ไข:

หนึ่งข้อเสนอแนะคือการละเว้นSTIntersectionและใช้เพียงอย่างเดียวSTIntersectsดังต่อไปนี้:

STIntersects:

select a.bg10
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

ปัญหาของวิธีการนี้คือSTIntersectsดูเหมือนว่าจะเลือกรูปหลายเหลี่ยมทั้งภายในและภายนอกและสัมผัสรูปหลายเหลี่ยมที่มีขนาดใหญ่ไม่ใช่เฉพาะที่อยู่ภายในอย่างเคร่งครัด ดูภาพตัวอย่างผลลัพธ์จากฟังก์ชัน STIntersects


คุณอาจจะลองทำบัฟเฟอร์น้อยที่สุดในรูปหลายเหลี่ยมที่มีของคุณและจากนั้นใช้อย่างใดอย่างหนึ่งหรือSTContains STWithinไม่ใช่แฮ็คที่ดีจริงๆ แต่จะให้ผลลัพธ์ที่คุณต้องการ ตัวเลือกอื่นจะทำ STIntersects ด้วยการเปรียบเทียบพื้นที่ Intersection และพื้นที่รูปหลายเหลี่ยม
MickyT

ฉันเริ่มทำงานในการเปรียบเทียบพื้นที่ แต่ได้เข้าไปในโพรงกระต่ายด้วยการเปรียบเทียบเรขาคณิตที่แปลงเป็นพื้นที่เป็นตัวเลข ฯลฯ ...
DPSSpatial

คำตอบ:


8

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

SELECT a.bg10 
FROM gis.usa_10_block_group a
    JOIN gis.usa_10_mkt_definition b
        ON a.shape.STWithin(b.shape.STBuffer(0.0001)) = 1
WHERE b.mktname = 'Loop'

นี่คือตัวอย่างรวดเร็วของพฤติกรรมที่คาดหวังของวิธีการเชิงพื้นที่สองสามอย่าง

SELECT Geometry::STGeomFromText(WKT,0), Description
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STIntersects(Geometry::STGeomFromText(WKT,0)) Intersects
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STContains(Geometry::STGeomFromText(WKT,0)) Contained
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STOverlaps(Geometry::STGeomFromText(WKT,0)) Overlaps
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STTouches(Geometry::STGeomFromText(WKT,0)) Touches
FROM (VALUES
    ('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'            ,'Interior corner')
    ,('POLYGON((90 90, 100 90, 100 100, 90 100, 90 90))' ,'Interior corner')
    ,('POLYGON((20 20, 40 20, 40 40, 20 40, 20 20))'     ,'Interior')
    ,('POLYGON((50 0, 70 0, 70 20, 50 20, 50 0))'        ,'Interior edge')
    ,('POLYGON((50 80, 70 80, 70 100, 50 100, 50 80))'   ,'Interior edge')
    ,('POLYGON((80 50, 100 50, 100 70, 80 70, 80 50))'   ,'Interior edge')
    ,('POLYGON((90 0, 110 0, 110 20, 90 20, 90 0))'      ,'Overlap')
    ,('POLYGON((100 50, 120 50, 120 70, 100 70, 100 50))','Exterior edge')
    )P(WKT,Description)
UNION ALL 
SELECT Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0),'Bounding Area',null,null,null,null

ผล

Description     Intersects Contained Overlaps Touches
--------------- ---------- --------- -------- -------
Interior corner 1          1         0        0
Interior corner 1          1         0        0
Interior        1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Overlap         1          0         1        0
Exterior edge   1          0         0        1
Bounding Area   NULL       NULL      NULL     NULL

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

2

ข้อความค้นหาจุดตัดควรมีลักษณะดังนี้ (สมมติว่าคุณต้องการให้บันทึกทั้งหมดกลับมาจาก 'a'):

select a.* --get all columns from table 'a'
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

ถ้าคุณต้องการแค่พื้นที่ของจุดตัด b นั้น (เช่นการตัด a ถึง b) คุณก็จะเพิ่ม STIntersection

select a.bg10
, a.STIntersection(b.geom) --clipped geometry from a against b
    from gis.usa_10_block_group a
    join gis.usa_10_mkt_definition b
    on a.shape.STIntersects(b.shape) = 1
    where b.mktname = 'Loop'

แต่นี่ยังไม่ได้รับรูปหลายเหลี่ยมที่อยู่ภายใน b แต่ ...

รูปหลายเหลี่ยมประเภทนี้ในรูปหลายเหลี่ยมนั้นมีลักษณะคล้ายกันมากกับขอบเขตและความบังเอิญของพวกเขา - เพื่อที่จะเป็น 'ภายใน' ขอบเขตของ a ไม่สามารถเกิดขึ้นพร้อมกับขอบเขตของ b - เหมือนกันสำหรับ 'มี'

ตามคำนิยามเหล่านี้วิธีการหลายรูปหลายเหลี่ยมของคุณเป็นจริงภายในข ... ?

คุณต้องการบัฟเฟอร์ b ก่อนที่คุณจะเลือกรูปหลายเหลี่ยมใน a ที่อยู่ภายในหรือไม่? หรือลบบัฟเฟอร์ใน a?

ไม่แน่ใจว่าคำตอบตรงนี้คืออะไร ...


ดูการแก้ไขสำหรับคำอธิบายแบบเต็มว่าทำไมสิ่งนี้จึงไม่ใช่สิ่งที่ฉันต้องการ
user1185790

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