เปลี่ยนรูปหลายเหลี่ยม“ ถนัดมือ” สำหรับ SQL 2008 (เรียงลำดับรูปหลายเหลี่ยมกลับด้าน)


11

ฉันมีสองสามร้อยรูปร่าง ( polygons และmultipolygons) แต่ละประกอบด้วยจุดนับหมื่นที่ฉันพยายามเข้าสู่ SQL 2008

น่าเสียดายที่รูปร่างที่ฉันพยายามนำเข้านั้นเป็น "ถนัดขวา" (เส้นรอบวงของแต่ละอันนั้นถูกลากตามเข็มนาฬิกาไปรอบ ๆ จุดที่มี) เซิร์ฟเวอร์ SQL สันนิษฐานว่าเป็นรูปร่าง "ถนัดซ้าย" (ทวนเข็มนาฬิการอบด้านใน) อย่างน้อยสำหรับgeographyประเภท ซึ่งหมายความว่า SQL ถือว่าฉันพยายามเลือกทั้งโลกยกเว้นรูปร่างของฉัน บางคนอธิบายว่านี่เป็นรูปร่าง "ด้านในออก"

จากMSDNซึ่งน่าผิดหวังไม่ได้บอกว่าจะใช้การวางแหวนแบบใด:

ถ้าเราใช้geographyชนิดข้อมูลเพื่อเก็บอินสแตนซ์อวกาศเราจะต้องระบุการวางแนวของวงแหวนและอธิบายตำแหน่งของอินสแตนซ์ได้อย่างถูกต้อง

หากคุณใช้การวางแนววงแหวนที่ไม่ถูกต้องใน SQL 2008 จะเกิดปัญหากับข้อผิดพลาดต่อไปนี้

ข้อผิดพลาด. NET Framework เกิดขึ้นระหว่างการดำเนินการตามขั้นตอนที่ผู้ใช้กำหนดเองหรือ "ภูมิศาสตร์" รวม: Microsoft.SqlServer.Types.GLArgumentException: 24205: อินพุตที่ระบุไม่ได้แสดงอินสแตนซ์ภูมิศาสตร์ที่ถูกต้องเพราะเกินซีกโลกเดียว ตัวอย่างภูมิศาสตร์แต่ละอันต้องอยู่ในซีกโลกเดียว สาเหตุทั่วไปสำหรับข้อผิดพลาดนี้คือรูปหลายเหลี่ยมที่มีการวางแนววงแหวนที่ไม่ถูกต้อง

การนำเข้ารูปทรงgeometryแทนการใช้geographyงานได้ดี แต่ฉันต้องการใช้geographyถ้าทำได้

ใน SQL 2012 ดูเหมือนว่าจะไม่สำคัญพอที่จะแก้ไขปัญหานี้ แต่ฉันผูกติดกับปี 2008

ฉันจะแปลงรูปร่างได้อย่างไร


1
+1 คำถามที่ยอดเยี่ยม ... คุณมีลิงค์ที่บอกว่าเซิร์ฟเวอร์ Sql ถือว่ารูปร่างด้านซ้ายมือหรือไม่?
Kirk Kuykendall

@ โบสถ์ขอบคุณ ฉันมีปัญหาในการค้นหาเอกสารอย่างเป็นทางการ แต่ฉันสามารถเชื่อมโยงไปที่ MSDN ซึ่งระบุว่าเรื่อง "การวางแนววงแหวน" (แม้ว่าจะไม่ได้บอกว่าจะใช้วิธีใด) ฉันจะใส่ข้อผิดพลาดที่ได้รับเมื่อเกิดข้อผิดพลาด
Michael - ที่ไหน Shirky Clay

คำตอบ:


14

บล็อกของ Spatial Edมีวิธีแก้ปัญหาที่กระชับ นี่คือ SQL แสดงให้เห็นถึงการเปลี่ยนแปลง:

DECLARE @geom GEOMETRY = 'POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))';
DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

และข้อความที่ตัดตอนมาจากโพสต์ของเอ็ด:

กุญแจสำคัญในพฤติกรรมนี้เป็นSTUnion()วิธีการ เนื่องจากนี่เป็นวิธีการที่ใช้OGC ซึ่งทำงานกับรูปทรงเรขาคณิตทั้งหมดสำหรับคุณลักษณะที่กำหนดจึงบังคับให้รูปหลายเหลี่ยมเข้ามาในทิศทางที่จำเป็นสำหรับวิธีนี้ซึ่งเพิ่งเกิดขึ้นกับรูปแบบที่ใช้สำหรับGeographyประเภท [... ] วิธีการแสดงนี้ค่อนข้างมีประสิทธิภาพทำให้ค่าใช้จ่ายเล็ก ๆ [... ]


2
ใน SQL Server 2008 r2 ฉันต้องใส่. MakeValid () ที่ด้านในของ STUnion () รวมถึงเพื่อให้มันใช้งานได้: .STUnion (@ geom.MakeValid (). STStartPoint ())
Chris Smith

@Styty ที่เหมาะสมสำหรับกรณีที่ SQL ไม่สามารถระบุจุดเริ่มต้นได้ บางทีถ้ารูปร่างกลับเป็นสองเท่าของมันเองหรือสถานการณ์แปลก ๆ ?
ไมเคิล - Clay Shirky อยู่ที่ไหน

ใช่ในกรณีของฉันรูปร่างเป็น whacky และทับซ้อนกัน
Chris Smith

0

ใน> = SQL Server 2012 วิธีการReorientObject ()ควรทำสิ่งนี้ให้สำเร็จ สำหรับ <SQL Server 2012 ด้านล่างเป็นวิธีทางเลือก

ที่มีอยู่ @g SQL ภูมิศาสตร์โค้ดด้านล่างจะดึงจุดและสร้างใหม่อีกครั้งรูปหลายเหลี่ยมที่มีจุด (จุด) เพื่อย้อนกลับ:
(หมายเหตุ 1: งานสำหรับรูปหลายเหลี่ยมที่เรียบง่ายไม่ได้สำหรับ multipolygons หรือรูปหลายเหลี่ยมกับแหวน / centroids)
(หมายเหตุ 2: ใช้ระบบพิกัด SRID 4326 (WGS 84))

--For existing geography @g
DECLARE @GeometryText varchar(max), @ReversedPolygon geography
DECLARE @GeometryType varchar(20) = 'POLYGON', @Count int
SET @Count = @g.STNumPoints()
WHILE @Count > 0
BEGIN
    SET @GeometryText = @GeometryText + CONVERT(varchar(30),CONVERT(decimal(12,8),@g.STPointN(@Count).Long)) + ' ' + CONVERT(varchar(30),CONVERT(decimal(12,8),@g.STPointN(@Count).Lat))
    SET @Count = @Count - 1
    IF @Count > 0 SET @GeometryText = @GeometryText + ','
END
SET @GeometryText = @GeometryType +'((' + @GeometryText + '))'
SET @ReversedPolygon = geography::STGeomFromText(@GeometryText, 4326); 

0

ดูเหมือนว่าฉันสามารถใช้บางส่วนไฮบริดไม่บริสุทธิ์ของ SQL และ C # จากSQL Server เครื่องมือเชิงพื้นที่ตามที่แนะนำในกองมากเกิน

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

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