14

I have ArcGIS Desktop 10.2 and my challenge is how to extract the of number vertices in each polygon for all features like this:

enter image description here

enter image description here

enter image description here

I have many parcels in my feature class and I want to extract the number of vertices for all features separately, then I want to display XY coordinates for all vertices.

for more information, i just want to convert vertices for each polygon and display number of each vertices staring from 1 number, so if i have polygon and it have a 4 vertices, a want to convert polygon to vertices i display number of vertices like this (1,2,3,4,5), then displaying xy for each vertices, i think the real challenge id to, how to convert all polygon to vertices and make each number of vertices starting from 1 number.

2
  • Based on your edit, do you want each feature to have a unique ID (1....n) per feature and XY coordinates? Would you prefer one column/field to have all of this information for labeling purposes e.g. [1, 942744.1234, 924654.1234] [2, 952744.1234, 925654.1234] ...?
    – Aaron
    Jan 30, 2014 at 18:59
  • yeah, if not mistake, one filed have an ID for number of vertices each polygon like this (1,2,3,4),(1,2,3,4,5),(1,2,3,4,5,6,),(1,2,3,4,5,6,7,8,9) etc, then i think about xy may be easy if we called add xy tool from arctoolbox
    – GIS Man
    Jan 30, 2014 at 19:07

4 Answers 4

22

The easiest way to do this is to add a new integer field to the attribute table of the parcels layer. Then, run field calculator with the following expression:

!Shape!.pointCount-!Shape!.partCount

The !Shape!.pointCount returns the total number of vertices in the feature. However, the first vertex of each part is repeated at the end, in order to close the feature. To handle this, subtract one vertex for each part using -!Shape!.partCount.

Note that you will have to use the Python parser for this expression to work.

Field calculator

3
  • this is really pretty cool, but will not provide the XY for each of these vertices. Seems the answer would be to use both responses (i.e., also @Aaron's) to get all requested info.
    – Roland
    Jan 30, 2014 at 17:02
  • @Roland You are right...I missed the part of the question about XY vertices. In that case you'll have to use the SearchCursor method in Aaron's answer or a geoprocessing tool like Feature Vertices To Points (though this tool requires an ArcGIS for Desktop Advanced license).
    – dmahr
    Jan 30, 2014 at 17:09
  • thank you very much @dmahr, i think there is a step missing, when i calculate value, the result is count number of vertices, so if i have parcel feature class with 5 vertices i want to displaying it like this 1,2,3,4,5 on each vertices, not count all vertices in one number, the real challenge it, how to display number for each vertices starting from 1 number for each parcel.
    – GIS Man
    Jan 30, 2014 at 18:25
12

dmahr provided a good solution to count vertices. For a non-programmatic way to label each point with the XY coords, try the following workflow:

  1. Feature Vertices to Points
  2. Add two new fields (type: double) in the new point FC "X", "Y"
  3. Calculate geometry. Right click field > Calculate Geometry... > X Coordinate of Point (repeat for Y field)
  4. Add another field "XY" (type: Text)
  5. Calculate "XY" field in field calculator, where XY =

    str(!x!) + " , " + str(!y!)

  6. Label features. Right click layer > Labels > Label Field: XY

This produces the following results:

enter image description here

You can also perform these actions programmatically using explode_to_points with a search cursor (as a start).

Deconstruct a feature into its individual points or vertices. If explode_to_points is set to True, a multipoint feature with five points, for example, is represented by five rows.

(The default value is False)

arcpy.da.SearchCursor (in_table, field_names, {where_clause}, {spatial_reference}, {explode_to_points}, {sql_clause})
1
  • seems one would need some post process or use @dmahr's answer to get a per-feature summation of # of vertices.
    – Roland
    Jan 30, 2014 at 17:03
5

The code below combines the other answers and adds a bit to number the vertices. results

import arcpy
arcpy.env.workspace = "in_memory"
#paths
fc = r"...\polygons"
fc_out = r"...\vertices"
arcpy.MakeFeatureLayer_management(fc, "lyr")
# add fields if needed
for FIELD in ["DRAW_ORDER", "COUNT"]:
    if FIELD not in [field.name for field in arcpy.ListFields(fc)]:
        try:
            arcpy.AddField_management("lyr", FIELD, "SHORT")
        except Exception as e:
            print e
# get the number of points minus overlapping (@dmahr - GSE)
arcpy.CalculateField_management("lyr", "COUNT", "!Shape!.pointCount-!Shape!.partCount", "PYTHON")
# dict to iterate and check count
OIDS = {}
for row in arcpy.da.SearchCursor("lyr", ["OBJECTID", "COUNT"]):
    OIDS[row[0]] = row[1]
del row
# get vertices as points and add XY (@Aaron - GSE)
arcpy.FeatureVerticesToPoints_management("lyr", fc_out)
arcpy.AddXY_management(fc_out)
# start adding a number to the points
for OID in OIDS:
    order_count = 1
    rows = arcpy.da.UpdateCursor(fc_out, ["DRAW_ORDER", "COUNT"], "ORIG_FID = %d"%OID)
    for row in rows:
        # will leave the overlapping as NULL
        if order_count <= OIDS[OID]:
            row[0] = order_count
            rows.updateRow(row)
            order_count += 1
##        # this can set the overlapping to 0 or some unique value (999)
##        else:
##            row[0] = 0
##            rows.updateRow(row)

The points are labelled in drawing order. The last point (under the first) will have no label and can be deleted by selecting all points that have Null, or unique, "DRAW_ORDER" values if not needed for reconstruction. A definition query can be used to remove the overlapping points from display.

XY data is present, but I will leave that to your labeling/displaying desires. See Aaron's answer about adding a XY field for labeling.

I was also toying with FeatureClass to numpy array, but I finished this first.

3
  • thank you @gm70560, i have followed your code variables, and save it as .py, but when i want to execute it, an error message appears, "The field name specified does not exist within the table", so what can i do?
    – GIS Man
    Feb 8, 2014 at 10:49
  • here is a print screen form my pc, i just set the target feature class path, and the path for output new feature class, in you code, if you can make a guideline for how to use your code, imageshack.com/i/fvsozep
    – GIS Man
    Feb 9, 2014 at 6:43
  • It didn't add the field (?). What happened further up in the results? I have a chat room to dump the full results. Leave a comment so I can check the room.
    – gm70560
    Feb 9, 2014 at 7:21
4

If one doesn't want to calculate a new field and just want to get a number of vertices per layer back really quickly (for generalization purposes such when exposing the datasets on the web), then it's possible to create a custom script tool inside a toolbox or expose the code as a Python add-in.

Custom script tool code:

import arcpy
in_fc = arcpy.GetParameterAsText(0)

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])
arcpy.AddMessage("***************************************")
arcpy.AddMessage("Number of vertices in the layer: {0}".format(count_vertices))
arcpy.AddMessage("***************************************")

Python add-in code (select a layer in the TOC to count vertices):

import arcpy
import pythonaddins

arcpy.env.overwriteOutput = True
mxd = arcpy.mapping.MapDocument("current")
in_fc = pythonaddins.GetSelectedTOCLayerOrDataFrame()

features = [feature[0] for feature in arcpy.da.SearchCursor(in_fc,"SHAPE@")]
count_vertices = sum([f.pointCount-f.partCount for f in features])

pythonaddins.MessageBox(count_vertices, 'Number of vertices in {0}'.format(in_fc.name), 0)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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