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
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":
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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.