ArcPy kullanarak çok satırlı çokgen bağlantı uç noktaları oluşturuluyor mu?


10

ArcGIS pythonscript ile bir dizi polyilnes içeren bir şekil dosyasının tüm uç noktalarını birbirine bağlayan bir çokgen oluşturmaya çalışıyorum, çokgendeki düğümlerin sırası önemli olduğu için bunu yaparken sorun yaşıyorum. Resimdeki gri poligonu yeşil çizgilerden elde etmek istiyorum

Gri poligonu manuel olarak yapmak zorunda kalmadan oluşturmak için yeşil çizgilerin uç noktalarını bağlamak istiyorum


Satırlarınızda sipariş vermek için bazı özellikler var mı?
Ian Turton

önce, @iant olarak tanımlanan siparişe ihtiyacınız var, o zaman bitiş noktasını bir sonraki başlangıç ​​noktasına bağlamak veya başka bir şekilde yapmak kuralına ihtiyacınız var
Matej

3
son noktalarında bir çeşit alfa gövdesi olabilir mi?
Ian Turton

Çizgi bir dereceye kadar onlara emir verme niteliklerine sahiptir. Bir kimlik numaraları var, ancak sağ dalın yukarıdaki örnekte 1-7, sol 15-21 var ve bağlandıktan sonra kimlikler 22-27
Amanda

1
A) TIN oluşturarak, çizgileri kullanarak, b) TIN'ı üçgenlere dönüştürerek c) çizgiyle bir sınırı paylaşan üçgenleri seçerek çok yaklaşabilirsiniz. Üstte silmek için yalnızca 1 çokgeniniz olacak
FelixIP

Yanıtlar:


11

ADIMLAR:

Bölümlerin merkez noktalarını hesaplayın: resim açıklamasını buraya girin

Öklid minimum yayılan ağaçlarını inşa ettiler, çözün ve tamponu hesaplayın, mesafe en kısa kesit uzunluğunun yarısına eşit: resim açıklamasını buraya girin

Bölüm bitiş noktaları oluşturun ve arabellek sınırında zincirlerini (çizgi boyunca mesafe) hesaplayın (tamponun kapalı çoklu çizgi versiyonu): resim açıklamasını buraya girin

Bitiş noktalarını zincirleme alanını kullanarak artan sırada sıralayın. Aşağıdaki FID'leri ile etiketlenmiş puanlar:

resim açıklamasını buraya girin

Sıralı nokta kümesinden çokgen oluşturun: resim açıklamasını buraya girin

Senaryo:

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

Bisiklet olduğunu biliyorum, ama kendiminkini ve onu seviyorum


2

QGIS için bu çözümü buraya gönderiyorum çünkü özgür yazılım ve uygulaması kolay. Ben sadece çoklu çizgi vektör katmanının doğru "dalını" düşündüm; bir sonraki resimde görülebileceği için (özellikler tablosunda 12 özellik):

resim açıklamasını buraya girin

QGIS Python Konsolunda çalıştırmak için kod (tek satırlık bir python listesi anlama algoritması):

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

Kodu çalıştırdıktan sonra:

resim açıklamasını buraya girin

bir çokgen bellek katmanı üretildi (öznitelikler tablosunda 11 özellik ile). Güzel çalışıyor.


1

Bir çokgene katılacak uç noktaları seçebilir, yalnızca bu noktalardan bir TIN oluşturabilirsiniz. TIN'i çokgenlere dönüştürün, çokgenleri çözün. Bu işlemi otomatikleştirmenin hilesi, her bir çokgene hangi noktaların katkıda bulunacağına karar vermektir. Geçerli yönleri olan satırlarınız varsa ve bu satırların tümü ortak bir özniteliği paylaşıyorsa, dışa aktarmak için bir sorgu yazarak uç köşeleri noktalara noktalarla noktalara çevirin, ardından ortak öznitelik değerine sahip noktaları sırayla seçin.
Noktaları ayıklamak / seçmek, x, y değerlerini bir imleç kullanarak okumak, yeni bir çokgen yazmak için x, y değerlerini kullanmak daha iyi olur. Gönderinizde ekli bir resim göremiyorum ama nokta sırası önemliyse, bir Python listesinde saklanan x, y değerlerine sahip olduktan sonra bunları sıralayın. http://resources.arcgis.com/EN/HELP/MAIN/10.1/index.html#//002z0000001v000000


1

@İant yorumunda genişleyen anlık görüntünüze en yakın geometri, uç noktaların alfa şeklidir (alfa gövdesi). Neyse ki GIS SE'de çok iyi kabul görmüş birçok konu cevaplanmıştır. Örneğin:

Sorununuzu çözmek için önce uç noktaları çıkarmak için Feature To Point özelliğini kullanın. Daha sonra içbükey gövdeyi hesaplamak için bu Bağlantıdaki python aracını kullanın .


İlk bağlantınız kopmuş gibi görünüyor.
PolyGeo
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.