Extraire les coordonnées des sommets des polygones dans ArcMap?


25

J'ai environ une douzaine de polygones dans une classe d'entités chargée dans ArcMap 10, tous dans WGS géographique 1984.

Comment obtenir facilement les coordonnées associées à chaque sommet de chaque polygone dans cette classe d'entités?

Idéalement, je voudrais qu'ils soient bien tabulés sous forme de feuille de calcul.

Réponses:



12

Cela fonctionne avec une licence ArcGIS standard:

desc = arcpy.Describe(fcl)
shapefieldname = desc.ShapeFieldName

gebieden = arcpy.UpdateCursor(fcl)

for gebied in gebieden:
    polygoon = gebied.getValue(shapefieldname)
    for punten in polygoon:
        for punt in punten:
            print punt.X, punt.Y


4

C'est une autre façon de le faire en utilisant un da.SearchCursor :

import arcpy
fc=r'C:\TEST.gdb\polygons123'

with arcpy.da.SearchCursor(fc,['OID@','SHAPE@']) as cursor:
    for row in cursor:
        array1=row[1].getPart()
        for vertice in range(row[1].pointCount):
            pnt=array1.getObject(0).getObject(vertice)
            print row[0],pnt.X,pnt.Y

Résultat en ObjectID, X et Y qui peuvent être copiés dans Excel:

...
1 537505.894287 6731069.60889
1 537533.516296 6731078.20947
1 537555.316528 6731082.53589
1 537562.501892 6731085.47913
1 537589.395081 6731070.52991
1 537617.062683 6731058.29651
2 537379.569519 6729746.16272
2 537384.81311 6729746.06012
2 537396.085327 6729748.62311
2 537404.065674 6729752.75311
2 537425.145325 6729773.72931
2 537429.842102 6729777.07129
2 537442.971313 6729780.10651
2 537450.27533 6729780.51611
...

Question rapide, que se passe-t-il dans la partie 'array1.getObject (0) .getObject (vertice)'?
Rex

@Rex voir la section d'aide de Array: pro.arcgis.com/en/pro-app/arcpy/classes/array.htm . À partir du tableau, je récupère chaque point / sommet
BERA

Génial, ça m'aide à mieux le comprendre. Alors pourquoi y a-t-il un tableau dans un tableau et pas seulement un tableau de points? Y a-t-il autre chose dans le premier tableau? Que vous apporterait array1.getObject (1)?
Rex

C'est parce que vous obtenez toutes les parties dans "row [1] .getPart ()", par conséquent, votre premier tableau est les différentes parties d'une fonctionnalité en plusieurs parties. Vous n'auriez donc quelque chose au-delà de array1.getObject (0) que si vous aviez une fonctionnalité en plusieurs parties?
Rex

3

Essayez les outils de géo-assistant des technologies spatiales. Il dispose de plusieurs outils gratuits qui peuvent faire ce que vous voulez. Essayez d'obtenir les coordonnées du polygone. Ou polygone aux points

et géo-assistants


2

Le script python suivant (qui nécessite ArcGIS 10.1 ou version ultérieure) utilise arcpy.dapour prendre un fichier de formes en entrée et créer une feuille de calcul avec une entrée pour chaque sommet dans chaque polygone présent dans le fichier .shp (et je crois qu'il fonctionne avec des licences arcgis de niveau inférieur) . Les identifiants d'objet et de séquence relient les points à une position spécifique dans un polygone spécifique.

H / t à @PaulSmith dans ce post: Obtenez tous les points d'une polyligne pour mettre en surbrillance l' explode_to_pointsoption dans l' arcpy.da.FeatureClassToNumPyArrayoutil

import os
import csv
import arcpy
from os import path
from arcpy import da
from arcpy import env

env.overwriteOutput = True
env.workspace = '/folder/containing/your/shp/here'

polygon_shp = path.join(env.workspace, 'your_shapefile_name.shp')
vertex_csv_path = 'your/csv/path/here/poly_vertex.csv'

def getPolygonCoordinates(fc):
    """For each polygon geometry in a shapefile get the sequence number and
    and coordinates of each vertex and tie it to the OID of its corresponding
    polygon"""

    vtx_dict = {}
    s_fields = ['OID@', 'Shape@XY']
    pt_array = da.FeatureClassToNumPyArray(polygon_shp, s_fields, 
        explode_to_points=True)

    for oid, xy in pt_array:
        xy_tup = tuple(xy)
        if oid not in vtx_dict:
            vtx_dict[oid] = [xy_tup]
        # this clause ensures that the first/last point which is listed
        # twice only appears in the list once
        elif xy_tup not in vtx_dict[oid]:
            vtx_dict[oid].append(xy_tup)


    vtx_sheet = []
    for oid, vtx_list in vtx_dict.iteritems():
        for i, vtx in enumerate(vtx_list):
            vtx_sheet.append((oid, i, vtx[0], vtx[1]))

    writeVerticesToCsv(vtx_sheet)

def writeVerticesToCsv(vtx_sheet):
    """Write polygon vertex information to csv"""

    header = (
        'oid',          'sequence_id', 
        'x_coordinate', 'y_coordinate')

    with open(vertex_csv_path, 'wb') as vtx_csv:
        vtx_writer = csv.writer(vtx_csv)
        vtx_writer.writerow(header)

        for row in vtx_sheet:
            vtx_writer.writerow(row)

getPolygonCoordinates(polygon_shp)

J'ai également écrit un script qui répond spécifiquement aux exigences de: Insérer les coordonnées des sommets dans le polygone qui est marqué comme doublon à cette question, ce code est ci-dessous:

import os
import arcpy
from os import path
from arcpy import da
from arcpy import env
from arcpy import management

env.overwriteOutput = True
env.workspace = '/folder/containing/your/shp/here'

polygon_shp = path.join(env.workspace, 'your_shapefile_name.shp')
file_gdb = 'your/file/gdb/path/here/temp.gdb'

def addVerticesAsAttributes(fc):
    """Add the x,y coordinates of vertices as attributes to corresponding 
    features.  The coordinates will be in the order the appear in the geometry"""

    polygon_copy = createGdbFcCopy(fc)

    vtx_dict = {}
    s_fields = ['OID@', 'Shape@XY']
    pt_array = da.FeatureClassToNumPyArray(polygon_copy, s_fields, 
        explode_to_points=True)

    for oid, xy in pt_array:
        xy_tup = tuple(xy)
        if oid not in vtx_dict:
            vtx_dict[oid] = [xy_tup]
        # this clause ensures that the first/last point which is listed
        # twice only appears in the list once
        elif xy_tup not in vtx_dict[oid]:
            vtx_dict[oid].append(xy_tup)

    # find that largest number of points that exist within a polygon to determine 
    # the number of fields that need to be added to the shapefile
    max_vertices = 0
    for vtx_list in vtx_dict.values():
        if len(vtx_list) > max_vertices:
            max_vertices = len(vtx_list)

    xy_fields = addXyFields(polygon_copy, max_vertices)

    u_fields = ['OID@'] + xy_fields
    with da.UpdateCursor(polygon_copy, u_fields) as cursor:
        oid_ix = cursor.fields.index('OID@')
        for row in cursor:
            xy_ix = oid_ix + 1
            for vtx in vtx_dict[row[oid_ix]]:
                for coord in vtx:
                    row[xy_ix] = coord
                    xy_ix += 1

            cursor.updateRow(row)

def createGdbFcCopy(fc):
    """Create copy of the input shapefile as a file geodatabase feature class,
    because a huge number of fields may be added to the fc this preferable to shp"""

    if not arcpy.Exists(file_gdb):
        management.CreateFileGDB(path.dirname(file_gdb), 
            path.basename(file_gdb))

    polygon_copy = path.join(file_gdb, 'polygon_shp_copy')
    management.CopyFeatures(polygon_shp, polygon_copy)
    return polygon_copy

def addXyFields(fc, vtx_count):
    """Add fields to the feature class that will hold the x, y coordinates for each
    vertex, the number of fields is twice the number of most vertices in any polygon"""

    field_list = []
    f_type = 'DOUBLE'
    for i in range(1, vtx_count+1):
        f_names = ['x{0}'.format(i), 'y{0}'.format(i)]
        for fn in f_names:
            management.AddField(fc, fn, f_type)

        field_list.extend(f_names)

    return field_list

addVerticesAsAttributes(polygon_shp)

Le premier script python fait ce que hpy a demandé! Ça marche très vite! Merci Grant Humphries!
ArisA

1

Je n'ai donc pas encore terminé la solution, mais il semble que vous pouvez utiliser cet outil:

Conversion> JSON> Fonctionnalités en JSON.

Cela convertira votre fichier de formes (dans mon cas, 81 polygones) en un fichier JSON. Vous pouvez l'ouvrir avec un éditeur de texte pour voir qu'en fait, tous les sommets sont répertoriés pour chaque polygone.

De plus, la bibliothèque standard python (import json) traite les objets json comme des dictionnaires. Vous pouvez ensuite simplement parcourir vos dictionnaires pour écrire les valeurs des sommets (et tout autre attribut souhaité) dans un fichier csv. Si je le fais fonctionner, je reviendrai et posterai le soln.


0

J'avais juste besoin des coordonnées x et y pour la polyligne et le polygone. J'ai utilisé ToolBox -> Outils de gestion des données -> Fonctionnalités -> Fonction à pointer. Cela a créé un fichier de forme de point, puis j'ai utilisé l'ajout de coordonnées XY à partir du même menu Fonctions pour générer des coordonnées XY. Ensuite, j'ai extrait les informations de la table d'attributs de formes dans une feuille Excel. Cela a résolu mon problème, je ne sais pas si vous recherchez la même chose.


Cela ne vous donnera-t-il qu'un seul point (X, Y) par polyligne / polygone lorsque la question demande un point (X, Y) pour chaque sommet de chaque polyligne / polygone?
PolyGeo

-2

Voici une solution de contournement en des temps désespérés:

  • Commencez à modifier la classe d'entités ou le fichier de formes
  • Sélectionnez l'entité polygonale et cliquez avec le bouton droit sur «Modifier les sommets»
  • Faites un clic droit sur l'un des sommets et sélectionnez «Propriétés d'esquisse»
  • Un fly-out apparaîtra avec les coordonnées des sommets listés
  • Prenez une capture d'écran de la liste des coordonnées
  • Collez la capture d'écran dans votre éditeur de photos / images préféré et enregistrez-le au format jpeg / png / bmp, etc.
  • Google 'OCR en ligne gratuit' Choisissez-en un parmi les résultats (certains sont meilleurs que d'autres)
  • Téléchargez votre fichier de la capture d'écran de coordonnées et convertissez
  • Choisissez votre type de fichier de sortie (txt, Excel, etc.)
  • Vérifiez les résultats car certains convertisseurs OCR sont des ordures !!!
  • Utilisez les données X, Y ajoutées dans Arcmap pour créer un jeu de données ponctuelles.

Cette méthode est correcte pour les petits ensembles de données, mais la dépendance / les limitations sur les convertisseurs OCR sont la principale préoccupation. Utiliser avec précaution.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.