SystemError: error return without exception set

4026
2
Jump to solution
10-28-2020 06:59 AM
JamesCrandall
MVP Frequent Contributor

This error "SystemError: error return without exception set" only recently popped up in an implementation and it only happens on some, not all, polygon features that are processed.  Error is throw on this line:

pcent = polygon.centroid

All this does is take the geometry attribute of some JSON (a polygon feature service) and gets the centroid.  I'm not sure what exactly is wrong with the geometry but seems to cause the error.

Attached .txt file contains the "inputJSON" variable (I thought it best to just add it in a file vs. paste in the post).

inputJSON = <grab from attached .txt file>
inSr = arcpy.SpatialReference(3857)
for i in inputJSON['geometry']['rings']:
	coordinates = i

	polygon = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in coordinates]), inSr)

	pcent = arcpy.Point
	pcent = polygon.centroid #error occurs here
	return pcent.X, pcent.Y‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Alum

The polygon is has 4 ring parts, and your code is requesting a centroid for each ring part.  The first ring part has 3 pairs of coordinates:

{
	"geometry": {
		"rings": [
			[
				[-9047616.7071, 3297677.1092999987],
				[-9047617.2766, 3297676.960099999],
				[-9047616.7071, 3297677.1092999987]
			],
			[
				[-9047712.4177, 3297707.5879999995],
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I'm not sure if the geometry is formed correctly, but I modified your code and ran the following in ArcMap's python window (10.5).  I then converted the rings into geojson and created a polygon feature to get the coordinates of its centroid.

>>> for i in inputJSON['geometry']['rings']:
...     coordinates = i
...     try:
...         polygon = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in coordinates]), inSr)
...         pcent = arcpy.Point
...         pcent = polygon.centroid #error occurs here
...         print(pcent.X, pcent.Y)
...     except:
...         print("bad ring")
...      
bad ring
(-9047688.632686786, 3297747.352303187)
(-9047607.857266191, 3297958.89263077)
(-9047509.45395274, 3297862.9346273225)
>>> 
>>> coordinates = inputJSON['geometry']['rings']
... geojson_polygon = {"type": "Polygon", "coordinates" : coordinates }
... polygon = arcpy.AsShape(geojson_polygon)
... 
... pcent = arcpy.Point
... pcent = polygon.centroid
... 
... print pcent.X, pcent.Y
... 
-9047510.96964 3297863.03471
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If the polygon has only one ring, you may get the correct centroid.  If it has multiple parts, you may be getting only the centroid of the first part.

View solution in original post

2 Replies
RandyBurton
MVP Alum

The polygon is has 4 ring parts, and your code is requesting a centroid for each ring part.  The first ring part has 3 pairs of coordinates:

{
	"geometry": {
		"rings": [
			[
				[-9047616.7071, 3297677.1092999987],
				[-9047617.2766, 3297676.960099999],
				[-9047616.7071, 3297677.1092999987]
			],
			[
				[-9047712.4177, 3297707.5879999995],
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I'm not sure if the geometry is formed correctly, but I modified your code and ran the following in ArcMap's python window (10.5).  I then converted the rings into geojson and created a polygon feature to get the coordinates of its centroid.

>>> for i in inputJSON['geometry']['rings']:
...     coordinates = i
...     try:
...         polygon = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in coordinates]), inSr)
...         pcent = arcpy.Point
...         pcent = polygon.centroid #error occurs here
...         print(pcent.X, pcent.Y)
...     except:
...         print("bad ring")
...      
bad ring
(-9047688.632686786, 3297747.352303187)
(-9047607.857266191, 3297958.89263077)
(-9047509.45395274, 3297862.9346273225)
>>> 
>>> coordinates = inputJSON['geometry']['rings']
... geojson_polygon = {"type": "Polygon", "coordinates" : coordinates }
... polygon = arcpy.AsShape(geojson_polygon)
... 
... pcent = arcpy.Point
... pcent = polygon.centroid
... 
... print pcent.X, pcent.Y
... 
-9047510.96964 3297863.03471
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If the polygon has only one ring, you may get the correct centroid.  If it has multiple parts, you may be getting only the centroid of the first part.

JamesCrandall
MVP Frequent Contributor

Thanks for taking a look Randy!

I think I will just have to test for > 1 ring and if true then maybe get the extent of all of them to use as the centroid.  

        ringCount = len(inputJSON['geometry']['rings'])
        if ringCount > 1:
            for i in inputJSON['geometry']['rings']:
                coordinates = i
                array = arcpy.Array([arcpy.Point(*coords) for coords in coordinates])

            boundary = arcpy.Polygon(array, inSr)
            pcent = arcpy.Point
            pcent = boundary.centroid
            return pcent.X, pcent.Y

        else:
            for i in inputJSON['geometry']['rings']:
                coordinates = i

                polygon = arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in coordinates]), inSr)

                pcent = arcpy.Point
                pcent = polygon.centroid
                return pcent.X, pcent.Y

I need to test what "boundary" exactly is if ringCount>1... I can't really tell, but it returns the pcent.X/Y

0 Kudos