Hi,
I have developed two tests to demonstrate the problem
def test_centroidTestFails(self):
polygonpoints = [
[37.310437, -122.244706],
[37.320437, -122.244706],
[37.320437, -122.242706],
[37.310437, -122.242706]]
points = arcpy.Array([arcpy.Point(*coords) for coords in polygonpoints])
polygon = arcpy.Polygon(points)
with self.assertRaises(Exception) as context:
centroid = polygon.centroid
def test_centroidTestSucceeds(self):
polygonpoints = [
[37.310437, -122.244706],
[37.320437, -122.244706],
[37.320437, -122.241706],
[37.310437, -122.241706]]
points = arcpy.Array([arcpy.Point(*coords) for coords in polygonpoints])
polygon = arcpy.Polygon(points)
centroid = polygon.centroid
Why is the first test failing? For some reason the generated points array can't be used as input for the arcpy.Polygon() constructor. polygon.pointCount will return 0 for the test_centroidTestFails(). What is going wrong? Am i doing something wrong or is this a framework problem?
EDIT: Note that there is a small difference in the data points that are used for the two tests. The first test fails for no apparent reason and polygon.pointCount will return 0 on this test. The second test works successfully. For some reason the Array of points that is created is not accepted by the polygon constructor in the first test. Adding an additional point to close the polygon is not necessary and doesn't resolve the issue. The polygon will still return 0 points when using the data points from the first test.
EDIT 2: the minor difference is -122.242706 vs. -122.241706 for the last two data points. ( .242 vs .241)
Solved! Go to Solution.
And when you create the geometry, always specify the spatial reference for the points. This is a geographic coordinate system and those points (which are not very far apart) could be collapsing.
So....
sr = arcpy.SpatialReference(4326) # GCS_WGS84 ..... poly = arcpy.Polygon(array, sr)
...
Could it be that you need to repeat the first coordinate to close the polygon?
Ex;
def test_centroidTestFails(self):
polygonpoints = [
[37.310437, -122.244706],
[37.320437, -122.244706],
[37.320437, -122.242706],
[37.310437, -122.242706],
[37.310437, -122.244706]]
No, that doesn't matter. The second test runs successfully with a 4 points. I also tried running it with 5 points, with no luck.
import arcpy
poly_pnts = [[37.310437, -122.244706],
[37.320437, -122.244706],
[37.320437, -122.241706],
[37.310437, -122.241706]]points = arcpy.Array([arcpy.Point(*coords) for coords in poly_pnts])
poly = arcpy.Polygon(points)
CH = poly.convexHull()
centroid = poly.centroid
print("Points\n{!r:}\nConvex Hull\n{}\nCentroid\n{!r:}".format(points, CH, centroid))
Did you go simple first?
>>>
Points
<Array [<Point (37.310437, -122.244706, #, #)>, <Point (37.320437, -122.244706, #, #)>, <Point (37.320437, -122.241706, #, #)>, <Point (37.310437, -122.241706, #, #)>]>
Convex Hull
<geoprocessing describe geometry object object at 0x02628C20>
Centroid
<Point (37.3154907227, -122.24319458, #, #)>
Note the small difference in the points that are defined for the two tests. The first set fails. The second set succeeds successfully. You used the second set, which is known to work.
Try again with this set and you will see it fails:
[37.310437, -122.244706],
[37.320437, -122.244706],
[37.320437, -122.242706],
[37.310437, -122.242706]]
Ok... just a query, If these are longitudes and latitudes, then you have the columns mixed up -122 is X aka long. and the 37's are Y. So you need to check the point order which should go clockwise. So pick one of your points and sort them by X and y pairs so that they are in clockwise order.
Good point! Thanks! I adjusted it in my code, but doesn't matter in regards to the 'bug' I mentioned.
And when you create the geometry, always specify the spatial reference for the points. This is a geographic coordinate system and those points (which are not very far apart) could be collapsing.
So....
sr = arcpy.SpatialReference(4326) # GCS_WGS84 ..... poly = arcpy.Polygon(array, sr)
...
specifing the spatial reference seems to resolve the issue. Could you explain or reference me to an article that explains the collapsing of the polygon. I'm not sure what this means. Would the arcpy.Polygon() constructor assume a default spatial reference when none specified where these points are to closely to one another?
strangely, I thought I posted a link to you this morning but it appears I failed to click Post.
I created quite the kerfuffle some time ago... this is one of the links...I have more elsewhere.