1

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
asked Jan 30, 2017 at 1:03
4
  • 1
    You possibly need to check the data type before your if and elif as you've told it that datatype = ["DEFeatureClass", "DEShapefile", "DEFile"] but it doesn't know the actual type when it gets to your if Commented Jan 30, 2017 at 1:29
  • @Midvalo I don't believe that's the problem since the parameter doesn't have 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. Commented Jan 30, 2017 at 3:20
  • @Midavalo. I ran 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. Commented Jan 30, 2017 at 3:42
  • 1
    I suggest you edit your question to include that information and seek an answer for that Commented Jan 30, 2017 at 3:45

1 Answer 1

0

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":
answered Jan 30, 2017 at 4:57
1
  • 2
    if str(inputPolygon)[-4:] == ".kmz" or ".kml": will always return true. What that code is actually doing is checking if the first expression str(inputPolygon)[-4:] == ".kmz" is True then if that is False, it checks the expression after the or 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 do if str(inputPolygon)[-4:] in (".kmz", ".kml"): instead. Commented Jan 30, 2017 at 5:08

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.