What returns geometry.getCentroid()?

4816
11
04-09-2019 07:32 AM
HoriaTudosie
Occasional Contributor II

I have this pice of code:

parcels.forEach(parcel => {
const centroid = parcel.geometry.getCentroid(); //getExtent().getCenter(); //getCentroid();
const feature = new Graphic(centroid, myUtils.NEW_ADDRESS_SYMBOL);
this.map.graphics.add(feature);

and I'm getting this result:

The centroids are not in center of parcels, and some are outside their parcels.

There is no point in publishing all code (I can do that on request), but changing this line:

const centroid = parcel.geometry.getExtent().getCenter(); //getCentroid();

for ilustrating the center of the extent of the parcel instead of the centroid give better results:

Note that this is not a good solution:

I have added the extent for the last two parcels to show that the centre of the extent is not the desired solution, but this is a lot better solution that the getCentroid function the way I got it.

0 Kudos
11 Replies
DanPatterson_Retired
MVP Emeritus

My limited confirmation between arcpy and numpy calculations of centroid and area for multiple part/ring features suggest that the 'shoelace' (aka area weighted) method is used for area.  This is also used in the ArcGIS module.  The centroids do differ and don't seem to follow an area weighted method.  In python/numpy, the location of the rings relative to the outer ring seems to have no bearing, nor does the convexity/concavity of the shape.  It would be conjecture at this point to specify what actual approach is used to determine what is meant by 'centroid' in arc* parlance for moderately complex shapes.  Perhaps someone from the originating arcobjects definition team would weigh in.

shapes can be seen here

/blogs/dan_patterson/2019/04/17/geometry-reconstructing-poly-features-4 

# ---- polygons in a featureclass, with multiple parts and holes

SR = getSR(in_fc0)
shapes = fc_shapes(in_fc0)

[(p.centroid, p.area) for p in shapes]

[(<Point (300005.0, 5000005.0, #, #)>, 100.0),
 (<Point (300005.0, 5000011.0, #, #)>, 78.0),
 (<Point (300019.70967741933, 5000009.941935484, #, #)>, 155.0),
 (<Point (300015.0, 5000011.0, #, #)>, 52.0),
 (<Point (300022.5, 5000006.2084, #, #)>, 36.0)]

# ---- s0 is an numpy array representation of arcpy polygons
# compare
(s0.centroids(), s0.areas())

(array([[ 5.  ,  5.  ],
        [ 4.26, 13.77],
        [19.46,  9.82],
        [14.08, 15.  ],
        [25.  ,  5.3 ]]), array([100.,  78., 155.,  52.,  36.]))
DavidDoyle
New Contributor

I have experienced the same problem.

Someone on the forum told me that if i If I reverse the order of the vertices.  So make them counter clockwise for the ones that dont work.

This worked for me.  For what ever reason reversing the order on those that dont work works.

For my purposes I get the centroid then check the centroid is within the polygon if its not i reverse the order of the vertices and it goes bang in the middle.

Weird.

0 Kudos