Why is the creation of the arcpy.Polygon object failing for this point array?

3516
12
Jump to solution
01-27-2016 05:41 AM
BKuiper
Occasional Contributor III

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)

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
NeilAyres
MVP Alum

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)

...

View solution in original post

12 Replies
JenniferMcCall4
Occasional Contributor III

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]]

0 Kudos
BKuiper
Occasional Contributor III

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.

0 Kudos
DanPatterson_Retired
MVP Emeritus

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, #, #)>

0 Kudos
BKuiper
Occasional Contributor III

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]]

0 Kudos
DanPatterson_Retired
MVP Emeritus

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.

BKuiper
Occasional Contributor III

Good point! Thanks! I adjusted it in my code, but doesn't matter in regards to the 'bug' I mentioned.

0 Kudos
NeilAyres
MVP Alum

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)

...

BKuiper
Occasional Contributor III

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?

0 Kudos
DanPatterson_Retired
MVP Emeritus

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.

Errors in arcpy's Polygon class