Run script with ArcGIS Pro (arcpy) installation and without --> different results syntax

901
5
Jump to solution
02-18-2018 12:01 AM
GISMountains
New Contributor III

If a script runs in an environment with ArcGIS Pro (arcpy) or in environment without the results are different. The "extent" result is ones an array and the other one is a string with all values:

Example:

import arcgis
from arcgis.gis import GIS
from arcgis.geometry import Polygon
gis = GIS()
webmap_search = gis.content.search(query = 'title:"World Regions" AND owner:esri', item_type = 'Feature Layer Collection')
layer_region = webmap_search[0].layers[0]
query_result = layer_region.query(where="REGION='Western Europe'")
selected_region = query_result.features[0]
from arcgis.geometry import Polygon
polygon = Polygon({
  "rings" : selected_region.geometry['rings'],
  "spatialReference" : {"wkid" : 3857}
})
extent = polygon.extent
print(extent)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Result WITHOUT arcpy:
(-533252.171281941, 5066318.40606212, 1910953.15492337, 7372844.99872111)

Result WITH arcpy (ArcGIS Pro):
-533252.171281941 5066318.40606212 1910953.15492337 7372844.99872111 NaN NaN NaN NaN

This behavior is difficult if you would like to use the same script in different environment.
0 Kudos
1 Solution

Accepted Solutions
JoshuaBixby
MVP Esteemed Contributor

Regarding your "PS," dare to dream, and I mean that in all seriousness.  Esri doesn't even host the code for the API on GitHub, it is just a glorified check box, "we're on GitHub, check."  The GitHub page isn't even accurate, in terms of its terminology, i.e., the API is "ArcGIS API for Python" and not "ArcGIS Python API."

At a minimum, I think this is a documentation defect.  The documentation simply states:

extent

The extent of the geometry.

Sufficiently vague, it doesn't say an extent object is being returned, but it also doesn't say a tuple of values is being returned.

Beyond the documentation being incomplete, I do think there is a larger code issue.  If someone wants an ArcPy Extent object, I think they should be explicit about it and use:

polygon.as_arcpy.extent‍

I think the Geometry objects—Common Data Types | ArcGIS for Developers  documentation addresses this better:

Envelope

An envelope is a rectangle defined by a range of values for each coordinate and attribute. It also has a spatialReference field. The fields for the z and m ranges are optional. An empty envelope has no location in space and is defined by the presence of an xmin field, a null value, or a "NaN" string.

Overall, I agree with you, whether the ArcGIS API for Python team does remains to be seen.

View solution in original post

5 Replies
DanPatterson_Retired
MVP Emeritus

There is a branching in the ArcGIS environment based on whether arcmap or pro is installed.  You would have to examine the actual code to find what is returned in those situations.  I think the arcmap/ArcGIS pro environment returns an arcpy Polygon object

This is the type of code line you are looking for in the module you are interested in (an example from one function

....
def __geo_interface__(self):
    """returns the object as an Feature Collection JSON string"""
    if HASARCPY
:....‍‍‍
GISMountains
New Contributor III

Yes this I found too:

@property
    def extent(self):
        """
        The extent of the geometry.
        """
        ptX = []
        ptY = []
        if HASARCPY:
            return getattr(self.as_arcpy, "extent", None)
        elif isinstance(self, Polygon):
            for pts in self['rings']:
                for part in pts:
                    ptX.append(part[0])
                    ptY.append(part[1])
            return min(ptX), min(ptY), max(ptX), max(ptY)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

But you agree that if you write a function the answer should always syntacticly be the same?  Or what I am missing?

Otherwise we need to program outside a checker and interpreter of the results: if arcpy is installed interpret the results different.

0 Kudos
DanPatterson_Retired
MVP Emeritus

I would simply check the returned object to see whether it was a list/tuple or 4 individual values, from there you can determine what to do.

If a tuple is returned you can use

if isinstance(someobject, (list, tuple)):

    .... then parse the contents

I have no expectation that esri completely replicate what can and can't be done within all environments.

The HASARCPY I would expect an 'extent' object to be returned, since that is what I expect.

If there is no arcpy, then it is totally reasonable that 4 values be returned... they could have returned a tuple/list, but I can exploit the fact

that they didn't to differentiate between the two environments.

If you are working with your own code base, then you should incorporate your own HASARCPY checks, which you can see in the code base

is simple to do.

GISMountains
New Contributor III

Thanks for your reply.

Yes it is possible to do this in the script who use the "ArcGIS API for Python". But it was some kind of frustrating to use this great library to create some geometry-stuff and it worked in an environment and in the other environment it does not work, after some time debugging you can find the answer..... But not in the documentation, or?

On the other hand it would really helpful if the answer is syntactically  the same.

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Regarding your "PS," dare to dream, and I mean that in all seriousness.  Esri doesn't even host the code for the API on GitHub, it is just a glorified check box, "we're on GitHub, check."  The GitHub page isn't even accurate, in terms of its terminology, i.e., the API is "ArcGIS API for Python" and not "ArcGIS Python API."

At a minimum, I think this is a documentation defect.  The documentation simply states:

extent

The extent of the geometry.

Sufficiently vague, it doesn't say an extent object is being returned, but it also doesn't say a tuple of values is being returned.

Beyond the documentation being incomplete, I do think there is a larger code issue.  If someone wants an ArcPy Extent object, I think they should be explicit about it and use:

polygon.as_arcpy.extent‍

I think the Geometry objects—Common Data Types | ArcGIS for Developers  documentation addresses this better:

Envelope

An envelope is a rectangle defined by a range of values for each coordinate and attribute. It also has a spatialReference field. The fields for the z and m ranges are optional. An empty envelope has no location in space and is defined by the presence of an xmin field, a null value, or a "NaN" string.

Overall, I agree with you, whether the ArcGIS API for Python team does remains to be seen.