Dealing with Group Layers in Python scripts

2331
6
07-04-2011 09:04 PM
yonatanrubinstein
New Contributor III
Hello,

I'm working on ArcGIS 9.3.1 and I run a python script which basically does a "select by location" query to several SDE layers which appear on the ArcMAP TOC (using a polygon shapefile the user points to) and copies the selected features to a new shapefile.

THE PROBLEM IS that some layers are within a group layer, and then the script gives a error stating :

<class 'arcgisscripting.ExecuteError'>: Failed to execute. Parameters are not valid.
ERROR 000840: The value is not a Feature Layer.
Failed to execute (SelectLayerByLocation)

now I understand that group layer is not a feature Layer and that SelectLayerByLocation only accepts feature Layers, that's where my question fits in:

Question: How can I reach a feature layer inside a Group layer using python code? or better yet, how can I tell what kind of layer I'm dealing with (Feature\group layer) using python code(describe method doesn't work on group)?  I'm running the script from a tool I built in ArcToolBox.

(this is a repost of a message I posted here, on geoprocessing forum, as I didn't find an answer and was hoping I'd find one here. thanks)

Thanks in Advance.
Tags (2)
0 Kudos
6 Replies
ChrisFox3
Occasional Contributor III
Hello,

I reviewed the other thread and Dale provided the proper method to pass a layer inside a Group Layer to a geoprocessing tool through python. Could you share more of your code? Do you pass the layer in as a parameter to the Script Tool or is hardcoded in the script?

In regards to your other point, unfortunately at 9.3 there is not an effective way to determine if a layer is a group layer or not. At ArcGIS 10 with the addition of the mapping module this functionality was added with the Layer Class and the isGroupLayer property. You can learn more about this  here:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/Layer/00s300000008000000/
0 Kudos
KimOllivier
Occasional Contributor III
Have you made sure that you are passing the full path of the layer?
Dragging a layer interactively looks like just the group/layer string in the dialog, but behind the scenes, and passed as a parameter is the full path.

A few judicious print statements will show that you need a full path, especially if you are not running in interactive mode and have not set the current workspace.
0 Kudos
yonatanrubinstein
New Contributor III
Chris, Kim,

Enclosed is the script I've written (with a few minor rewrites of names). It works well, except for the Group Layer (in this example ","county features//parks") - it doesn't recognize the feature layer inside the group ("Parks"). I've tried to write the path every way Dale suggested ( // , \\ , \, /, ///) and still, it doesn't work.

Thank you in advance

(oh, and you're welcome to point out anything you think I can improve, as I am quite a NEWBIE)

# -----------------------------------------------------------------------------------------------------------
#
#  This script does a "select by location" query on layers in the TOC and exports the results as shapefiles.
#
#  Note: when building a tool for this script, this tool requires a shapefile input
#
# -----------------------------------------------------------------------------------------------------------

# Import system modules
import sys, string, os, arcgisscripting
from os.path import basename, splitext

# Create the Geoprocessor object
gp = arcgisscripting.create(9.3)

# Load required toolboxes...
gp.AddToolbox("E:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")
gp.AddToolbox("E:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Data Management Tools.tbx")

multinputs = sys.argv[1]
inputlist = multinputs.split(";")
units = ["unit_388", "unit_434"]

# Local variables...
unitnames = [ splitext(basename(i))[0] for i in inputlist ]
cop_dictionary = {"local housing":"house","local streets":"streets","county features//parks":"cparks"}
#The cop_dictionary variable houses the layer's names: the first name as the one appearing in TOC, second name as name of output shp
#notice the third one is a parks layer in a group layer (county features)
part_path = "X:\\Exported_shps\\" 

f = open( part_path + "logfile.txt ", 'a')
f.write(" The script is: " + str(sys.argv[0]))
for iter in cop_dictionary:
    for curr in unitnames:
        fc_output_subdir = part_path + str(curr) + "\\"
        try:
           os.makedirs(fc_output_subdir)
        except OSError:
            pass
        exportkav = fc_output_subdir + cop_dictionary[iter] 
        imp = iter
        inter = iter
        using = "X:\\units_poly_bank\\" + curr + ".shp"
        gp.AddMessage( cop_dictionary[iter] +" "+ curr)
        f.write( "   " + str(cop_dictionary[iter])+ " \n")
        f.write("   " + str(curr)+ " \n")

        desc = gp.Describe(imp)
        typest = str(desc.ShapeType)
        if "Point" in typest:
            gp.SelectLayerByLocation_management(imp, "WITHIN", using, "", "NEW_SELECTION")
            f.write("POINT LAYER DETECTED!! performing -WITHIN- select ONLY" + str(imp)+ " \n")
            gp.AddMessage("POINT LAYER DETECTED!! performing -WITHIN- select ONLY")
        else:
            gp.SelectLayerByLocation_management(imp, "WITHIN", using, "", "NEW_SELECTION")
            f.write("Finished -WITHIN- select"+ " \n")
            gp.AddMessage("Finished -WITHIN- select")
            gp.SelectLayerByLocation_management(imp, "CROSSED_BY_THE_OUTLINE_OF", using, "", "ADD_TO_SELECTION")
            f.write("Finished -CROSSED_BY_THE_OUTLINE- select"+ " \n")
            gp.AddMessage("Finished -CROSSED_BY_THE_OUTLINE- select")
        # Process: Select...
        gp.Select_analysis(inter, exportkav, "")
        gp.AddMessage(exportkav + " has been exported \n")
        f.write( str(cop_dictionary[iter]) + "_" + curr + " has been exported \n" )

# Use these commands when f i n i s h e d
f.write( "Total export has ended \n" )
f.flush()
f.close()  

del inputlist, using, exportkav, imp, inter



0 Kudos
ChrisFox3
Occasional Contributor III
Thanks for passing along the code. Initially, I don't see any logic errors that would cause this problem other than "//" a single slash forward or backward should work, but you indicated this was a problem as well.

A couple of things to try, can you run the select by location tool in arcmap when selecting the layer within the group as the input?

Write a simplified script with everything hardcoded that only does a select by location on the group layer. Then create a script tool with no paramaters and run it, does it work?
import arcgisscripting
gp = arcgisscripting.create(9.3)
gp.SelectLayerByLocation_management("county features/parks", "WITHIN", "AnotherLayer", "", "NEW_SELECTION") #Change "AnotherLayer" to a layer in the Map Document to use in the selection


In your original code you can also add gp.AddMessage statements to print variables that are being passed into the Select Layer by Location function call. Specifically it would be good to see what is actually being stored in the variable 'imp' when it is passed to Select Layer by Location.
0 Kudos
yonatanrubinstein
New Contributor III
Answers:

I ran the Select by location tool with choosing the feature class within the group feature. It worked fine, without any problem.

I wrote a simplified script with the variables hardcoded, exactly as you wrote. It didn't work -

When running the script on "county features/parks" I got the following error:

<class 'arcgisscripting.ExecuteError'>: Failed to execute. Parameters are not valid.
ERROR 000732: Input Feature Layer: Dataset county features/parks does not exist or is not supported
Failed to execute (SelectLayerByLocation).

When running the script on "parks" I got the following error:

<class 'arcgisscripting.ExecuteError'>: Failed to execute. Parameters are not valid.
ERROR 000840: The value is not a Feature Layer.
Failed to execute (SelectLayerByLocation).

When adding the GP.Addmessage (imp) it prints out the name of the dataset : "county features/parks".

The thing I've noticed but can't explain: I have about ten group layers and it turns out that the above errors happens with all of them but one (which gets selected without a problem), but there is nothing different about that one - it is identical in every parameter I can think of.

What do you say?
0 Kudos
ChrisFox3
Occasional Contributor III
What happens if you start a new map document, create a new group layer and add the parks feature class to it? Avoid just copying and pasting the layer, but rather recreate the layer.

Either way would it be possible for you to send your map document and the parks feature class to me?

I have tested with the same exact scenario at 9.3 with a group layer called county features and a sub layer called parks and it worked as expected, so I am interested in what might be different in your test scenario.
0 Kudos