5

I am working with a Search Cursor approach to calculate centroids within polygon features. You can see from the screenshot that the script calculates centroids within polygon features, however, some of the centroids are located outside of the polygon features (circled in red). Is there a way to force the centroids to be calculated within the polygons? It appears as if the Feature To Point (Data Management) tool allows for this, although I am unable to use an an Advanced license for this.


enter image description here


import arcpy

input_fc = "C:\\temp\\geodatabase.gdb\\featureclass"
output_fc = "C:\\temp\\geodatabase.gdb\\featureclass_centroids"

cursor = arcpy.da.SearchCursor(input_fc, "SHAPE@XY")
centroid_coords = []
for feature in cursor:
    centroid_coords.append(feature[0])

point = arcpy.Point()
pointGeometryList = []

for pt in centroid_coords:
    point.X = pt[0]
    point.Y = pt[1]

    pointGeometry = arcpy.PointGeometry(point)
    pointGeometryList.append(pointGeometry)

arcpy.CopyFeatures_management(pointGeometryList, output_fc)
  • 2
    There is centroid inside option in add geometry attributes tool. – FelixIP Sep 27 at 22:02
7

You do not say whether you are using ArcPy with the ArcGIS Pro or ArcMap application of the ArcGIS Desktop product so I'll assume that it is ArcGIS Pro and reference that documentation.

In the PointGeometry help it says that the labelPoint property returns:

The point at which the label is located. The labelPoint is always located within or on a feature.

and that the centroid property returns:

The true centroid if it is within or on the feature; otherwise, the label point is returned.

Consequently, you should be either to use either. However, one caveat is that it appears you must set a spatial reference on your point geometries before centroid will use its otherwise condition. That caveat is mentioned at ArcPy centroid within polygon.

To see that ArcPy can use the centroid property to write a point inside a C shaped polygon try running the following code, most of which is only there to create test data:

import arcpy

# Create test data
fishnetFC = r"C:\temp\test.gdb\fishnetFC"
c7PolysFC = r"C:\temp\test.gdb\c7PolysFC"
c1PolyFC = r"C:\temp\test.gdb\c1PolyFC"
centroidInPolyFC = r"C:\temp\test.gdb\centroidInPolyFC"
sr = arcpy.SpatialReference("WGS 1984")
arcpy.management.CreateFishnet(fishnetFC, "0 0", "0 1", 1, 1, 3, 3,
                               None, "NO_LABELS", "DEFAULT", "POLYGON")
arcpy.management.DefineProjection(fishnetFC, sr)
arcpy.analysis.Select(fishnetFC,c7PolysFC, "OID NOT IN (5, 6)")
arcpy.management.Dissolve(c7PolysFC, c1PolyFC, None, None,
                          "SINGLE_PART", "DISSOLVE_LINES")

# Create feature class of points at centroid or
# another location guaranteed to be inside polygons
arcpy.management.CreateFeatureclass(r"C:\temp\test.gdb",
                                    "centroidInPolyFC","POINT")
cursor = arcpy.da.InsertCursor(centroidInPolyFC, "SHAPE@")  
for row in arcpy.da.SearchCursor(c1PolyFC, "SHAPE@"):
    cursor.insertRow([row[0].centroid])  
del row,cursor

The output looks like this:

enter image description here

| improve this answer | |

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.