2

I have an arcpy script which is bringing layers within a workspace into the table of contents, checking whether they contain features within the "current" extent of the mxd, and removing them if they are not. my script is as follows:

mxd = arcpy.mapping.MapDocument ("CURRENT")
arcpy.env.workspace = 'Database Connections\database.sde'
arcpy.env.overwriteOutput = True
df = arcpy.mapping.ListDataFrames(mxd, "*")[0] 
arcpy.env.extent = df.extent

dsList = arcpy.ListDatasets("", "Feature")  

for ds in dsList:
    fcList = arcpy.ListFeatureClasses("*","",ds)
    for FC in fcList:
        try:
            addLayer = arcpy.mapping.Layer(FC)
            addLayer.name = FC
            addLayer.visible = False
            arcpy.mapping.AddLayer(df,addLayer,"AUTO_ARRANGE")

            for lyr in arcpy.mapping.ListLayers(mxd,""):
                cnt = int(arcpy.GetCount_management(lyr).getoutput(0))
                if cnt<1:
                    arcpy.mapping.RemoveLayer(df,lyr)
                del addLayer
        except:
            print "problem with: " + str(FC)
            pass
            del FC
        del fcList

print 'finished'
arcpy.RefrechTOC()
arcpy.RefreshActiveView()
arcpy.AddMessage("Appropriate Feature Layers Added")
mxd.save
del mxd

This script works, but the trouble is, the database that I am working with has become larger than it used to be, so much so that this tool takes too long to run now for it to be useful.

Question: is there a way to call arcpy.mapping.RemoveLayer() outside of the 'for' loop of arcpy.mapping.ListLayers() in order to cut the size of the list the loop checks to 1?

  • Perhaps intersect 2 extents in memory and skip add layer if output is empty. – FelixIP Aug 31 '18 at 21:53
  • arcpy.mapping.ListLayers is not dependent on the number of tables in the database, but the number of Layers in the MapDocument. It's ListFeatureClasses which is the long pole in your tent. Still, there are a number of ways to solve this that don't rely on double-nested loops. – Vince Aug 31 '18 at 22:48
  • It seems like you could create a view of SDE_Layers that exposes minx,miny,maxx and maxy. That way you could open a cursor and just make one query of the database to find all featureclassnames that intersect your extent. – Kirk Kuykendall Sep 1 '18 at 1:55
  • 1
    Your description of your tool isn't correct, it's not removing those that don't intersect but those that have no features, either way I'd do that outside the loop... if you really want to skip those that don't intersect get your dataframe extent resources.arcgis.com/en/help/main/10.2/index.html#//… and your arcpy.describe(ds).extent resources.arcgis.com/en/help/main/10.2/index.html#/… and check for overlap before adding the layer avoiding the horrible double nested loop idea altogether. – Michael Stimson Sep 1 '18 at 11:31
0

I realized that I was not achieving the goal I had described in my question. Instead of automatically adding the layer and conditionally removing it, I did not add the layer until a condition (containing features in the current env.extent) was met.

cnt  = int(arcpy.GetCount_management(lyr).getoutput(0))
if cnt<1:
    addLayer = arcpy.mapping.Layer(FC)
    addLayer.name = FC
    addLayer.visible = False
    arcpy.mapping.AddLayer(df,addLayer,"AUTO_ARRANGE")

was a more appropriate solution. It seems so simple now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.