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
  • 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 – Midavalo Jan 30 '17 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. – Edward Jan 30 '17 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. – Edward Jan 30 '17 at 3:42
  • I suggest you edit your question to include that information and seek an answer for that – Midavalo Jan 30 '17 at 3:45
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
    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. – user2856 Jan 30 '17 at 5:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.