24

I've got about a dozen polygons in a feature class loaded in ArcMap 10, all in geographic WGS 1984.

How do I easily obtain the coordinates associated with each vertex of each polygon in that feature class?

Ideally I would like them to be nicely tabulated in spreadsheet format.

30

Use the Feature Vertices To Points tool within ArcToolbox or if you do not have Advanced license then you may use the Polygon to Point tool from ET GeoWizard (free tool). Finally, in ArcMap use the Add XY Coordinates tool to generate the XY value for each vertex and use Table to Excel to generate a spreadsheet.

12

This works with a standard ArcGIS license:

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
8

There is a sample toolbox which includes a Write Features To Text File python script which:

Writes feature coordinates to a text file.

Note:

Technically, the tools in the Samples toolbox have been deprecated. They are still installed with ArcGIS so that any existing script or model tools you developed before 10 continue to work.

4

This is another way to do it using a 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

Resulting in ObjectID, X and Y which can be copied to 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
...
  • Quick question, what is going on at the 'array1.getObject(0).getObject(vertice)' part? – Rex Apr 24 '18 at 20:37
  • @Rex see help section for Array: pro.arcgis.com/en/pro-app/arcpy/classes/array.htm . From the Array i fetch each Point/vertice: i67.tinypic.com/34gstig.jpg – BERA Apr 25 '18 at 5:15
  • Great, that helps me understand it a bit better. So why is there an array in an array and not just an array of points? Is there anything else in the first array? What would array1.getObject(1) give you? – Rex Apr 25 '18 at 17:27
  • It is because you get all parts in "row[1].getPart()", therefore, your first array is the the different parts of a multipart feature. So you would only have something beyond array1.getObject(0) if you had a multipart feature? – Rex Apr 25 '18 at 17:34
3

Try the geo-wizard tools fron Spatial technologies. It has several free tools that can do what you want. Try the get polygon coordinates. Or polygon to points

et geo-wizards

2

The following python script (which requires ArcGIS 10.1 or later) utilizes arcpy.da to take a shapefile as an input and create a spreadsheet with an entry for each vertex in each polygon present in the .shp (and I believe it works with lower level arcgis licenses). Object and sequence id's tie the points back to a specific position in a specific polygon.

H/t to @PaulSmith in this post: Get all the points of a polyline for highlighting the explode_to_points option in the arcpy.da.FeatureClassToNumPyArray tool

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)

I also wrote a script that specifically addresses the requirements of: Insert vertices coordinates in polygon which is marked as duplicate to this question, that code is below:

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)
  • First python script does what hpy asked for! It works very fast! Thanks Grant Humphries! – ArisA Dec 15 '17 at 8:11
1

So I haven't completed the solution, yet, but it looks like you can use this tool:

Conversion > JSON > Features to JSON.

This will convert your shapefile (in my case 81 polygons) to a JSON file. You can open this with a text editor to see that, indeed, all the vertices are listed for each polygon.

Further, the python standard library (import json) treats the json objects as dictionaries. You can then simply loop through your dictionaries to write the vertex values (and any other attributes you want) to a csv file. If I get it to work I'll come back & post the soln.

0

I just needed the x and y co-ordinates for the Polyline and Polygon. I used ToolBox -> Data Management tools -> Features -> Feature to Point. This created a point shape file, then i used add XY coordinates from the same Features menu to generate XY co-ordinates. Then i extracted the information from shapes attribute table into a excel sheet. This solved my problem, not sure if you are looking for the same.

  • Won't this only give you one point (X,Y) per polyline/polygon when the question is asking for one point (X,Y) for each vertex in each polyline/polygon? – PolyGeo Aug 31 '16 at 6:51
-2

Here's a work-around in desperate times:

  • Start editing the feature-class or shapefile
  • Select the polygon feature and right-click to 'Edit Vertices'
  • Right-click on one of the vertices and select 'Sketch Properties'
  • A fly-out will appear with the coordinates of the vertices listed
  • Take a screen-shot of the coordinate list
  • Paste the screen-shot into your favourite photo/picture editor and save as a jpeg/png/bmp etc
  • Google 'Free online OCR' Pick one from the results (some are better than others)
  • Upload your file of the coordinate screen shot and convert
  • Choose your output file type (txt, Excel etc)
  • Check results as some OCR converters are rubbish!!!
  • Use the add X,Y data in Arcmap to create a point dataset.

This method is OK for small datasets but the dependency/limitations on the OCR converters are the main concern. Use with caution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.