ใช้หุ่นดี: แปลระหว่างรูปหลายเหลี่ยมและ MultiPolygons


12

[แก้ไข: การแก้ปัญหานี้เพียงเพื่อใช้ OGR เพื่ออ่านรูปร่างไฟล์ ดูตัวอย่างของ geographika]

ใน Shapefile ของ ESRI ไม่มีความแตกต่างระหว่างรูปหลายเหลี่ยมและ MultiPolygons นอกจากนี้ไม่มีความแตกต่างที่ชัดเจนระหว่างหลุมภายในและวงแหวนภายนอก (นอกเหนือจาก "ความถนัด" ของรูปหลายเหลี่ยมที่กำหนด)

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

ปรากฏว่าสำหรับหุ่นดี 's รูปหลายเหลี่ยมและ MultiPolygon ก่อสร้างจะต้องมีความแตกต่างที่ชัดเจนระหว่างภายนอกและแหวนภายในดังนั้นวิธีการที่ฉันควรจะย้ายจากรายการที่ไม่ชัดเจนของแหวนชุดสั่งซื้อของรูปหลายเหลี่ยมแยกออกจากกันกับที่กำหนดไว้อย่างชัดเจนภายในและแหวนภายนอก ?

ในการสรุป: ถ้าฉันมีรายการรูปหลายเหลี่ยมของวง แต่ฉันไม่รู้ว่าวงแหวนใดที่เป็นรูในการตกแต่งภายในหรือเป็นรูปหลายเหลี่ยมที่แยกจากกัน

ฉันกำลังมองหาโซลูชันอัลกอริทึมแบบง่ายที่ฉันสามารถนำไปใช้ในไพ ธ อนสามารถใช้ในการประมวลผลรูปหลายเหลี่ยมหลายร้อยใน ~ นาทีหรือน้อยกว่าและฉันทำเช่นนี้เพื่อดำเนินการแยกจำนวนมาก


คำถามนี้ไม่มีข้อมูลที่สำคัญเกี่ยวกับสิ่งที่คุณใช้ในการอ่าน Shapefile
inc42

@ inc42 ฉันใช้หลามเพื่ออ่านไฟล์โดยตรง
BenjaminGolder

อ่าบิต Shapely นั้นทำให้เข้าใจผิด ปัญหาที่แท้จริงของคุณคือการหาวิธีกำหนด "ชนิด" ของวงแหวนในรูปแบบ Shapefile :)
inc42

คำตอบ:


10

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

อธิบายอีกครั้งเกิดอะไรขึ้นกับโปรแกรมอ่านไฟล์รูปร่างที่มีอยู่

การเอ็กซ์พอร์ตฟีเจอร์ ID และค่า M จาก Shapefile นั้นจะไม่ง่ายกว่าหรือไม่จากนั้นเข้าร่วมกลับไปยังรูปหลายเหลี่ยมหลังจากใช้ตัวอ่าน Shapefile ที่มีอยู่แล้วหรือไม่

สำหรับการจับคู่แบบหลายชุดคุณสามารถใช้เทคนิคเดียวกับการกำหนดรูปหลายเหลี่ยม ID ให้กับ "ID ตัวแก้ไข" แล้วเพิ่มแอททริบิวนี้กลับไปที่ฟีเจอร์

แก้ไข: ในขณะที่คุณพูดว่าคุณไม่ต้องการใช้ OGR ในกรณีที่คุณเปลี่ยนใจ ..

import ogr
# Get the driver
driver = ogr.GetDriverByName('ESRI Shapefile')
# Open a shapefile
shapefileName = "D:/temp/myshapefile.shp"
dataset = driver.Open(shapefileName, 0)

layer = dataset.GetLayer()
for index in xrange(layer.GetFeatureCount()):
    feature = layer.GetFeature(index)
    geometry = feature.GetGeometryRef()
    #geometry for polygon as WKT, inner rings, outer rings etc. 
    print geometry

รูปทรงเรขาคณิตควรมีผลลัพธ์ดังนี้:

POLYGON ((79285 57742,78741 54273...),(76087 55694,78511 55088,..))

วงเล็บแรกประกอบด้วย coords ของวงแหวนด้านนอกซึ่งตามมาคือวงเล็บเหลี่ยมของวงแหวนภายใน หากคุณมีคะแนนค่า Z ควรอยู่ในรูปแบบ 79285 57742 10 (โดยที่พิกัดสุดท้ายคือความสูง)

มิฉะนั้นคุณสามารถใช้ฟังก์ชั่น Shapely ประกอบด้วยและภายในเพื่อประเมินรูปหลายเหลี่ยมด้วยกันและใช้ดัชนีเชิงพื้นที่ล่วงหน้า - http://pypi.python.org/pypi/Rtree/เพื่อเพิ่มความเร็วในการประมวลผล


ขอบคุณนี่ไม่ใช่สิ่งที่ฉันกำลังมองหา แต่ฉันเห็นการชี้แจงเพิ่มเติมที่ฉันสามารถทำได้กับคำถามของฉัน เพื่อตอบคำถามของคุณ: 1 เพราะฉันกำลังเรียงลำดับพวกเขาให้ทำสี่แยกเป็นตันในตอนแรก 2 ไม่มีอะไรฉันแค่ต้องการอันที่มีน้ำหนักเบาและฉันสามารถใช้งานได้ง่ายจาก python และฉันไม่ได้เรียนรู้ ogr 3 ไม่มันจะไม่ง่ายขึ้นในกรณีนี้
BenjaminGolder

1
ว้าว! ขอบคุณ geographika! ตอนนี้ฉันเชื่อแล้ว 90% ว่า ogr เป็นวิธีแก้ปัญหา ฉันพบปัญหาในการติดตั้งกับ ogr แต่ดูเหมือนว่าพวกเขาควรค่ากับการทำงาน ดังนั้น ogr จัดวงแหวนในเอาต์พุต wkt หรือไม่? และมันก็ใช้ได้กับรูปร่างสามมิติ (ฉันใช้ 3d มาก)?
BenjaminGolder

ดูเหมือนว่าคำตอบสำหรับคำถามของฉันคือใช่และใช่ และขอขอบคุณที่แนะนำให้ฉันรู้จัก rtree OGR ดูเหมือนจะแก้ปัญหาของฉันทั้งหมด - ตราบใดที่ฉันสามารถกำหนดค่าการติดตั้งได้อย่างถูกต้องในครั้งนี้
BenjaminGolder

การติดตั้ง OGR ซ้ำ - โปรดจำไว้ว่าคุณจะต้องใช้ไบนารีสำหรับ Windows และการเชื่อมโยง Python ที่ตรงกัน
geographika

9

ก่อนอื่นให้ใช้ ogr เพื่อเปิด shapefile:

from osgeo import ogr
source = ogr.Open("mpolys.shp")
layers =  source.GetLayerByName("mpoly")
len(layers)
1

แปลงรูปทรง shapefile เป็นรูปทรงเรขาคณิตที่ดี

from shapely.wkb import loads
element=layers[0] #(because lenght of layer =1, else you need "for element in layers: ...")
geom = loads(element.GetGeometryRef().ExportToWkb())
geom.geom_type
'MultiPolygon'
print geom
MULTIPOLYGON ((..... # the geometry in shapely wkt format

สำหรับรูปหลายเหลี่ยมในรูปหลายเหลี่ยม:

poly=[]
for pol in geom:
    poly.append(pol)
poly[0]
<shapely.geometry.polygon.Polygon object at 0x00B82CB0>
poly[0].geom_type
'Polygon'
print(poly[1])
POLYGON ((.... # the geometry in shapely wkt format

และตอนนี้คุณสามารถใช้ฟังก์ชั่นทั้งหมดของหุ่นดี ( หุ่นดี )


1

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

นั่นอาจเป็น 'การประมวลผลที่เข้มข้นมากขึ้น' ที่คุณต้องการหลีกเลี่ยง แต่จริงๆแล้วเป็นเพียงการวนซ้ำผ่านพิกัดที่มาฟรีเมื่อคุณต้องอ่านมันต่อไป


ฉันขอโทษ - คำถามของฉันทำให้เข้าใจผิดเล็กน้อยและฉันได้แก้ไขแล้ว ฉันมีรูปหลายเหลี่ยมและฉันรู้ว่าเมื่อฉันมีรายการของรูปหลายเหลี่ยมมากกว่าหนึ่งแหวน แต่นอกเหนือจากคำสั่งตามเข็มนาฬิกาหรือทวนเข็มนาฬิกาของจุดฉันไม่ทราบว่าพวกเขาเป็นวงแหวนภายในหรือภายนอก หากพวกเขาเป็นวงแหวนภายในฉันไม่มีวิธีที่จะแน่ใจได้ว่าวงแหวนภายนอกนั้นเป็นของใครนอกจากการวัดตำแหน่งของพวกเขา
BenjaminGolder

ฉันเห็น. ฉันก็ดีใจที่เห็นว่าคุณพบหนทางสู่ ogr ;)
relet

-2

ตามที่ระบุโดย @ inc42ในหน้า 8 ของคำอธิบายทางเทคนิค Shapefile ESRI: กระดาษสีขาว ESRI - กรกฎาคม 1998 (หน้า 12 จาก 34 ใน PDF) มีการอภิปรายเนื้อหารูปหลายเหลี่ยมบันทึกซึ่งอาจเป็นสิ่งที่คุณหลังจาก:

รูปหลายเหลี่ยมอาจมีวงแหวนด้านนอกหลายวง คำสั่งของจุดยอดหรือการวางแนวของวงแหวนจะระบุว่าด้านใดของวงแหวนที่อยู่ด้านในของรูปหลายเหลี่ยม


p.10 มีหรือไม่ "รูปหลายเหลี่ยมอาจมีวงแหวนรอบนอกหลายวงลำดับของจุดยอดหรือทิศทางสำหรับวงแหวนระบุว่าด้านใดของวงแหวนที่อยู่ภายในของรูปหลายเหลี่ยม"
inc42

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