Suite

Créer un polygone reliant les extrémités de plusieurs lignes à l'aide d'ArcPy ?


J'essaie de comprendre comment créer un polygone qui relie tous les points de terminaison d'un fichier de formes contenant un ensemble de polyilnes avec pythonscript dans ArcGIS, j'ai du mal à le faire car l'ordre des nœuds dans le polygone est important. Je veux réaliser le polygone gris dans l'image à partir des lignes vertes


PAS:

Calculer les points centraux des sections :

Construit leur arbre couvrant minimum euclidien, le dissoudre et calcule la mémoire tampon, la distance est égale à la moitié de la longueur de la section la plus courte :

Créez des points d'extrémité de section et calculez leur chaînage (distance le long de la ligne) sur la limite du tampon (version polyligne fermée du tampon) :

Triez les points d'extrémité dans l'ordre croissant à l'aide du champ de chaînage. Points ci-dessous étiquetés par leur FID :

Créer un polygone à partir d'un ensemble ordonné de points :

Scénario:

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 par le def prim de PRIM( nodes, edge ): conn = defaultdict( list ) pour n1,n2,c in edge: 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 ) tandis que usable_edges: coût, n1, n2 = heappop( usable_edges ) si n2 non utilisé: used.add( n2 ) mst.append( ( n1, n2, cost ) ) for e in conn[ n2 ]: si e[ 2 ] non utilisé: 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 avec arcpy.da.SearchCursor(SECTIONS, "[email protected]") comme curseur : # créer des points de centre et de fin pour r ow dans le curseur : 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('Computer minimum spanning tree') m=len(cPoints) nodes=[str(i) for i in range(m)] p=list (itt.combinations(range(m), 2)) arêtes=[] pour f,t dans p : p1=cPoints[f] p2=cPoints[t] dX=p2.X-p1.X;dY=p2. Y-p1.Y lenV=sqrt(dX*dX+dY*dY) edge.append((str(f),str(t),lenV)) MST=prim(nodes,edges) mLine=[] pour l'arête dans MST : p1=cPoints[int(edge[0])] p2=cPoints[int(edge[1])] mLine.append([p1,p2]) pLine=arcpy.Polyline(arcpy.Array(mLine),SR ) # créer un tampon et calculer le chaînage buf=pLine.buffer(lMin/2) outLine=buf.boundary() chaînage=[] pour p dans les points de terminaison : mesure=outLine.measureOnLine(p) chainage.append([mesure,p] ) chainage.sort(key=lambda x: x[0]) # polygone construit pGon=arcpy.Array() pour paire dans le chaînage : pGon.add(pair[1]) pGon=arcpy.Polygon(pGon,SR) curT = arcpy.da.InsertCurso r(PGONS,"[email protected]") curT.insertRow((pGon,)) del curT sauf : message = "
*** ERREURS PYTHON *** " ; showPyMessage() message = "Informations de suivi Python : " + traceback.format_tb(sys.exc_info()[2])[0] ; showPyMessage() message = "Informations d'erreur Python : " + str(sys.exc_type)+ " : " + str(sys.exc_value) + "
" ; showPyMessage()

Je sais que c'est un vélo, mais c'est le mien et j'aime ça


Je poste cette solution pour QGIS ici car il s'agit d'un logiciel gratuit et facile à mettre en œuvre. Je n'ai considéré que la "branche" droite du calque vectoriel polyligne; comme on peut l'observer sur l'image suivante (12 caractéristiques à la table des attributs) :

Le code (algorithme dans une compréhension de liste python d'une ligne), pour s'exécuter sur la console Python de QGIS, est :

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 formes fermées 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]) #création d'une couche mémoire pour plusieurs polygones crs = layer.crs() epsg = crs.postgisSrid() uri = "Polygon?crs=epsg:" + str(epsg) + "&field=id:integer""&index=yes" mem_layer = QgsVectorLayer(uri, "polygone", "mémoire") QgsMapLayerRegistry.instance().addMapLayer(mem_layer) mem_layer.startEditing() #Set features feature = [QgsFeature() for i in range(n-1)] for i dans la plage (n-1) : #set geometry feature[i].setGeometry(QgsGeometry.fromPolygon(mult_pol[i])) #set attributs valeurs feature[i].setAttributes([i]) mem_layer.addFeature(feature[i ], True) #arrêter l'édition et enregistrer les modifications mem_l ayer.commitChanges()

Après avoir exécuté le code :

il a été produit une couche mémoire polygonale (avec 11 entités dans sa table d'attributs). Cela fonctionne bien.


Vous pouvez sélectionner les extrémités qui participeront à un polygone, créer un TIN à partir de ces seuls points. Convertissez le TIN en polygones, dissolvez les polygones. L'astuce pour automatiser ce processus est de décider quels points contribuer à chaque polygone. Si vous avez des lignes avec des directions valides et que ces lignes partagent toutes un attribut commun, vous pouvez écrire une requête pour exporter, par exemple, les sommets de fin en utilisant des sommets de ligne vers des points, puis sélectionnez par attribut les points qui ont la valeur d'attribut commune.
Mieux vaudrait extraire/sélectionner les points, lire les valeurs x , y à l'aide d'un curseur, utiliser les valeurs x, y pour écrire un nouveau polygone. Je ne peux pas voir une image jointe dans votre message, mais si l'ordre des points est important, une fois que vous avez les valeurs x, y stockées dans une liste Python, triez-les. http://resources.arcgis.com/EN/HELP/MAIN/10.1/index.html#//002z0000001v000000


En développant le commentaire @iant, la géométrie la plus proche de votre instantané est la forme alpha (coque alpha) des extrémités. Heureusement, de nombreux fils de discussion bien reçus ont déjà reçu une réponse sur GIS SE. Par exemple:

  • Créer un polygone complexe à partir d'une couche de points en utilisant uniquement des points limites dans ArcGIS

  • Que sont la définition, les algorithmes et les solutions pratiques pour la coque concave ?

Pour résoudre votre problème, utilisez d'abord Caractéristique à point pour extraire les extrémités. Ensuite, utilisez l'outil python de ce lien pour calculer la coque concave.


Voir la vidéo: Cartes Hypsometrique sous ArcGis (Octobre 2021).