Arcpy ArcGIS Pro Syntax to Determine if a Layer is Visible in the Table of Contents

1049
6
Jump to solution
05-30-2023 11:59 AM
Gene_Sipes
New Contributor III

I am trying to write a standalone script for ArcGIS Pro, so that it checks if a layer is visible in the table of contents before running any geo processing functions. I have tried using the following, but it ends up just printing all of the layers in the TOC even if they are turned off, and I get an error stating: 

"AttributeError: The attribute 'visible' is not supported on this instance of Layer."

I have tried running it in the Python Window within ArcPro as well, with same result. 

# Import ArcPy site-package
import arcpy


# the open records request Pro Project
aprx = arcpy.mp.ArcGISProject(
    r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.aprx")

# list of layers in the project
myMap = aprx.listMaps()[0]


for layer in myMap.listLayers():
    if layer.supports("VISIBLE") == True:
       if layer.visible == True:
           print(layer.name)


print('I am done listing layers')

 

0 Kudos
1 Solution

Accepted Solutions
Gene_Sipes
New Contributor III

Alright, got it to work! Edge (ChatGPT) is awesome. Here is my final code, just because. I also realize there is a tool called Extract Data that can accomplish the same thing, but this was more of a python challenge for me than anything. Cheers. 

# Import ArcPy site-package and os modules
import arcpy
import os


# the open records request Pro Project
aprx = arcpy.mp.ArcGISProject(
    r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.aprx")

# list of layers in the project
myMap = aprx.listMaps()[0]

# Set the clip featureclass
clipFeatures = r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.gdb\SelectionPoly"

# Set the directory path where the clipped shapefiles will be stored
path = r"C:\Users\sipes_gene\Documents\OpenRecords"

# script will ask user to enter new folder name, folder will be place in path
outFolder = input('Enter your folder name :')

# join the path to the new folder name
outWorkspace = os.path.join(path, outFolder)

# Set the XY tolerance of the clip function
clusterTolerance = .000378

# create the directory
os.mkdir(outWorkspace)


for layer in myMap.listLayers():
    try:
        # check if layer is visible in TOC, if true evaluate against selection polygon
        if layer.visible:
            print('Layer {} is visible.'.format(layer))
            # validate feature class names
            featureClassName = arcpy.ValidateTableName(layer, outWorkspace)
            outFeatureClass = os.path.join(outWorkspace, featureClassName)
            # create a feature layer from layer on disk
            featureLayer = arcpy.MakeFeatureLayer_management(
                layer, "{}_fl".format(layer))
            # evaluate feature layer against selecting polygon
            selectedFeatureLayer = arcpy.SelectLayerByLocation_management(
                featureLayer, "intersect", clipFeatures)
            # get count of selected features for print statement
            count = int(arcpy.GetCount_management(selectedFeatureLayer)[0])
            if count == 0:
                print("%s features do not exist within AOI" % layer)
            else:
                # Clip each feature class in the list with the clip feature class.
                # looks for clip feature so as not to clip it.
                if selectedFeatureLayer != os.path.basename(clipFeatures):
                    arcpy.Clip_analysis(
                        selectedFeatureLayer, clipFeatures, outFeatureClass, clusterTolerance)
                    print("{} {} features clipped to AOI".format(count, layer))
                    print("All is well in the Universe, good bye")

    except Exception as e:
        print(f"An error occurred: {e}")

print('I am done clipping layers to AOI')

View solution in original post

0 Kudos
6 Replies
DavidPike
MVP Frequent Contributor

.supports is a bit flakey I think.

 

 

# Import ArcPy site-package
import arcpy


# the open records request Pro Project
aprx = arcpy.mp.ArcGISProject(
    r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.aprx")

# list of layers in the project
myMap = aprx.listMaps()[0]

for layer in myMap.listLayers():
    try:
       if layer.visible:
           print(layer.name)

    except:
        pass


print('I am done listing layers')

 

Gene_Sipes
New Contributor III

Thanks... well that kind of worked. It at least only prints out the name of the layers that are visible, but I still get a nasty little error.

 

Traceback (most recent call last):
File "c:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 90, in _get
return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "\\san_marcos\files\DeptShares\Public Services\Transportation\GIS\Scripts\Python\OpenRecordsRequestReWrite.py", line 15, in <module>
if layer.visible:
File "c:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 93, in _get
raise AttributeError(
AttributeError: The attribute 'visible' is not supported on this instance of Layer.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "c:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 90, in _get
return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "\\san_marcos\files\DeptShares\Public Services\Transportation\GIS\Scripts\Python\OpenRecordsRequestReWrite.py", line 18, in <module>
print("error - " + layer.name)
File "c:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 93, in _get
raise AttributeError(
AttributeError: The attribute 'name' is not supported on this instance of Layer.

0 Kudos
DavidPike
MVP Frequent Contributor

ah ok, I'll just pass it.  A bit hacky but if it's not production code and it works..  Have edited the previous code above.

0 Kudos
Gene_Sipes
New Contributor III

I really can't understand why my second print statement never runs. I am slowly building out my code to step along the way. Here I create a feature layer and select records from it that intersect my selecting polygon, but the last print statement: print('just finished selecting features within clip feature'), never runs. Here is the output from the code below:

about to evaluate if layer.visible is true
about to evaluate if layer.visible is true
about to evaluate if layer.visible is true
Layer Centerline is visible.
about to evaluate if layer.visible is true
about to evaluate if layer.visible is true
about to evaluate if layer.visible is true
about to evaluate if layer.visible is true
I am done clipping layers to AOI

 

import arcpy
import os


# the open records request Pro Project
aprx = arcpy.mp.ArcGISProject(
    r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.aprx")

# list of layers in the project
myMap = aprx.listMaps()[0]

# Set the clip featureclass
clipFeatures = r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.gdb\SelectionPoly"

# Set the directory path where the clipped shapefiles will be stored
path = r"C:\Users\sipes_gene\Documents\OpenRecords"

# script will ask user to enter new folder name, folder will be place in path
outFolder = input('Enter your folder name :')

# join the path to the new folder name
outWorkspace = os.path.join(path, outFolder)

# Set the XY tolerance of the clip function
clusterTolerance = .000378

# create the directory
os.mkdir(outWorkspace)


for layer in myMap.listLayers():
    try:
        print('about to evaluate if layer.visible is true')
        if layer.visible:
            print('Layer {} is visible.'.format(layer))
            featureClassName = arcpy.ValidateTableName(layer, outWorkspace)
            outFeatureClass = os.path.join(outWorkspace, featureClassName)
            arcpy.MakeFeatureLayer_management(layer, layer)
            arcpy.SelectLayerByLocation_management(
                layer, "within", clipFeatures)
            print('just finished selecting features within clip feature')

    except:
        pass

print('I am done clipping layers to AOI')
0 Kudos
Gene_Sipes
New Contributor III

Ok, made some progress, using {layer} as both the input and output of MakeFeatureLayer seems to be the problem. 

 

0 Kudos
Gene_Sipes
New Contributor III

Alright, got it to work! Edge (ChatGPT) is awesome. Here is my final code, just because. I also realize there is a tool called Extract Data that can accomplish the same thing, but this was more of a python challenge for me than anything. Cheers. 

# Import ArcPy site-package and os modules
import arcpy
import os


# the open records request Pro Project
aprx = arcpy.mp.ArcGISProject(
    r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.aprx")

# list of layers in the project
myMap = aprx.listMaps()[0]

# Set the clip featureclass
clipFeatures = r"\\san_marcos\arcfile\Department Projects and File Geodatabases\Public Services\Transportation\GSipes\ProProjects\OpenRecordsRequests\OpenRecordsRequests.gdb\SelectionPoly"

# Set the directory path where the clipped shapefiles will be stored
path = r"C:\Users\sipes_gene\Documents\OpenRecords"

# script will ask user to enter new folder name, folder will be place in path
outFolder = input('Enter your folder name :')

# join the path to the new folder name
outWorkspace = os.path.join(path, outFolder)

# Set the XY tolerance of the clip function
clusterTolerance = .000378

# create the directory
os.mkdir(outWorkspace)


for layer in myMap.listLayers():
    try:
        # check if layer is visible in TOC, if true evaluate against selection polygon
        if layer.visible:
            print('Layer {} is visible.'.format(layer))
            # validate feature class names
            featureClassName = arcpy.ValidateTableName(layer, outWorkspace)
            outFeatureClass = os.path.join(outWorkspace, featureClassName)
            # create a feature layer from layer on disk
            featureLayer = arcpy.MakeFeatureLayer_management(
                layer, "{}_fl".format(layer))
            # evaluate feature layer against selecting polygon
            selectedFeatureLayer = arcpy.SelectLayerByLocation_management(
                featureLayer, "intersect", clipFeatures)
            # get count of selected features for print statement
            count = int(arcpy.GetCount_management(selectedFeatureLayer)[0])
            if count == 0:
                print("%s features do not exist within AOI" % layer)
            else:
                # Clip each feature class in the list with the clip feature class.
                # looks for clip feature so as not to clip it.
                if selectedFeatureLayer != os.path.basename(clipFeatures):
                    arcpy.Clip_analysis(
                        selectedFeatureLayer, clipFeatures, outFeatureClass, clusterTolerance)
                    print("{} {} features clipped to AOI".format(count, layer))
                    print("All is well in the Universe, good bye")

    except Exception as e:
        print(f"An error occurred: {e}")

print('I am done clipping layers to AOI')
0 Kudos