I am creating a custom tool within a Python Toolbox framework using ArcGIS v10.4. The tool's behavior is dependent on the type of Input polygon chosen by the user (it can be shapefile, feature class, or a KML/KMZ file). I have attempted to create a conditional statement based on the datatype of the input polygon chosen by the user, yet my conditional statement isn't working. Pertinent code below:
if parameters[0].datatype == "File": #Convert KML to Shapefile
arcpy.KMLToLayer_conversion(parameters[0].valueAsText, outputLocation, "OARS_Scratch") # Specify name of .gdb to be "OARS_Scratch.gdb"
tempFC1 = outputLocation + os.path.sep + r"OARS_Scratch.gdb\Placemarks\Polygons" # "Placemarks" is the default feature database name created & "Polygons" is the default name after running KML conversion function
tempFC2 = arcpy.env.scratchGDB + os.path.sep + "tempFC2"
sr = arcpy.SpatialReference("NAD 1983 UTM Zone 13N") # Create spatial reference object
arcpy.Project_management(tempFC1, tempFC2, sr, "WGS_1984_(ITRF00)_To_NAD_1983") # Project the new shapefile from WGS84 to NAD83 UTM Zone 13N & use the specified geographic transformation
arcpy.FeatureClassToShapefile_conversion(tempFC2, outputLocation) # convert feature class to shapefile
inputPolygon = outputLocation + os.path.sep + "tempFC2.shp"
newfc = outputLocation + os.path.sep + str(userCustomNameEsri) + ".shp"
arcpy.Append_management(inputPolygon, newfc, "NO_TEST") # Append shapefile from step above to template
arcpy.Delete_management(outputLocation + os.path.sep + "OARS_Scratch.lyr") # Cleanup: delete both geodatabases, layer file, and temporary shapefile.
arcpy.Delete_management(outputLocation + os.path.sep + "OARS_Scratch.gdb")
arcpy.Delete_management(outputLocation + os.path.sep + "scratch.gdb")
arcpy.Delete_management(outputLocation + os.path.sep + "tempFC2.shp")
elif parameters[0].datatype == "Feature Class" or "Shapefile":
inputPolygon = parameters[0].value
newfc = outputLocation + os.path.sep + str(userCustomNameEsri) + ".shp"
arcpy.Append_management(inputPolygon, newfc, "NO_TEST")
When I try running the tool and choose a KMZ file, I get the following error:
Traceback (most recent call last):
File "<string>", line 431, in execute
File "c:\program files (x86)\arcgis\desktop10.4\arcpy\arcpy\management.py", line 3898, in Append
raise e
ExecuteError: Failed to execute. Parameters are not valid.
ERROR 000349: The input parameter is not a Table View
Failed to execute (Append).
Line 431 in my python toolbox script (.pyt) is the 3rd line after the "elif" statement shown above, which is what I want the tool to run if the input polygon is a shapefile/feature class (I don't want to run this for a KMZ file).
How do I fix my conditional statement? I must be accessing the object's properties incorrectly, but after trying attempting alternative approaches unsuccessfully (below), I'm at a loss.
if parameters[0].datatype == "DEFile":
...
elif parameters[0].datatype == "DEFeatureClass" or "DEShapefile":
...
OR
inputPolygon = parameters[0].value
if str(inputPolygon)[-4:] == ".KMZ" or "KML":
...
else:
...
This is how the parameter is defined earlier in my code:
def getParameterInfo(self):
"""Define parameter definitions"""
param0 = arcpy.Parameter(
displayName = "Input Polygon",
name = "Input Polygon",
datatype = ["DEFeatureClass", "DEShapefile", "DEFile"], # "DEFile" allows KML/KMZ files
parameterType = "Required",
direction = "Input")
params = [param0]
return params
Edited, new below - Additional troubleshooting info:
arcpy.AddMessage("The datatype of parameter[0].datatype is {0}".format(parameters[0].datatype)) # [u'Feature Class', u'Shapefile', u'File']
When a shapefile is input:
arcpy.AddMessage("The name of the file is {0}".format(parameters[0].value)) # C:\Documents\ArcGIS\New_Shapefile.shp
inputPolygon = parameters[0].value
arcpy.AddMessage("The name of inputPolygon is {0}".format(parameters[0].value)) # C:\Documents\ArcGIS\New_Shapefile.shp
arcpy.AddMessage("The datatype of inputPolygon is {0}".format(type(inputPolygon))) # <type 'str'>
arcpy.AddMessage("The last 4 characters of inputPolygon are {0}".format(str(inputPolygon)[-4:])) # .shp
When a KMZ file is input:
arcpy.AddMessage("The name of the file is {0}".format(parameters[0].value)) # C:\Documents\ArcGIS\version1.kmz
inputPolygon = parameters[0].value
arcpy.AddMessage("The name of inputPolygon is {0}".format(parameters[0].value)) # C:\Documents\ArcGIS\version1.kmz
arcpy.AddMessage("The datatype of inputPolygon is {0}".format(type(inputPolygon))) # <type 'str'>
arcpy.AddMessage("The last 4 characters of inputPolygon are {0}".format(str(inputPolygon)[-4:])) # .kmz
1 Answer 1
This code fixes the conditional statement & the code will correctly accept shapefiles / feature classes or KML/KMZ files.
if str(inputPolygon)[-4:] == ".kmz" or str(inputPolygon)[-4:] == "kml":
...
elif str(inputPolygon)[-4:] == ".shp":
...
else:
...
An alternative approach of the 1st line suggested by Luke in the comments below that also works is
if str(inputPolygon)[-4:] in (".kmz", ".kml"):
...
These code snippets are VERY similiar to one of the alternate approaches I had tried, which failed.
if str(inputPolygon)[-4:] == ".kmz" or ".kml":
-
2
if str(inputPolygon)[-4:] == ".kmz" or ".kml":
will always return true. What that code is actually doing is checking if the first expressionstr(inputPolygon)[-4:] == ".kmz"
isTrue
then if that isFalse
, it checks the expression after theor
as a standalone expression. See boolean operations. A string with any value (i.e ".kml") will evaluate to True and an empty string will evaluate to False. You could doif str(inputPolygon)[-4:] in (".kmz", ".kml"):
instead.user2856– user28562017年01月30日 05:08:59 +00:00Commented Jan 30, 2017 at 5:08
Explore related questions
See similar questions with these tags.
if
andelif
as you've told it thatdatatype = ["DEFeatureClass", "DEShapefile", "DEFile"]
but it doesn't know the actual type when it gets to yourif
multiValue = True
. The user will pick just one input polygon that could be one of those 3 datatypes, so the datatype would be decided based on the choice, or that's my assumption --- maybe I'm wrong. Please clarify if I'm misunderstanding your suggestion.arcpy.AddMessage("Datatype of the user input is {0}".format(parameters[0].datatype))
& you were right in that it returned[u'Feature Class', u'Shapefile', u'File']
. Now just need to figure out how to properly use this information to inform the conditional statement.