I have a polygon feature class. I convert it to a point. Name of field (for example !Number!) in a point feature converted from polygon "A2"(The first point should be in the upper left corner (relative to north) of the polygon.) must match the direction of points in a clockwise. I know "AutoIncrement ()" at using Field Calculator, to change the numerical name of points by OBJECTID, but the point ID identifier sometimes do not match with the clockwise direction. Only one method that I know is to copy the contents of a table in Excel and renumber as I need. Then insert into ArcGIS the modified table in Excel and "display XY data"->"Data"->"Export data to point features". But maybe someone knows how to do it easier?enter image description here

  • 1
    Do you need to create new polygons so the vertex order starts in the Upper-Left or do you want a list of vertices, for each polygon, in the corrected order?
    – klewis
    Commented Nov 22, 2013 at 0:28
  • Both variants are good. I know how to fix the order of the vertices using Excel, but it is slow and not always convenient method. As a result, I need to make a list of vertices (including coordinates) for each polygon in the correct order. And the correct order of the vertices must be displayed on the map. I need the fastest possible way.
    – Jannik
    Commented Nov 26, 2013 at 0:08
  • Perhaps it might look like , 1 Use the repair tool geometry and vertex IDs goes clockwise direction . 2 converted polygons to points. 3 in attribute table using python autoIncrement () "expression. cal" 4 From upper left points are numbered with pStart = 1. 5 The rest of the points are numbered with pStart => next number of the last numbered point in paragraph 4 . 6 As a result, the point of going clockwise direction points are numbered as I need to . But they have the wrong ID order. Maybe it's not so important. Do you think there is another way more faster?
    – Jannik
    Commented Nov 26, 2013 at 5:32
  • Hi Jannik, did you find out a solution to your problem? Also interested if there is a way of doing this.
    – Slevy
    Commented Sep 12, 2016 at 5:19

5 Answers 5


Use the Repair Geometry tool - the polygon will be reset as clockwise direction.

The Check Geometry documentation says:

Incorrect ring ordering—The polygon is topologically simple, but its rings may not be oriented correctly (outer rings—clockwise, inner rings—counterclockwise).

While the Repair Geometry documentation does not mention clockwise/counterclockwise but says:

Incorrect ring ordering: The geometry will be updated to have correct ring ordering.

  • The first point should be in the upper left corner (relative to north) of the polygon.
    – Jannik
    Commented Nov 21, 2013 at 9:02
  • There is no topological requirement in GIS software that specifies where the first point should be. What is the rationale for such a need?
    – blah238
    Commented Nov 21, 2013 at 9:04
  • 1
    Conditions of numbering for issue of cadastral parcels.
    – Jannik
    Commented Nov 21, 2013 at 9:31
  • 4
    @Jannik but how do you define the upper left with complex shapes. Like in your exemple 6 is the left poitn, but 9 is the uppr point and 8 could be a "corner" candidate.
    – radouxju
    Commented Sep 12, 2016 at 5:56
  • Agree with @radouxju starting point requires better definition, e.g. nearest to NW corner of shape extent
    – FelixIP
    Commented Sep 18, 2016 at 20:25

The polygon below was created counterclockwise (not sure if it matters) starting at point 11/15. The point furthest to the left will get objectid 1.

import arcpy
arcpy.env.outputCoordinateSystem = 'D:\Projektionsfiler\SWEREF99TM.prj'

#Create points from polygon vertices
arcpy.FeatureVerticesToPoints_management(in_features='counterclockwise_polygon', out_feature_class='clockwise_points')
#Duplicate points are created at start/stop, removing one
with arcpy.da.UpdateCursor('clockwise_points',['OBJECTID'], 'OBJECTID = 1') as ucursor:
    for row in ucursor:

#create a list of x, y, and objectid of the clockwise points
coordinates = [f for f in arcpy.da.SearchCursor('clockwise_points',['SHAPE@X','SHAPE@Y','OBJECTID'])]

#find starting point = point furthest to the left
start_point = sorted(coordinates)[0]
#find index of start point in coordinates list
index_of_start_point = [i for i,x in enumerate(coordinates) if x[2]==start_point[2]]

#move start point to first position in list

#find index of points with smaller OBJECTID than start point
index_of_lesserpoints = [j for j,z in enumerate(coordinates) if z[2]<start_point[2]]

#create a new list and add coordinate pairs with Objectids in the right order starting with OBJECTID of start_point

#create a new point fc and insert points
arcpy.CreateFeatureclass_management(out_path=arcpy.env.workspace, out_name='new_clockwise_points', geometry_type='POINT')
with arcpy.da.InsertCursor('new_clockwise_points',['SHAPE@XY']) as icursor:
    for pair in coordinates_in_order:

enter image description here

  • Great, Will give this a shot. Would you know how this would handle donuts?
    – Slevy
    Commented Sep 19, 2016 at 3:40


enter image description here enter image description here


import arcpy

##  input parameters
mxd = arcpy.mapping.MapDocument("CURRENT")
polygons = arcpy.mapping.ListLayers(mxd,"PGONS")[0]
points = arcpy.mapping.ListLayers(mxd,"POINTS")[0]

##truncated coordinate as string
def truncate(f, n):
    s = '{}'.format(f)
    i, p, d = s.partition('.')
    return '.'.join([i, (d+'0'*n)[:n]])        

with arcpy.da.SearchCursor(polygons,["SHAPE@","MB2013"]) as cursor:
    for shp,idL in cursor:
##      get extent NW corner
        Q='"MB2013" = %s'%("'"+idL+"'")
##      order points along boundary at new start
        with arcpy.da.SearchCursor(points,"SHAPE@") as pCur:
            for line in pCur:
                if d<dMin: dMin=d;lMin=L
        for i,(L,pnt) in enumerate(aList):
            if L>=lMin: aList[i][0]=L-lMin
##     dictionary of points signatures and chainage
        for i,(L,pnt) in enumerate(newList):
##      transfer new order to points table
        with arcpy.da.UpdateCursor(points,("SHAPE@","GroupNo")) as pCur:
            for pnt,no in pCur:


enter image description here

I hope there are enough comments in the script to understand a method I applied. It is tested on shapefiles and of course field names are to be changed

  • This great, would you know how this would handle with donuts in the shape?
    – Slevy
    Commented Sep 19, 2016 at 3:39
  • 1
    It most likely will, providing points are sitting on the outer ring only, multipart - unlikely. Just test it, no harm expected
    – FelixIP
    Commented Sep 19, 2016 at 3:54

The Production Mapping extension includes a Set Origin Vertex tool that may suit your purposes:

A polygon is a collection of rings. Rings contain collections of points, or vertices, which describe a closed path. The first vertex, number 0, in the outermost ring of a polygon is the origin vertex. Vertices are oriented in a clockwise direction from the origin vertex. The origin vertex is the from-point (and to-point) of the ring that encloses a polygon.

The Set Origin Vertex tool allows you to change the origin vertex of a polygon feature. The following workflows may require you to use this tool:

  • Grid and graticules layers—Set an origin location for an area of interest.
  • Suppress outline geometry effect—Control where line suppression starts.
  • Ow its look like very simple but we dont have "Production Mapping extension". Maybe you know another way?
    – Jannik
    Commented Nov 22, 2013 at 8:43

Solving a portion of the problem, I recommend that the starting vertex is the vertex closest to the NW corner of the polygon's minimum bounding box (MBR).

An efficient processing function for the entire problem would:

  1. Create a temporary array of vertex, old and new vertex order
  2. Create a temporary point geometry variable and store the MBR NW cnr in it
  3. Read in a geometry into the temp array
  4. Measure each vertex distance to the NW corner of the MBR
  5. Find the minimum distance of all measures in step 4
  6. Assign that vertex as the start point (new order = 1)
  7. Assign the remaining vertex orders as +1 from the new start point, proceeding in the old order
  8. Update the geometry by recreating the vertex array in the new order
  9. Return the updated geometry

Examples of how to implement such ordinate array processing, temporary variable assignment, etc. can be found here for the case of SDO geometry storage in Oracle.

Not strictly an easier solution than manipulation in Excel, but it scales well to lots of polygons.

Your Answer

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

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