Extracting vertices from a polygon to create coordinate points (feature vertices to point)

5673
10
08-15-2016 06:29 PM
CaitlinMaher
New Contributor

I am looking for a way to extract coordinate points from a road casement i have drawn to put them in a new shapefile and create a table of coordinate points for the road. I have been taught to turn on vertex snapping to the casement in an editing session for my coordinate point shapefile and just run mouse over the casement until it snaps to a vertex and then create a point there but this method seems extremely inefficient so I'm hoping someone has a better way.

Thanks 😃

0 Kudos
10 Replies
DanPatterson_Retired
MVP Esteemed Contributor

seems like an awful hard way to create point vertices when you can use Feature Vertices To Points—Help | ArcGIS for Desktop 

or if you don't have the license level, then there are other options

CaitlinMaher
New Contributor

Thanks Dan, I did check out that option but unfortunately don't have the license to use any of the "feature to" type tools. You mentioned there are other options, would love to hear any other suggestions?

0 Kudos
NeilAyres
MVP Frequent Contributor

Try Ianko's tools.

I see Poly to Point is a free tool in ET Geo wizards.

http://www.ian-ko.com/

Otherwise you would have to use some python / arcpy magic.

FC_Basson
MVP Regular Contributor

With Python you can iterate the polygon part vertices and write them to a new table.  You can change the field names and outputs as required.  Select a single polygon segment to only write one table and run the script from the ArcMap Python console.

import arcpy
mxd = arcpy.mapping.MapDocument('CURRENT')
df = mxd.activeDataFrame
layers = arcpy.mapping.ListLayers(df)
layer = layers[0]

with arcpy.da.SearchCursor(layer, ["SHAPE@", "OBJECTID"]) as lcursor:
 for lrow in lcursor:
   polygon = lrow[0]
   objId = lrow[1]
   # create table for selected feature
   arcpy.CreateTable_management(arcpy.env.scratchWorkspace, "pntTable_" + str(objId))
   table = arcpy.env.scratchWorkspace + "\\pntTable_" + str(objId)
   # add fields or use a template
   arcpy.AddField_management(table, "X", "DOUBLE")
   arcpy.AddField_management(table, "Y", "DOUBLE")
   icursor = arcpy.da.InsertCursor(table, ["X", "Y"])
   # iterate through polygon parts
   part = polygon.getPart(0) # assuming a single part polygon
   # list polygon part points
   for pnt in part:
     print "X: " + str(pnt.X) + " Y: " + str(pnt.Y)
     # add to table
     icursor.insertRow([pnt.X, pnt.Y])
   del icursor
del lcursor‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
NeilAyres
MVP Frequent Contributor

Sorry FC, but shouldn't the Create table and the InsertCursor stuff be outside the Search Cursor loop.

At the mo, you are creating a new table for every row in the SearchCursor.

0 Kudos
FC_Basson
MVP Regular Contributor

Yes Neil, it could/should sit outside.  I put it inside just for demo purposes.  The main thing is to show the iteration over the polygon part vertices.

0 Kudos
NeilAyres
MVP Frequent Contributor

Ha....

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

For a shorter way

# -*- coding: utf-8 -*-
"""
:Created on Tue Aug 16 04:47:18 2016   @author: Dan
:Script:   poly_to_points.py
:Author:   Dan.Patterson@carleton.ca
:Modified: 2016-07-09
:Purpose:  polygon to point demo
:Requires: nothing
:Notes:    none
:Functions: can't you read
:References: none yet
"""

import arcpy


def main():
    """
    : - Produce a structured array from an input file
    : - Print information for that array
    : - Output a shapefile
    """
    input_shp = r"F:\Test2\AOI_mtm9.shp"   # change obviously
    output_shp = r"F:\Test2\AOI_pnts.shp"  # also
    desc_obj = arcpy.Describe(input_shp)
    SR = desc_obj.spatialReference         # spatial reference object
    OID_fld = desc_obj.OIDFieldName        # FID normally
    shp_fld = desc_obj.shapeFieldName
    print("using...\n{}\nto create...\n{}".format(input_shp, output_shp))
    print("file read...")
    arr = arcpy.da.FeatureClassToNumPyArray(input_shp, [OID_fld, shp_fld],
                                            spatial_reference=SR,
                                            explode_to_points=True)
    arcpy.da.NumPyArrayToFeatureClass(arr, output_shp, shp_fld, SR)
    print("file written...\n{}".format(arr))
    return arr


# -------------------------------------------------------------------------
if __name__ == "__main__":
    """Test section, just modify main()   """
    arr = main()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

output

[(0, [340000.0, 5022000.0]) (0, [340000.0, 5026000.0])
 (0, [344000.0, 5026000.0]) (0, [344000.0, 5022000.0])
 (0, [340000.0, 5022000.0])]‍‍‍‍‍‍

# with repr(arr)instead of str representation

print(repr(arr))

array([(0, [340000.0, 5022000.0]), (0, [340000.0, 5026000.0]),
       (0, [344000.0, 5026000.0]), (0, [344000.0, 5022000.0]),
       (0, [340000.0, 5022000.0])], 
      dtype=[('FID', '<i4'), ('Shape', '<f8', (2,))])‍‍‍‍‍‍‍‍

Of course this could be all fluffed up if there was more than one polygon, single-part or multipart, with/without holes and it had attributes.  It doesn't matter... the polygon is exploded into its constituent parts and returned as a featureclass/shapefile depending on your preference.

NeilAyres
MVP Frequent Contributor

Cool. I had forgotten about the "explode to points" option. Mr Numpy rules

0 Kudos