ArcGISProject.activeView: Return table, etc. views.

336
4
10-18-2023 10:56 AM
Status: Already Offered
Labels (1)
AlfredBaldenweck
MVP Regular Contributor

So, a colleague of mine recently ran into an issue where a tool was failing in updateParameters() because on a particular line, the list index was out of range.

Is the code in question (Error caused by line 3 in this snippet):

 

 

aprx = arcpy.mp.ArcGISProject('current')
mv = aprx.activeView
if str(mv).split(' ')[0].split('.')[2] == "Layout": #if a activeView returns a layout, get the map frame from it
    mf = mv.listElements("MAPFRAME_ELEMENT")[0].map
else: #it's a map view
    mf = mv.map

 

 

What we figured out is that trying to run the tool with an attribute table open and active was causing the issue.

Essentially, because ArcGISProject.activeView only sees Map or Layout Views, it was feeding line 3 a None object, which can't be split, acted upon, etc.

I'd prefer to avoid this sort of thing in the future.

Here are two options I can think of to fix this:

  • If a table, etc. is open and active, return the map it belongs to
    • Alternatively, return the last active map/layout.
  • Recognize table, etc views in Active view, be able to check the type of the result.
4 Comments
AlfredBaldenweck

It appears this functionality is found in .activeMap.

Please mark this thread as already offered.

Thank you.

JeffBarrette
Status changed to: Already Offered

@AlfredBaldenweck this can be accomplished a little easier using either type() or isInstance, for example,

p = arcpy.mp.ArcGISProject('current')
av = p.activeView
if type(av) == arcpy._mp.MapView:
print("MAPVIEW")
elif type(av) == arcpy._mp.Layout:
print("LAYOUT")
else:
print("NONE")

or

p = arcpy.mp.ArcGISProject('current')
if isinstance(pactiveView, arcpy._mp.Layout):
# work with the layout
elif isinstance(p.activeView, arcpy._mp.Map):
# work with the map
else:
# Nothing found, active element isn't a map or layout

Jeff - Layout and arcpy.mp teams

AlfredBaldenweck

Hey Jeff, I actually need to eat crow again here.

I talked to my colleague and got a better understanding of what the issue was.

He created a tool to zoom to a particular geographic location (e.g. USGS quad). You select the state you want, then it grabs the correct quads for that state for you to choose. The third and final parameter is the map you zoom to, which is calculated using your active view.

The problem with this is that it will return None if a table, etc. is active, and then the entire thing will pre-emptively break. Once this happens, the most reliable way of fixing it is to just re-open the tool and trying again.

activeMap will actually do the right thing and return the map the table belongs to, but the thing with activeMap is that you can't change the view at all. 

The current work around is to use setErrorMessage() to tell the user to make a map or layout view active again, but it would be a lot easier if we could have tables, etc. return the map view they belong to.

JeffBarrette

@AlfredBaldenweck have you tried using functions like Map.openView()?  We currently don't have the ability to specifically close or even reference a particular view because they are not named and you can have many views open that all point to the same map, for example.  So we introduced openView on Map, Layout, and Report objects.  It will open and activate a view for that specific object.  If you don't want to keep opening extra views, we also introduced ArcGISProject.closeViews().  THis was you can close everything and open a specific, active view. I hope this helps your scenario.

Jeff - Layout and arcpy.mp teams