Tạo đa giác kết nối điểm cuối của nhiều dòng bằng ArcPy?


10

Tôi đang cố gắng tìm ra cách tạo ra một đa giác kết nối tất cả các điểm cuối của một shapefile có chứa một tập hợp các polyilnes với pythonscript trong ArcGIS, tôi gặp khó khăn khi thực hiện điều này vì thứ tự các nút trong đa giác là rất quan trọng. Tôi muốn đạt được đa giác màu xám trong hình từ các đường màu xanh lá cây

Tôi muốn kết nối các điểm cuối của các đường màu xanh lá cây để tạo đa giác màu xám mà không phải thực hiện thủ công


dòng của bạn có một số thuộc tính để đưa ra thứ tự?
Ian Turton

trước tiên, bạn cần thứ tự được xác định là @iant đã hỏi, sau đó bạn cần quy tắc cho dù kết nối điểm cuối với điểm bắt đầu tiếp theo hay thực hiện theo bất kỳ cách nào khác
Matej

3
thất bại có thể một số loại vỏ alpha trên các điểm cuối?
Ian Turton

Dòng nào ở một mức độ nào đó có thuộc tính để cung cấp cho chúng thứ tự. Họ có số ID, nhưng ví dụ ở phía trên bên phải có ID 1-7, bên trái 15-21 và sau khi họ được kết nối, ID là 22-27
Amanda

1
Bạn có thể tiến rất gần bằng cách a) tạo TIN, sử dụng các dòng, b) chuyển đổi TIN thành các tam giác c) chọn các tam giác có chung đường biên với các đường. Bạn sẽ chỉ có 1 đa giác để xóa ở trên cùng
FelixIP

Câu trả lời:


11

CÁC BƯỚC:

Tính điểm trung tâm phần: nhập mô tả hình ảnh ở đây

Xây dựng cây bao trùm tối thiểu Euclide của họ, hòa tan nó và tính toán bộ đệm, khoảng cách bằng một nửa chiều dài phần ngắn nhất: nhập mô tả hình ảnh ở đây

Tạo các điểm kết thúc của phần và tính toán chuỗi của chúng (khoảng cách dọc theo đường thẳng) trên đường biên của bộ đệm (phiên bản polyline đóng của bộ đệm): nhập mô tả hình ảnh ở đây

Sắp xếp các điểm cuối theo thứ tự tăng dần bằng cách sử dụng trường chainage. Các điểm dưới đây được dán nhãn bởi FID của họ:

nhập mô tả hình ảnh ở đây

Tạo đa giác từ tập hợp các điểm được sắp xếp: nhập mô tả hình ảnh ở đây

Kịch bản:

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()

Tôi biết nó là một chiếc xe đạp, nhưng nó là của riêng tôi và tôi thích nó


2

Tôi đăng giải pháp này cho QGIS tại đây vì đây là phần mềm miễn phí và dễ thực hiện. Tôi chỉ xem xét đúng "nhánh" của lớp vectơ polyline; vì nó có thể được quan sát ở hình ảnh tiếp theo (12 tính năng trong bảng thuộc tính):

nhập mô tả hình ảnh ở đây

Mã (thuật toán trong việc hiểu danh sách python một dòng), để chạy tại Bảng điều khiển Python của QGIS, là:

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()

Sau khi chạy mã:

nhập mô tả hình ảnh ở đây

nó được tạo ra một lớp bộ nhớ đa giác (với 11 tính năng trong bảng thuộc tính của nó). Nó hoạt động độc đáo.


1

Bạn có thể chọn các điểm cuối sẽ tham gia vào một đa giác, tạo TIN từ chỉ những điểm đó. Chuyển đổi TIN thành đa giác, hòa tan đa giác. Mẹo để tự động hóa quá trình này là quyết định điểm nào sẽ đóng góp cho mỗi đa giác. Nếu bạn có các dòng có chỉ đường hợp lệ và tất cả các dòng đó đều có chung một số thuộc tính chung, bạn có thể viết một truy vấn để xuất các đỉnh kết thúc bằng cách sử dụng các đỉnh của dòng thành các điểm, sau đó chọn theo các điểm có giá trị thuộc tính chung.
Tốt hơn là trích xuất / chọn các điểm, đọc các giá trị x, y bằng con trỏ, sử dụng các giá trị x, y để viết một đa giác mới. Tôi không thể nhìn thấy một hình ảnh đính kèm trong bài viết của bạn nhưng nếu thứ tự điểm quan trọng thì một khi bạn có các giá trị x, y được lưu trữ trong danh sách Python, hãy sắp xếp chúng. http://resource.arcgis.com/EN/HELP/MAIN/10.1/index.html#//002z0000001v000000


1

Mở rộng trên bình luận @iant, hình học gần nhất với ảnh chụp nhanh của bạn là hình dạng alpha (vỏ alpha) của các điểm cuối. May mắn thay, nhiều chủ đề được đón nhận đã được trả lời trên GIS SE. Ví dụ:

Để giải quyết vấn đề của bạn, trước tiên hãy sử dụng Feature To Point để trích xuất các điểm cuối. Sau đó sử dụng công cụ python từ Liên kết này để tính toán thân tàu lõm.


Liên kết đầu tiên của bạn dường như bị phá vỡ.
PolyGeo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.