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.
Solved! Go to Solution.
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)
At the end of a very long thread, this may be a workaround:
Interesting! I’m away from my workstation but will give it a try tomorrow and report back.
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)
This worked, thanks!