0

Is there a way to display dynamic text on following conditions?

  • based on current layout view (Data Frame)
  • combine text from attribute tables from different features (others than Data Driven feature)

Dynamic_text_attribute_table

Solution should be as follows:

Dynamic_text_ShouldBeSolution

Similar option is used for legends:

  • Legend Properties - Items - Map Extend Options

Dynamic_text_legend

  • Do you have any Python skills? Custom coding will most likely be the answer. – Dan Mar 18 '18 at 23:59
  • @Dan I have some Python skill (see my other Questions), but in this case I have no clue which way I should try. I´m familiar with geometry, with layout not so much. How would you select features by DataFrame view? I think approach to whole question could be like this: 1) Select features by dataframe view, 2) create list of attributes of the selected features, 3) show list as text in Layout view. All this should be dynamic, so if i pan, text would change. – Honzin Mar 19 '18 at 11:41
  • I think you're heading down the right path, but it may have to be a workflow that you manually trigger rather than dynamically as you pan. It's probably do-able as you pan but ArcObjects will be required. I'd build this sort of functionality into a Python Add-In or a stand-alone script to update the text immediately prior to exporting the map to an output format. – Dan Mar 19 '18 at 11:49
  • As far as select features by data frame, you could create a geometry object that matches the data frame extent then do a select by location using that object...there may be a easier way but that's the first thing that popped into my head. – Dan Mar 19 '18 at 11:51
4

This Python script will get you halfway there (note: tested only on 10.3.1 but should still work on 10.6). The code is verbose to illustrate what is going on, feel free to optimise. It creates a polygon object based on the extent of the first data frame in the MXD. It then uses that polygon in a Select Layer By Location operation. It then uses a search cursor on the selected features to create a list of attributes. Finally it updates a text element on the layout with the list of attributes.

It does not automatically update the text element when the data frame extent changes. As mentioned in the comments, you'll probably need to use ArcObjects to get that level of functionality.

The script runs from within ArcMap and you can use it as is. I've just run it from the Python console with

execfile(r"E:\Temp\Select_Features_Within_Data_Frame.py")

It would be more usable if you incorporate the logic into a Python add-in and build a method for specifying multiple layers and fields as inputs.

You will need to modify the aSelectLayer and aSelectField variables to suit your data. You will also need to add a text element on your layout with the Element Name of "Features_in_Data_Frame". I suggest adding it as Rectangle Text so that it can automatically handle text that may overflow one line.

import arcpy

# ---------------------------------------------------------------------------
def GetAttributeList(aLyr, aField):
    aList = []
    with arcpy.da.SearchCursor(aLyr, aField) as aRows:
        for aRow in aRows:
            aList.append(aRow[0])
    return aList
# ---------------------------------------------------------------------------

# ---------------------------------------------------------------------------
def FeatCount(aLyr):
    return int(arcpy.GetCount_management(aLyr).getOutput(0))
# ---------------------------------------------------------------------------

aSelectLayer = "test_pnt"
aSelectField = "UFI"

aMXD = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(aMXD)[0]
aExtents = df.extent
Xmin = aExtents.XMin
Ymin = aExtents.YMin
Xmax = aExtents.XMax
Ymax = aExtents.YMax

aPnt1 = arcpy.Point(Xmin, Ymin)
aPnt2 = arcpy.Point(Xmin, Ymax)
aPnt3 = arcpy.Point(Xmax, Ymax)
aPnt4 = arcpy.Point(Xmax, Ymin)

aArray = arcpy.Array()
aArray.append(aPnt1)
aArray.append(aPnt2)
aArray.append(aPnt3)
aArray.append(aPnt4)

aPoly = arcpy.Polygon(aArray)

arcpy.SelectLayerByLocation_management(aSelectLayer,"WITHIN",aPoly,"#","NEW_SELECTION")

if FeatCount(aSelectLayer) > 0:
    aValues = GetAttributeList(aSelectLayer, aSelectField)

    # Update the text element in the layout
    elm = arcpy.mapping.ListLayoutElements(aMXD, "TEXT_ELEMENT", "Features_in_Data_Frame")[0]
    elm.text = "; ".join(aValues)

    arcpy.SelectLayerByAttribute_management(aSelectLayer, "CLEAR_SELECTION")
    arcpy.RefreshActiveView()

enter image description here enter image description here

EDIT

I just noticed that if you change the data frame extent to somewhere where there are no features and run the script, the text element will not update. Just add the following to the bottom of the if clause:

else:
    elm = arcpy.mapping.ListLayoutElements(aMXD, "TEXT_ELEMENT", "Features_in_Data_Frame")[0]
    elm.text = "No features in extent"
  • Great! I just edited line 34. I didn't recognise "GetAttributeList" so I went through by SearchCoursor. – Honzin Mar 22 '18 at 7:49
  • If you have another look at the top of the script you will see that GetAttributeList is a function that uses a Search Cursor to return a list of attributes. – Dan Mar 22 '18 at 22:59
  • If you dont have access to the text elements through the production mapping extension is there any way the output can be linked to a standard text box? – Cameron May 22 '18 at 13:46
  • @Cameron, this method is using out-of-the-box ArcGIS/arcpy. – Dan May 22 '18 at 22:46

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.