Le script python suivant (qui nécessite ArcGIS 10.1 ou version ultérieure) utilise arcpy.da
pour 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_points
option dans l' arcpy.da.FeatureClassToNumPyArray
outil
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)