TransWikia.com

How to ensure centroid is calculated within polygon?

Geographic Information Systems Asked on April 26, 2021

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:tempgeodatabase.gdbfeatureclass"
output_fc = "C:tempgeodatabase.gdbfeatureclass_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)

One Answer

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:temptest.gdbfishnetFC"
c7PolysFC = r"C:temptest.gdbc7PolysFC"
c1PolyFC = r"C:temptest.gdbc1PolyFC"
centroidInPolyFC = r"C:temptest.gdbcentroidInPolyFC"
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:temptest.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

Correct answer by PolyGeo on April 26, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP