ArcGIS API for Python >= 1.5.1: arcgis.geometry.Polygon.is_valid() method for polygons does not work

12-14-2018 06:15 AM
New Contributor III

we use ArcGIS API for Python in a project and encountered the following problem:

In ArcGIS API for Python 1.5.1 the boolean type property "is_valid" of geometries of type Polygon was removed and replaced by a method. This method is_valid() does not work like the boolean property in the previous versions. It throws an error for valid Polygon geometries as shown below:

In ArcGIS API for Python 1.5.0 the boolean type attribute worked well:

Do you have an idea how to work around this problem ?

Link to the github issue: API for Python 1.5.1 & 1.5.2: arcgis.geometry.Polygon.is_valid() method for polygons does not work ·... 

Best regards,
Lukas Bug
Student assistant at Esri Deutschland


I prepared two Jupyter Notebooks to be able to reproduce this issue. You will find them in the attached zip file.

Documentation mentions it in the GeoSeriesAccessor section and return type should be the boolean types True or False:

arcgis.features module — arcgis 1.5.2 documentation 

Rohit Singh

0 Kudos
2 Replies
MVP Legendary Contributor
import arcgis
v = int(arcgis.__version__.replace(".", ""))
if v < 152:
    do something
    do something else

Not ideal, but since a wrapper for compatibility wasn't provided, you do a version check in the interim, so you can move forward with your work

MVP Esteemed Contributor

When looking at the source code, this is clearly a defect.  I am surprised this passed unit testing before release, but maybe that shows gaps in Esri's unit testing.

It turns out there are 2 or 3 bad lines of code depending on what Esri's intent was with the structure of this code.  In order not to monkey with the core code, I took the approach of inserting a couple lines of code at the beginning of the file to address the bad code in the middle of the file.

If you insert the following two lines after the import statements in arcgis/geometry/ ,

list_types = (list, tuple)
number_type = (int, float, complex)

then the sample code works correctly:

>>> import arcgis
>>> gis = arcgis.gis.GIS()
>>> poly_item = gis.content.get("ea22ca8b61bb48b5a26dced27e332140")
>>> poly = poly_item.layers[0].query().features[0]
>>> print(poly.geometry)
{'rings': [[[-115271.33271643, 6782407.11514766], [124744.621382951, 6782407.11514766], [124744.621382951, 6642689.72542993], [-115271.33271643, 6642689.72542993], [-115271.33271643, 6782407.11514766]]]}
>>> polygon_geom = arcgis.geometry.Polygon(poly.geometry)
>>> polygon_geom.is_valid()