List layers from current view using Arcpy
A DataFrame
object has an extent
property, the extent
property/object can be used in the basic spatial relationship methods of contains
, within
, equals
, overlaps
, touches
and disjoint
as well as distanceTo
, see here for more details on those methods.
With that in mind you can loop over the layers you retrieve from calling arcpy.mapping.ListLayers(mxd,"", df)
and retrieve each layers extent by calling the getExtent
method on each layer. The spatial relationships discussed above can be tested between the extent.polygon
object of each layer and the dataframe to determine if they are indeed within the extent of the dataframe. If you are using data driven pages the extent of each page can be retrieved with an mxd
object with this call mxd.dataDrivePages.dataFrame.extent
.
It is important to note that the extent of a layer often has a larger footprint that than the actual vector within the layer (e.g. the polygon, points, raster, etc.), so depending on the spatial relationship you choose to test it may include more layers than are actually visible. Here is an example (thanks @KHibma) of how you would use a spatial relationship method of the DataFrame
with a Layer
object:
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for l in arcpy.mapping.ListLayers(df):
if not df.extent.disjoint(l.getExtent()):
print l.name
As a quick and dirty method, you could compare extents, as already answered. However (also mentioned), that doesn't necessarily indicate whether a feature is visible in the current view (e.g. if you zoom in far enough within a feature class' extent, at some point you will not see any features).
There's a definite performance hit if you need to find visible features. You can get at it using several methods, but in some way you need to perform an overlay operation at the feature level. You could use: Spatial Join (as below), Intersect, Select Layer By Location, or search cursor through all features checking 'overlaps' against the df.extent, among others.
mxd = arcpy.mapping.MapDocument("CURRENT") # map
df = arcpy.mapping.ListDataFrames(mxd)[0] # data frame
arcpy.env.addOutputsToMap = False # disable add outputs
for lyr in arcpy.mapping.ListLayers(df): # loop through layers
try:
sp = arcpy.SpatialJoin_analysis(df.extent.polygon,lyr,r'in_memory\sp',"JOIN_ONE_TO_ONE","KEEP_COMMON",'',"INTERSECT") # perform overlay
if int(arcpy.GetCount_management(sp).getOutput(0)) > 0: # check if overlay found any features
print '{}: visible'.format(lyr.name)
else: # no features found
print '{}: not visible'.format(lyr.name)
except:
print '{}: not a feature layer or some other problem'.format(lyr.name) # not feature layer, e.g. WMS