Trouble Accessing Layers with Python

3762
11
Jump to solution
04-13-2015 09:38 AM
RachaelJohnson
Occasional Contributor

In case you've been following my fairly boring saga: I am making progress on my program!  I have my files going where they need to go! Yay!

I am trying to remove intermediate and unnecessary layers from the map document.  I have a raster file, "SoilUnclass", that I want to remove from my map document to de-clutter my Table of Contents. I put the following code together based on what I've seen and read. I left my variable definitions out of the code but my inputs are all initialized with the proper file paths.

SoilUnclass = arcpy.PolygonToRaster_conversion(soil, "HSG", ScratchPath + r"\SoilUnclass",

   "MAXIMUM_COMBINED_AREA")

SoilClass = arcpy.sa.Reclassify(SoilUnclass, "HSG", arcpy.sa.RemapValue([["A", 1],

  ["B", 2],

  ["C", 3],

  ["D", 4],

  ["A/D", 14],

  ["B/D", 24],

  ["C/D", 34],

  ["---", 4]]), "NODATA")

SoilClass.save(WorkPath + r"\SoilClass")

SoilClass.save(GDBpath + r"\SoilClass")

df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

arcpy.mapping.RemoveLayer(df, SoilUnclass)

When I run that code, I receive the following error:

Runtime error

Traceback (most recent call last):

  File "<string>", line 2, in <module>

  File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\utils.py", line 182, in fn_

    return fn(*args, **kw)

  File "c:\program files (x86)\arcgis\desktop10.3\arcpy\arcpy\mapping.py", line 1845, in RemoveLayer

    assert isinstance(remove_layer, Layer)

AssertionError

...?? It may be worth noting that when I do arcpy.mapping.ListLayers(mxd), "SoilUnclass" is not a layer that shows up.  Only the files that were in the map document before I ran my code are listed.  I saved my document and did ListLayers() again but nothing changed.  How can I get access to these layers to modify them?

0 Kudos
1 Solution

Accepted Solutions
DarrenWiens2
MVP Honored Contributor

This may or may not help. I started with one polygon layer ('asdasd') and ran PolygonToRaster, saving to the in_memory workspace ('OutLocation'). The 'type' of the SoilUnclass object is a 'Result' not a 'Layer'. ListLayers() does return layer objects, including the newly created and added 'OutLocation' layer. You can remove the new layer by calling RemoveLayer referencing the layer object, not the result object. This leaves me with only my original layer, 'asdasd'. 'OutLocation' would still be saved on disk, though.

>>> mxd = arcpy.mapping.MapDocument('CURRENT')

... df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

... SoilUnclass = arcpy.PolygonToRaster_conversion('asdasd', "Id", r"in_memory\OutLocation", "MAXIMUM_COMBINED_AREA")

... print type(SoilUnclass)

... print arcpy.mapping.ListLayers(mxd)

... print type(arcpy.mapping.ListLayers(mxd)[1])

... arcpy.mapping.RemoveLayer(df, arcpy.mapping.ListLayers(mxd)[1])

... print arcpy.mapping.ListLayers(mxd)

...

<class 'arcpy.arcobjects.arcobjects.Result'>

[<map layer u'asdasd'>, <map layer u'OutLocation'>]

<class 'arcpy._mapping.Layer'>

[<map layer u'asdasd'>]

View solution in original post

11 Replies
DarrenWiens2
MVP Honored Contributor

I believe this is because SoilUnclass is a raster object (data), not a layer object in your mxd. Since you never added this data to your map, there is no need (or way) to remove it. To delete data on disk, use Delete.

0 Kudos
RachaelJohnson
Occasional Contributor

ListLayers() does bring up two raster datasets in addition to my shapefiles, so I am not sure that the problem is caused because SoilUnclass is a raster.  When I run the code in the ArcGIS python window, it adds SoilUnclass to the table of contents, so it's definitely in my map.  I don't necessarily want to delete the file, either, just get it out of my Table of Contents. 

0 Kudos
DarrenWiens2
MVP Honored Contributor

ListLayers() does not return raster datasets, it returns layers saved in your mxd that point to raster datasets. If you hit save in ArcMap (or, potentially, "mxd.save()", although I don't believe you've actually added SoilUnclass to the mxd saved on disk) once SoilUnclass has been added, you could then reference the layer that has been saved in the table of contents.

RachaelJohnson
Occasional Contributor

Ah, I see.  I closed and opened the MXD and now ListLayers is showing those layers. So even though the raster is showing up in the Table of Contents, it's not officially a layer until the map is saved and closed and reopened, apparently?  This poses a problem...

0 Kudos
RachaelJohnson
Occasional Contributor

If I save and redefine my mxd, then it works. Should that be necessary?

0 Kudos
DarrenWiens2
MVP Honored Contributor

This may or may not help. I started with one polygon layer ('asdasd') and ran PolygonToRaster, saving to the in_memory workspace ('OutLocation'). The 'type' of the SoilUnclass object is a 'Result' not a 'Layer'. ListLayers() does return layer objects, including the newly created and added 'OutLocation' layer. You can remove the new layer by calling RemoveLayer referencing the layer object, not the result object. This leaves me with only my original layer, 'asdasd'. 'OutLocation' would still be saved on disk, though.

>>> mxd = arcpy.mapping.MapDocument('CURRENT')

... df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

... SoilUnclass = arcpy.PolygonToRaster_conversion('asdasd', "Id", r"in_memory\OutLocation", "MAXIMUM_COMBINED_AREA")

... print type(SoilUnclass)

... print arcpy.mapping.ListLayers(mxd)

... print type(arcpy.mapping.ListLayers(mxd)[1])

... arcpy.mapping.RemoveLayer(df, arcpy.mapping.ListLayers(mxd)[1])

... print arcpy.mapping.ListLayers(mxd)

...

<class 'arcpy.arcobjects.arcobjects.Result'>

[<map layer u'asdasd'>, <map layer u'OutLocation'>]

<class 'arcpy._mapping.Layer'>

[<map layer u'asdasd'>]

View solution in original post

RachaelJohnson
Occasional Contributor

It helped because now I know about Results vs Layers!  Sure enough, my SoilUnclass is a Result data type. I am not sure how you managed to get it to add the OutLocation layer, however.  Is it because it is in the memory and it adds the layer automatically in that case? 

0 Kudos
DarrenWiens2
MVP Honored Contributor

No, saving to in_memory is not the issue - it also adds a layer saving to disk:

>>> arcpy.env.scratchWorkspace = r'C:/junk'

... mxd = arcpy.mapping.MapDocument('CURRENT')

... df = arcpy.mapping.ListDataFrames(mxd,"*")[0]

... SoilUnclass = arcpy.PolygonToRaster_conversion('asdasd', "Id", 'OutLocation', "MAXIMUM_COMBINED_AREA")

... print type(SoilUnclass)

... print arcpy.mapping.ListLayers(mxd)

... print type(arcpy.mapping.ListLayers(mxd)[1])

... arcpy.mapping.RemoveLayer(df, arcpy.mapping.ListLayers(mxd)[1])

... print arcpy.mapping.ListLayers(mxd)

...

<class 'arcpy.arcobjects.arcobjects.Result'>

[<map layer u'asdasd'>, <map layer u'OutLocation'>]

<class 'arcpy._mapping.Layer'>

[<map layer u'asdasd'>]

0 Kudos
RachaelJohnson
Occasional Contributor

Actually, now that I'm running things out of PyCharm instead of the GIS Python window, I see now how the results aren't being added and how it doesn't make layers for it.  It's much faster to run my program from PyCharm than from the GIS Python window, too!  So I see that removing the results/layers is eventually going to be superfluous.  I can add any layers to the map when my code is all complete, I assume. 

Thank you for taking the time to help me!  I learn so much every time I post on here.  I hope one day I know enough about Python to help with other people's problems!

0 Kudos