การสร้างจุดเชื่อมต่อรูปหลายเหลี่ยมที่เชื่อมต่อของหลายบรรทัดโดยใช้ ArcPy?


10

ฉันกำลังพยายามหาวิธีการสร้างรูปหลายเหลี่ยมที่เชื่อมต่อจุดปลายทั้งหมดของ shapefile ที่มีชุดของ polyilnes ด้วย pythonscript ใน ArcGIS ฉันมีปัญหาในการทำเช่นนี้เนื่องจากลำดับของโหนดในรูปหลายเหลี่ยมนั้นมีความสำคัญ ฉันต้องการได้รูปหลายเหลี่ยมสีเทาในรูปภาพจากเส้นสีเขียว

ฉันต้องการเชื่อมต่อจุดสิ้นสุดของเส้นสีเขียวเพื่อสร้างรูปหลายเหลี่ยมสีเทาโดยไม่ต้องทำด้วยตนเอง


บรรทัดของคุณมีคุณสมบัติบางอย่างเพื่อให้การสั่งซื้อ?
Ian Turton

ครั้งแรกที่คุณจะต้องสั่งซื้อที่กำหนดไว้เป็น @iant ถามแล้วคุณต้องเชื่อมต่อกฎว่าปลายทางจะ StartPoint ถัดไปหรือทำวิธีอื่น ๆ
มาเตจ์

3
ล้มเหลวที่อาจเป็นเรืออัลฟาในจุดสิ้นสุดบางอย่าง?
Ian Turton

บรรทัดทำในระดับหนึ่งมีคุณลักษณะเพื่อให้พวกเขาสั่ง พวกเขามีหมายเลขประจำตัวประชาชน แต่สำหรับตัวอย่างด้านบน rightbranch มี ID 1-7 ทางซ้าย 15-21 และหลังจากที่พวกเขาเชื่อมต่อ ID คือ 22-27
Amanda

1
คุณสามารถเข้าใกล้มากโดย a) สร้าง TIN โดยใช้บรรทัด b) แปลง TIN เป็นรูปสามเหลี่ยม c) เลือกรูปสามเหลี่ยมที่แบ่งปันขอบเขตกับเส้น คุณจะมีรูปหลายเหลี่ยมเพียง 1 รูปที่จะลบที่ด้านบน
FelixIP

คำตอบ:


11

ขั้นตอน:

คำนวณคะแนนกลางส่วน: ป้อนคำอธิบายรูปภาพที่นี่

สร้างทรีสคริปขั้นต่ำแบบยูคลิด, ละลายและคำนวณบัฟเฟอร์, ระยะทางเท่ากับครึ่งหนึ่งของความยาวส่วนที่สั้นที่สุด: ป้อนคำอธิบายรูปภาพที่นี่

สร้างจุดสิ้นสุดของส่วนและคำนวณ chainage ของพวกเขา (ระยะทางตามแนวเส้น) บนขอบเขตของบัฟเฟอร์ (ปิดเวอร์ชัน polyline ของบัฟเฟอร์): ป้อนคำอธิบายรูปภาพที่นี่

เรียงลำดับจุดสิ้นสุดตามลำดับจากน้อยไปมากโดยใช้ฟิลด์ chainage คะแนนด้านล่างระบุโดย FID ของพวกเขา:

ป้อนคำอธิบายรูปภาพที่นี่

สร้างรูปหลายเหลี่ยมจากชุดคะแนนที่สั่ง: ป้อนคำอธิบายรูปภาพที่นี่

สคริปต์:

import arcpy, traceback, os, sys,time
from heapq import *
from math import sqrt
import itertools as itt
from collections import defaultdict

try:
    def showPyMessage():
        arcpy.AddMessage(str(time.ctime()) + " - " + message)
    # MST by PRIM's
    def prim( nodes, edges ):
        conn = defaultdict( list )
        for n1,n2,c in edges:
            conn[ n1 ].append( (c, n1, n2) )
            conn[ n2 ].append( (c, n2, n1) )
        mst = []
        used = set( nodes[ 0 ] )
        usable_edges = conn[ nodes[0] ][:]
        heapify( usable_edges )

        while usable_edges:
            cost, n1, n2 = heappop( usable_edges )
            if n2 not in used:
                used.add( n2 )
                mst.append( ( n1, n2, cost ) )

                for e in conn[ n2 ]:
                    if e[ 2 ] not in used:
                        heappush( usable_edges, e )
        return mst        


    mxd = arcpy.mapping.MapDocument("CURRENT")
    SECTIONS=arcpy.mapping.ListLayers(mxd,"SECTION")[0]
    PGONS=arcpy.mapping.ListLayers(mxd,"RESULT")[0]
    d=arcpy.Describe(SECTIONS)
    SR=d.spatialReference

    cPoints,endPoints,lMin=[],[],1000000
    with arcpy.da.SearchCursor(SECTIONS, "Shape@") as cursor:
        # create centre and end points
        for row in cursor:
            feat=row[0]
            l=feat.length
            lMin=min(lMin,feat.length)
            theP=feat.positionAlongLine (l/2).firstPoint
            cPoints.append(theP)
            theP=feat.firstPoint
            endPoints.append(theP)
            theP=feat.lastPoint
            endPoints.append(theP)

        arcpy.AddMessage('Computing minimum spanning tree')
        m=len(cPoints)
        nodes=[str(i) for i in range(m)]
        p=list(itt.combinations(range(m), 2))
        edges=[]
        for f,t in p:
            p1=cPoints[f]
            p2=cPoints[t]
            dX=p2.X-p1.X;dY=p2.Y-p1.Y
            lenV=sqrt(dX*dX+dY*dY)
            edges.append((str(f),str(t),lenV))
        MST=prim(nodes,edges)

        mLine=[]
        for edge in MST:
            p1=cPoints[int(edge[0])]
            p2=cPoints[int(edge[1])]
            mLine.append([p1,p2])
        pLine=arcpy.Polyline(arcpy.Array(mLine),SR)

        # create buffer and compute chainage
        buf=pLine.buffer(lMin/2)
        outLine=buf.boundary()
        chainage=[]
        for p in endPoints:
            measure=outLine.measureOnLine(p)
            chainage.append([measure,p])
        chainage.sort(key=lambda x: x[0])

        # built polygon
        pGon=arcpy.Array()
        for pair in chainage:
            pGon.add(pair[1])
        pGon=arcpy.Polygon(pGon,SR)
        curT = arcpy.da.InsertCursor(PGONS,"SHAPE@")
        curT.insertRow((pGon,))
        del curT
except:
    message = "\n*** PYTHON ERRORS *** "; showPyMessage()
    message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
    message = "Python Error Info: " +  str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()

ฉันรู้ว่ามันเป็นจักรยาน แต่มันเป็นของฉันและฉันก็ชอบ


2

ฉันโพสต์โซลูชันนี้สำหรับ QGIS ที่นี่เพราะเป็นซอฟต์แวร์ฟรีและใช้งานง่าย ฉันพิจารณาเฉพาะ "สาขา" ที่เหมาะสมของชั้นโพลีไลน์เวกเตอร์ ในขณะที่มันสามารถสังเกตได้ในภาพถัดไป (12 คุณสมบัติที่ตารางคุณลักษณะ):

ป้อนคำอธิบายรูปภาพที่นี่

รหัส (อัลกอริทึมในรายการบรรทัดความเข้าใจบรรทัดเดียว) สำหรับการทำงานที่ Python Console ของ QGIS คือ:

layer = iface.activeLayer()

features = layer.getFeatures()

features = [feature for feature in features]

n = len(features)

geom = [feature.geometry().asPolyline() for feature in features ]

#multi lines as closed shapes
multi_lines = [[geom[i][0], geom[i][1], geom[i+1][1], geom[i+1][0], geom[i][0]]
               for i in range(n-1)]

#multi polygons
mult_pol = [[] for i in range(n-1)]

for i in range(n-1):
    mult_pol[i].append(multi_lines[i])

#creating a memory layer for multi polygon
crs = layer.crs()
epsg = crs.postgisSrid()

uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes"

mem_layer = QgsVectorLayer(uri,
                           "polygon",
                           "memory")

QgsMapLayerRegistry.instance().addMapLayer(mem_layer)

mem_layer.startEditing()

#Set features
feature = [QgsFeature() for i in range(n-1)]

for i in range(n-1):
    #set geometry
    feature[i].setGeometry(QgsGeometry.fromPolygon(mult_pol[i]))
    #set attributes values
    feature[i].setAttributes([i])
    mem_layer.addFeature(feature[i], True)

#stop editing and save changes
mem_layer.commitChanges()

หลังจากรันรหัส:

ป้อนคำอธิบายรูปภาพที่นี่

มันผลิตเลเยอร์หน่วยความจำรูปหลายเหลี่ยม (มี 11 คุณสมบัติที่ตารางคุณลักษณะของมัน) มันใช้งานได้ดี


1

คุณสามารถเลือกจุดสิ้นสุดที่จะเข้าร่วมในรูปหลายเหลี่ยมสร้าง TIN จากเฉพาะจุดเหล่านั้น แปลง TIN เป็นรูปหลายเหลี่ยมละลายรูปหลายเหลี่ยม เคล็ดลับในการทำให้กระบวนการนี้เป็นแบบอัตโนมัติคือการตัดสินใจว่าจะให้คะแนนกับรูปหลายเหลี่ยมแต่ละแบบอย่างไร หากคุณมีเส้นที่มีทิศทางที่ถูกต้องและเส้นเหล่านั้นใช้คุณลักษณะทั่วไปบางอย่างร่วมกันคุณสามารถเขียนแบบสอบถามเพื่อส่งออกพูดจุดสิ้นสุดโดยใช้จุดยอดเส้นไปยังจุดจากนั้นเลือกตามแอตทริบิวต์จุดเหล่านั้นที่มีค่าแอตทริบิวต์ทั่วไป
ดีกว่าที่จะแยก / เลือกจุดอ่านค่า x, y โดยใช้เคอร์เซอร์ใช้ค่า x, y เพื่อเขียนรูปหลายเหลี่ยมใหม่ ฉันไม่เห็นรูปภาพที่แนบมาในโพสต์ของคุณ แต่ถ้าการสั่งซื้อแบบพอยต์มีความสำคัญเมื่อคุณมีค่า x, y ที่เก็บไว้ในรายการ Python ให้เรียงลำดับ http://resources.arcgis.com/EN/HELP/MAIN/10.1/index.html#//002z0000001v000000


1

การขยายความคิดเห็น @iant รูปทรงเรขาคณิตที่ใกล้เคียงที่สุดกับภาพถ่ายของคุณคือรูปร่างอัลฟ่า (alpha hull) ของจุดสิ้นสุด โชคดีที่กระทู้ตอบรับที่ดีจำนวนมากได้รับการตอบแล้วใน GIS SE ตัวอย่างเช่น:

ในการแก้ปัญหาของคุณให้ใช้ฟีเจอร์ทูชี้เพื่อแยกจุดสิ้นสุด จากนั้นใช้เครื่องมือหลามจากลิงค์นี้เพื่อคำนวณลำเรือเว้า


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