I am creating a toolbox tool using a python script that creates maps based on user input. I have created a map template that gets saved and altered with python. I am struggling on how to update some text in text boxes in the layout view using Arcpy. I was able to do it with dynamic text with data driven pages, but I couldn't find any python code to get data driven pages to refresh so I decided to try to update the text with python directly. With data driven pages, the dynamic text was pulling the text from an attribute table. I'm fairly new to python so am struggling with how to pull values from a table to use as part of the text. I am able to update text as long as I have the variable defined somewhere else (not from a table), but the only method I found to pull data from a table was with a search cursor but that returns a list rather than a value so I get an error. The feature classes with the text values I want only have one row in them so it is a list of one. How can I convert that list to a value. I am only including the applicable parts of the script. I also removed the actual paths from the code.
import arcpy
import os
ID = arcpy.GetParameterAsText(1)
city = arcpy.GetParameterAsText(3)
WS = os.path.join('path to gdb', "WS")
dfield = 'name'
datefield = 'date'
cfield = "county"
#Use SearchCursor - these features only have one row, but these are my problem because they are lists
wsname = [row[0] for row in arcpy.da.SearchCursor(WS, dfield)]
wsdate = [row[0] for row in arcpy.da.SearchCursor(WS, datefield)]
county = [row[0] for row in arcpy.da.SearchCursor(overview, cfield)]
#update text
for elm in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
elm.text = elm.text.replace('WS',wsname) #this doesn't work because wsname is a list
elm.text = elm.text.replace('City',city) #this works
elm.text = elm.text.replace('text2',"words" ID " -more words") #This works
elm.text = elm.text.replace('Name', county) #this doesn't work because county is a list
elm.text = elm.text.replace('Date',wsdate) #this doesn't work because wsdate is a list
arcpy.RefreshActiveView()
mxd.save()
CodePudding user response:
This code will work when run from a arcgis toobox script tool.
# define the aprx file and the layout in the project
import arcpy
aprx = arcpy.mp.ArcGISProject(r'path\to\the\arcgis\aprxfile.aprx')
aprxLayout = aprx.listLayouts()[0] '''adding the zero index will return the first
layout in the layout list, if there is more than one layout'''
# get the attribute value to use for the layout text element
fieldNames = ['FieldName1', 'FieldName2']
with arcpy.da.SearchCursor(r'path\to.gdb\featureclass', fieldNames) as sc:
for row in sc:
if (row[0]) is not None:
field1Value = (row[0])
if (row[0]) is None:
field1Value = 'Null'
if (row[1]) is not None:
field2Value = (row[0])
if (row[1]) is None:
field2Value = 'Null'
# Assign the attribute value to the layout text element
for textElem in aprxLayout.listElements:
if textElem.name == 'name of layout text element in the element properties':
text.Elem.text = field1Value
if textElem.name == 'name of layout text element in the element properties':
text.Elem.text = field2Value
aprx.saveACopy(r'path/to/folder/projectname')
del aprx
CodePudding user response:
I was able to tweak armedwiththeword's code to come up with this.
import arcpy
mxd = arcpy.mapping.MapDocument(path_to_mxd)
fieldNames = ['name', 'date']
with arcpy.da.SearchCursor(WS, fieldNames) as sc:
for row in sc:
if(row[0]) is not None:
field1Value = (row[0])
if(row[0]) is None:
field1Value = 'Null'
if(row[1]) is not None:
field2Value = (row[1])
if(row[1]) is None:
field2Value = 'Null'
fieldName = ['CTY_NAME']
with arcpy.da.SearchCursor(overview, fieldName) as sc:
for row in sc:
if(row[0]) is not None:
field3Value = (row[0])
if(row[0]) is None:
field3Value = 'Null'
# Assign the attribute value to the layout text element
for textElem in arcpy.mapping.ListLayoutElements(mxd,'TEXT_ELEMENT'):
if textElem.name == 'title':
textElem.text = field1Value " words"
if textElem.name == 'subtitle':
textElem.text = "WS -0" ID " -more words"
if textElem.name == 'city':
textElem.text = city
if textElem.name == 'county':
textElem.text = field3Value
if textElem.name == 'date':
textElem.text = field2Value