Estrarre coordinate di vertici poligonali in ArcMap?


25

Ho circa una dozzina di poligoni in una classe di funzioni caricata in ArcMap 10, tutti in WGS geografico 1984.

Come posso ottenere facilmente le coordinate associate a ciascun vertice di ciascun poligono in quella classe di caratteristiche?

Idealmente, vorrei che fossero ben tabulati in formato foglio di calcolo.

Risposte:



12

Funziona con una licenza 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

Questo è un altro modo per farlo usando 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

Con conseguente ObjectID, X e Y che possono essere copiati in 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
...

Domanda veloce, cosa sta succedendo nella parte 'array1.getObject (0) .getObject (vertice)'?
Rex,

@Rex vedi la sezione di aiuto per Array: pro.arcgis.com/en/pro-app/arcpy/classes/array.htm . Dall'array
prendo

Fantastico, questo mi aiuta a capirlo un po 'meglio. Quindi perché c'è un array in un array e non solo un array di punti? C'è qualcos'altro nel primo array? Cosa ti darebbe array1.getObject (1)?
Rex,

È perché ottieni tutte le parti in "row [1] .getPart ()", quindi il tuo primo array sono le diverse parti di una funzione multipart. Quindi avresti qualcosa al di là di array1.getObject (0) se avessi una funzione multipart?
Rex,

3

Prova gli strumenti di geomago delle tecnologie spaziali. Ha diversi strumenti gratuiti che possono fare quello che vuoi. Prova a ottenere le coordinate del poligono. O poligono a punti

et geo-maghi


2

Il seguente script python (che richiede ArcGIS 10.1 o successivo) utilizza arcpy.daper prendere uno shapefile come input e creare un foglio di calcolo con una voce per ogni vertice in ciascun poligono presente in .shp (e credo che funzioni con licenze arcgis di livello inferiore) . L'ID oggetto e sequenza lega i punti a una posizione specifica in un poligono specifico.

H / t @PaulSmith in questo post: ottieni tutti i punti di una polilinea per evidenziare l' explode_to_pointsopzione nello arcpy.da.FeatureClassToNumPyArraystrumento

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)

Ho anche scritto uno script che affronta in modo specifico i requisiti di: Inserisci le coordinate dei vertici nel poligono che è contrassegnato come duplicato a questa domanda, che il codice è sotto:

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)

Il primo script Python fa quello che ha chiesto hpy! Funziona molto velocemente! Grazie Grant Humphries!
ArisA,

1

Quindi non ho ancora completato la soluzione, ma sembra che tu possa usare questo strumento:

Conversione> JSON> Funzioni in JSON.

Questo convertirà il tuo shapefile (nel mio caso 81 poligoni) in un file JSON. Puoi aprirlo con un editor di testo per vedere che, in effetti, tutti i vertici sono elencati per ogni poligono.

Inoltre, la libreria standard di Python (import json) tratta gli oggetti json come dizionari. È quindi possibile semplicemente scorrere i dizionari per scrivere i valori dei vertici (e qualsiasi altro attributo desiderato) in un file CSV. Se lo faccio funzionare tornerò e pubblicherò il messaggio.


0

Avevo solo bisogno delle coordinate xey per Polyline e Polygon. Ho usato ToolBox -> Strumenti di gestione dati -> Funzionalità -> Funzionalità da puntare. Questo ha creato un file di forma di punto, quindi ho usato aggiungere coordinate XY dallo stesso menu Funzioni per generare coordinate XY. Quindi ho estratto le informazioni dalla tabella degli attributi di forme in un foglio Excel. Questo ha risolto il mio problema, non sono sicuro che tu stia cercando lo stesso.


Questo non ti darà solo un punto (X, Y) per polilinea / poligono quando la domanda richiede un punto (X, Y) per ciascun vertice in ciascuna polilinea / poligono?
PolyGeo

-2

Ecco una soluzione in tempi disperati:

  • Inizia a modificare la feature class o lo shapefile
  • Seleziona la funzione poligono e fai clic con il tasto destro del mouse su "Modifica vertici"
  • Fai clic con il tasto destro su uno dei vertici e seleziona "Proprietà schizzo"
  • Apparirà un riquadro a comparsa con le coordinate dei vertici elencati
  • Cattura una schermata dell'elenco delle coordinate
  • Incolla la schermata nel tuo editor di foto / immagini preferito e salva come jpeg / png / bmp ecc
  • Google "OCR online gratuito" Scegli uno dei risultati (alcuni sono migliori di altri)
  • Carica il tuo file della schermata delle coordinate e converti
  • Scegli il tipo di file di output (txt, Excel ecc.)
  • Controlla i risultati poiché alcuni convertitori OCR sono spazzatura !!!
  • Utilizzare i dati X, Y aggiunti in Arcmap per creare un set di dati punto.

Questo metodo è OK per piccoli set di dati, ma la dipendenza / le limitazioni sui convertitori OCR sono la principale preoccupazione. Usare con cautela.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.