3

How could I adapt the following code to enable me to zoom to each individual selected Geometry one after the other?

import arcpy
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]
df.zoomToSelectedFeatures()
arcpy.RefreshActiveView()
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Robert Buckley
  • 10,175
  • 14
  • 76
  • 156
  • 2
    Off the top of my head could this be done using a for loop and the arcpy.da.searchcursor()? – spk578 Jun 29 '15 at 08:53
  • 1
    Without knowing why you want to do this, my first thought is that it sounds like it may be a requirement that could be met using Data Driven Pages functionality. – PolyGeo Jun 29 '15 at 09:33
  • 1
    Use Case is that I want to use a click a button to iterate through the selected elements (one element per click) without having to double click in the attribute table. The great advantage is that when I have many (over 500) geometries to click through, I can just do this very quickly with a single button. – Robert Buckley Jun 29 '15 at 09:50

2 Answers2

3

I have a visit tool (in C#, converted from VB.net, which was upgraded from VB6 which was influenced by a tool I wrote in AML)... anyway, the key is to use the Envelope of the geometry in the case of polygon, polyline or multipoint and recentre the map extent.

Here is a very basic start for you:

import arcpy
mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]
Envelopes = [] # store extents here

# find the selection set
SelLayer = arcpy.mapping.ListLayers(mxd,data_frame=df)[0] # first layer
fidSet   = arcpy.Describe(SelLayer).FIDSet

if len(fidSet) == 0:
    arcpy.AddMessage("Nothing selected")
else:
    # now cursor through it an get the geometries
    # storing their extents into a list
    with arcpy.da.SearchCursor(SelLayer,"SHAPE@") as SCur:
        for feat in SCur:
            # I'm going to assume polygon/polyline
            Envelopes.append(feat[0].extent) # grab the envelope 

    df.extent = Envelopes[0] # first extent
    arcpy.RefreshActiveView()

First you need to check there is a selction against the layer, if there is cursor through the records (remember that if there is a selection against a layer only the selected records are returned) using SHAPE@ to get the geometry object which has an extent as a property, store these in a list and then calling the first one to set the current dataframe extent (also a property).

Note that once the list is made the selection can be changed, this may or may not be what you want. In my case I wanted the extents to remain and be able to edit as I went through the list.

Michael Stimson
  • 25,566
  • 2
  • 35
  • 74
1

You can incorporate your code as above to include the following:

  1. Use arcpy.da.searchcursor() make a python list of those selected features
  2. Iterate through your python list using a unique ID to create and use an SQL expression letting you Select By Attribute, then zoom to selected features.

Playing around I think something along these lines will work...it is untested at the moment:

import arcpy

mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
# From selection make feature layer (ArcGIS always defaults to using selected features)
LayerList = []
with arcpy.da.SearchCursor("Layer1", "OBJECTID") as Cursor:
    for item in Cursor:
        LayerList.append(item)
        Query = """{0} = {1}""".format("OBJECTID", item)
        #print LayerList
        #print Query
        for rows in LayerList:
            arcpy.SelectLayerByAttribute_management("Layer1", "NEW_SELECTION", Query)
            df.zoomToSelectedFeatures()
spk578
  • 1,516
  • 1
  • 11
  • 27
  • Bear in mind this will literally scroll through those selected features zooming from one to the next so as @PolyGeo indicated I'm not sure what purpose this will hold. – spk578 Jun 29 '15 at 09:39
  • To view the features it would probably be worthwhile setting the data frame reference scale so you have some context for the selected data. – spk578 Jun 29 '15 at 09:58
  • I would set the definitionQuery property of the layer to Query instead of performing SelectLayerByAttribute which I suspect is slightly more expensive. – PolyGeo Jun 29 '15 at 10:20
  • 1
    Another technique which may be worth considering is getting your arcpy.da rows back as a dictionary: https://arcpy.wordpress.com/2012/07/12/getting-arcpy-da-rows-back-as-dictionaries/ – PolyGeo Jun 29 '15 at 10:25