Select to view content in your preferred language

Layers in Current Visible Extent

3579
3
05-09-2014 07:50 AM
ColinStief1
Deactivated User
Greetings,

I'm looking to turn off all of the layers NOT in the current visible extent. I figured a Python Add-In would be the easiest way to achieve this functionality.  I've snooped around the arcpy classes and their methods, and I'm not seeing what I'm looking for (i.e. Layer.inVisibleExtent).

Does this mean I'll have to create an add-in with .Net/ArcObjects? I've seen the powerpoint that's floating around about accessing Arc Objects with Python, but don't necessarily want to go that route.

Thanks,

Colin
Tags (2)
3 Replies
MattEiben
Deactivated User
I actually just answered a similar question in this post.

Essentially my solution is to take the extent of the layer you want to test, convert it's extent box to a Polygon geometry object, and use the "overlaps" method of the Extent arcpy object to test if that geometry is in your dataframe extent (visible).

Code Example:

# Get your Feature Layer extent
layer = arcpy.mapping.Layer("Your Feature Layer")
extent = arcpy.Describe(layer).extent

# Create a Polygon object from that extent
extentArray = arcpy.Array(i for i in (extent.lowerLeft,
                                      extent.lowerRight,
                                      extent.upperRight,
                                      extent.upperLeft,
                                      extent.lowerLeft))

extentPolygon = arcpy.Polygon(extentArray, arcpy.SpatialReference(4326))
del extentArray


Now you have a Polygon Geometry object that represents the extent around the feature you want to test for visibility.
All that's left now is to use the "overlaps" method of the Extent object to see if your feature layer is visible in your dataframe.

# Get reference to your dataframe
mxd = arcpy.mapping.MapDocument("CURRENT") 
df = arcpy.mapping.ListDataFrames(mxd, "*")[0]

# Whenever appropriate, test if the layerframe overlaps the extent geometry of your feature layer
if df.extent.overlaps(extentPolygon) == False:
    layer.visible = False
    arcpy.RefreshActiveView()


Depending how you want to implement this, you may want to use List Layers to do this with all your layers.  You may also need some logic to detect whether your layers are already visible or not, but this should give you the general idea.

Hope it helps!
0 Kudos
ColinStief1
Deactivated User
eibenm,

Thanks for the help, your logic worked great. I beefed it up a little to make sure that anything within the visible extent stays visible.

One caution to anybody that grabs this: it breaks for polygons or polylines whose actual extent meets the criteria, but visible extent does not. In other words, if your polygon is present just off screen to the left, and also just off screen to the top, for instance, it will still be left visible. In my case, this code suits my needs because I'm only using square rasters whose visible extent is the same as their actual extent.

import arcpy

# Get reference to your dataframe
mxd = arcpy.mapping.MapDocument("CURRENT") 
df = arcpy.mapping.ListDataFrames(mxd, "*")[0]

# Loop through layers in first dataframe
for lyr in arcpy.mapping.ListLayers(mxd, "", df):
    extent = arcpy.Describe(lyr).extent
    extentArray = arcpy.Array(i for i in (extent.lowerLeft,
                                          extent.lowerRight,
                                          extent.upperRight,
                                          extent.upperLeft,
                                          extent.lowerLeft))
    extentPolygon = arcpy.Polygon(extentArray, arcpy.SpatialReference(4269))

    # Check if the layer can be seen at all... if not, turn it off
    if (df.extent.overlaps(extentPolygon) == True or
        df.extent.within(extentPolygon) == True or
        df.extent.contains(extentPolygon) == True):
        lyr.visible = True
    else:
        lyr.visible = False

    del extent
    del extentArray
    del extentPolygon

# Refresh the View        
arcpy.RefreshActiveView()


Colin
0 Kudos
MattEiben
Deactivated User
I'm glad that worked out for you Colin!  I did a little more research afterwards and found this method. 

Minimum Bounding Geometry

You should definitely look into using this with "CONVEX_HULL" as your geometry type.  While my method works great for you due to your raster cells fitting my method well, this approach may work better for testing if other less rectangular vector types are visible.
0 Kudos