Getting activeMap extent coordinates after setting activeMap.spatialReference

909
4
Jump to solution
03-22-2022 03:03 PM
EricEagle
Occasional Contributor III

In ArcGIS Pro (2.9), I'm doing some processing work based on a mask I derive from the active map view.

The processor expects UTM-projected data.  However, it might be that the user has not projected their map project to UTM, so I am trying to catch and handle that in the flow.  Right now my code looks like this:

d = arcpy.Describe(raster_in)
r_in_sr = d.spatialReference

# Make sure data is not unprojected or in common GCS
if r_in_sr.factoryCode in [4326, 3857, None]:
    raise ProjectionException("Input data not projected. Please ensure all inputs are projected and retry.")

# Make sure the active map is set to same spatial reference as input layer
p = arcpy.mp.ArcGISProject("CURRENT")
m = p.activeMap
m.spatialReference = r_in_sr  # successfully switches active map coord system!

# Now get the view extent
view_extent = p.activeView.camera.getExtent()
arcpy.AddMessage(view_extent)  # Yields GCS Lat/Lons, not UTM!

extent_poly = arcpy.Polygon(
    arcpy.Array(
        [
            view_extent.lowerLeft,
            view_extent.lowerRight,
            view_extent.upperRight,
            view_extent.upperLeft,
            view_extent.lowerLeft
        ]
    ), spatial_reference=r_in_sr
).projectAs(r_in_sr)  # neither of these sr's do anything, I still get GCS lat/lons

mask = arcpy.CopyFeatures_management(extent_poly, os.path.join(scratch, "mask"))  # scratch is arcpy.env.scratchGDB

 

The interesting thing here is that if I START the process with a UTM-projected active map, the whole thing works fine.  I get extent coordinates in UTM.

If I start the process with a common GCS, the script does set the active map to a UTM coordinate system.  But nothing I do seems to coerce the Polygon object to UTM: it still reports GCS Lat/Lon coordinates.  Therefore when I call 'mask' on UTM-projected input layers, it throws an error and tells me the extent is wrong.

The amusing thing is, that if I simply re-run it after that, the script starts out with the active map in the UTM projection set from the previous attempt, and runs fine.

This feels like a bug, but I could definitely be doing something wrong, so I thought I'd check with the experts before I file it with our customer rep.

1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

Do it the other way around: instead of setting the map coordinate system, project the extent.

d = arcpy.Describe(raster_in)
r_in_sr = d.spatialReference

# Make sure data is not unprojected or in common GCS
if r_in_sr.factoryCode in [4326, 3857, None]:
    raise ProjectionException("Input data not projected. Please ensure all inputs are projected and retry.")

# Get the current view extent
p = arcpy.mp.ArcGISProject("CURRENT")
view_extent = p.activeView.camera.getExtent()
arcpy.AddMessage(view_extent.polygon.spatialReference.factoryCode)
arcpy.AddMessage(view_extent.polygon.firstPoint)

# project view_extent; note that you don't have to construct the polygon yourself!
extent_poly = view_extent.polygon.projectAs(r_in_sr)
arcpy.AddMessage(extent_poly.spatialReference.factoryCode)
arcpy.AddMessage(extent_poly.firstPoint)

 


Have a great day!
Johannes

View solution in original post

4 Replies
curtvprice
MVP Esteemed Contributor
0 Kudos
EricEagle
Occasional Contributor III

Interesting!  I’m away from my workstation but will give it a try tomorrow and report back.

0 Kudos
JohannesLindner
MVP Frequent Contributor

Do it the other way around: instead of setting the map coordinate system, project the extent.

d = arcpy.Describe(raster_in)
r_in_sr = d.spatialReference

# Make sure data is not unprojected or in common GCS
if r_in_sr.factoryCode in [4326, 3857, None]:
    raise ProjectionException("Input data not projected. Please ensure all inputs are projected and retry.")

# Get the current view extent
p = arcpy.mp.ArcGISProject("CURRENT")
view_extent = p.activeView.camera.getExtent()
arcpy.AddMessage(view_extent.polygon.spatialReference.factoryCode)
arcpy.AddMessage(view_extent.polygon.firstPoint)

# project view_extent; note that you don't have to construct the polygon yourself!
extent_poly = view_extent.polygon.projectAs(r_in_sr)
arcpy.AddMessage(extent_poly.spatialReference.factoryCode)
arcpy.AddMessage(extent_poly.firstPoint)

 


Have a great day!
Johannes
EricEagle
Occasional Contributor III

This worked, thanks!

0 Kudos