I'm new to writing Python toolboxes for ArcMap, but I have several other tools I've written in this toolbox that do work.
This standalone script works:
import arcpy
from arcpy.mapping import MapDocument
import arcview
input = r'Y:\Shared with Fusion\spatial_query.mxd'
md = MapDocument(input)
map = md.activeDataFrame
extent = map.extent
print('old:')
print(extent.spatialReference.name)
print(extent)
out_sr = arcpy.SpatialReference(4326)
new_extent = extent.projectAs(out_sr)
print('new:')
print(new_extent.spatialReference.name)
print(new_extent)
But similar logic in a Python toolbox tool fails. (Simplified from a larger tool for debugging.) Inputs using the same MXD as above are the map's current display extent and 4326.
class ProjectAsTest(object):
def __init__(self):
"""ProjectAsTest"""
self.label = "ProjectAsTest"
self.description = "Test projecting a query extent to an EPSG value"
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
param0 = arcpy.Parameter(displayName = "Query Extent",
name = "query_extent",
datatype = "GPExtent",
parameterType = "Required",
direction = "Input")
param1 = arcpy.Parameter(displayName = "Force Coordinate System (EPSG code)",
name = "force_epsg",
datatype = "GPLong",
parameterType = "Optional",
direction = "Input",
enabled = False)
params = [param0, param1]
return params
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Validate parameters."""
# Query Extent
if parameters[0].altered:
if parameters[0].value:
parameters[1].enabled = True
else:
parameters[1].value = None
parameters[1].enabled = False
return
def updateMessages(self, parameters):
"""Set validation messages"""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
query_extent = parameters[0].value
force_epsg = parameters[1].value
messages.AddMessage('Query extent is {0} {1} {2} {3}'.format(query_extent.XMin,
query_extent.YMin, query_extent.XMax, query_extent.YMax))
try:
epsg = query_extent.spatialReference.factoryCode
except:
messages.AddErrorMessage("An extent with a spatial reference must be specified.")
raise arcpy.ExecuteError
return
messages.AddMessage('Query extent EPSG is {0}'.format(epsg))
active_epsg = None
active_extent = None
if not force_epsg == None:
messages.AddMessage('Query extent will be projected.')
force_spatial_ref = None
try:
force_spatial_ref = arcpy.SpatialReference(force_epsg)
except:
messages.AddErrorMessage('{0}'.format(sys.exc_info()))
messages.AddErrorMessage('EPSG code {0} is not recognized.'.format(force_epsg))
raise arcpy.ExecuteError
return
try:
active_extent = query_extent
active_extent.projectAs(force_spatial_ref)
except:
messages.AddErrorMessage('{0}'.format(sys.exc_info()))
messages.AddErrorMessage('Cannot reproject extent to EPSG code {0}.'.format(force_epsg))
raise arcpy.ExecuteError
return
active_epsg = force_epsg
if not active_epsg:
active_epsg = epsg
active_extent = query_extent
messages.AddMessage('Active EPSG is {0}'.format(active_epsg))
messages.AddMessage('Active extent is {0} {1} {2} {3}'.format(active_extent.XMin,
active_extent.YMin, active_extent.XMax, active_extent.YMax))
return
# end class ProjectAsTest
The error output is:
(<type 'exceptions.RuntimeError'>, RuntimeError(u'Object: CreateObject error creating spatial reference',), <traceback object at 0x18ADECB0>)
Cannot reproject extent to EPSG code 4326.
Is there something different I have to do in the Python toolbox environment to use Extent.projetctAs? Is the extent I'm getting from the user dialog somehow different from the one from the MapDocument?