ArcPy를 사용하여 여러 줄의 끝점을 연결하는 다각형을 만드시겠습니까?


10

ArcGIS에서 pythonscript와 함께 polyilnes 세트를 포함하는 shapefile의 모든 끝점을 연결하는 다각형을 만드는 방법을 알아 내려고하는데 다각형의 노드 순서가 중요하기 때문에이 작업을 수행하는 데 문제가 있습니다. 녹색 선에서 그림의 회색 다각형을 달성하고 싶습니다.

녹색 선의 끝점을 연결하여 수동으로 할 필요없이 회색 다각형을 만들고 싶습니다.


라인에 주문을 제공 할 속성이 있습니까?
Ian Turton

먼저, @iant가 요청한대로 정의 된 순서가 필요합니다. 그런 다음 끝점을 다음 시작점에 연결하거나 다른 방식으로 수행할지 여부가 필요합니다.
Matej

3
종말점에 일종의 알파 선체가 없을까요?
Ian Turton

라인에는 어느 정도 순서를 지정할 수있는 속성이 있습니다. ID 번호가 있지만 위의 예에서 오른쪽 지점의 ID는 1-7, 왼쪽 15-21이며 연결 후 ID는 22-27입니다.
Amanda

1
a) 선을 사용하여 TIN 만들기, b) TIN을 삼각형으로 변환 c) 선과 경계를 공유하는 삼각형을 선택하면 매우 가까워 질 수 있습니다. 상단에 삭제할 다각형은 1 개뿐입니다.
FelixIP

답변:


11

단계 :

계산 섹션 중심점 : 여기에 이미지 설명을 입력하십시오

유클리드 최소 스패닝 트리를 구축하고, 분해하여 버퍼를 계산하며, 가장 짧은 섹션 길이의 절반에 해당하는 거리 : 여기에 이미지 설명을 입력하십시오

버퍼의 경계 (닫힌 폴리 라인 버전의 버퍼)에서 단면 끝점을 만들고 연쇄 거리 (선을 따라 거리)를 계산합니다. 여기에 이미지 설명을 입력하십시오

연결 필드를 사용하여 오름차순으로 끝점을 정렬하십시오. 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 가지 기능) :

여기에 이미지 설명을 입력하십시오

QGIS의 Python 콘솔에서 실행하기위한 코드 (한 줄 파이썬 목록 이해의 알고리즘)는 다음과 같습니다.

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 값을 사용하여 새 다각형을 작성하는 것이 좋습니다. 게시물에 첨부 된 그림을 볼 수 없지만 포인트 순서가 중요하면 Python 목록에 x, y 값이 저장되면 정렬하십시오. http://resources.arcgis.com/EN/HELP/MAIN/10.1/index.html#//002z0000001v000000


1

@iant 주석을 확장하면 스냅 샷에 가장 가까운 형상은 끝점의 알파 모양 (알파 선체)입니다. 다행스럽게도 GIS SE에서 많은 수신 스레드가 이미 답변되었습니다. 예를 들면 다음과 같습니다.

문제를 해결하려면 먼저 Feature To Point 를 사용하여 끝점을 추출하십시오. 그런 다음 이 링크 의 Python 도구를 사용하여 오목 선체를 계산하십시오.


첫 번째 링크가 끊어진 것 같습니다.
PolyGeo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.