I used an Python (2.7) ArcMap script for years and now I am trying to convert it to use with ArcPro (Python 3). I have converted half of my ArcMap script to ArcPro (with Visual Studio) but am stuck on modifying my code to zoom to the extent of the layer after modifying its definition query.
The map name is "Mailing List Map".
The layout I want to use to export my pdf maps from is called:"Irrigation_Services_Maps"
The table name I am changing the map title of is a variable called irrStats. It has two columns, Customer Name and Frequency (number of customer names-each record represents an irrigation point. A single customer can have many irrigation points)
I want to create a map with the customer name as the title and all the irrigation points associated with that customer and export it as a pdf.
Can someone please guide me as to rewrite this. I have spent all day reviewing this with no discernable solution. You would think it was easier than this.
Issues with code start at line that begins #####. I could not figure out how to add line numbers.
Thanks
import arcpy, os
from datetime import datetime
startTime = datetime.now()
print ((datetime.now() - startTime))
irrFile = arcpy.GetParameterAsText(0) # Gets the irrigation file with the data in it
pdfFolder = arcpy.GetParameterAsText(1) # Asks for folder location to put the pdf output files
arcpy.AddMessage(pdfFolder)
pdflist = [f for f in os.listdir(pdfFolder) if f.endswith(".pdf")]
for f in pdflist:
os.remove(os.path.join(pdfFolder, f))
arcpy.env.overwriteOutput = True # Allows us to run the script repeatedly without deleting the intermediate files
aprx = arcpy.mp.ArcGISProject("CURRENT")
aprxMap = aprx.listMaps("Mailing List Map")[0]
lyt=aprx.listLayouts("Irrigation_Services_Maps")[0]
scratchDir = pdfFolder + "\\scratch" # Temporary folder to store temp data
arcpy.AddMessage(scratchDir)
if not os.path.exists(scratchDir):
os.makedirs(scratchDir)
arcpy.env.workspace = scratchDir
arcpy.env.overwriteOutput = True
tempFGDB = arcpy.CreateFileGDB_management(scratchDir, "scratchGDB").getOutput(0)
arcpy.AddMessage(tempFGDB)
arcpy.env.workspace = tempFGDB
irrStats = "irr_stats"
if arcpy.Exists(irrStats):
arcpy.Delete_management(irrStats)
arcpy.Frequency_analysis(irrFile, irrStats, "cus_name")
with arcpy.da.SearchCursor(irrStats, ("FREQUENCY", "cus_name")) as rows: # Goes through the irrStats table
for row in rows:
cusName = row[1]
cusFreq = row[0]
if len(cusName) > 1:
arcpy.AddMessage(cusName)
lyr = aprxMap.listLayers(irrFile)[0]
lyr.definitionQuery = ""
lyr.definitionQuery = "\"cus_name\" = " + "'" + cusName + "'"
for xyz in aprx.listLayouts():
for elm in xyz.listElements("TEXT_ELEMENT"):
if elm.name == "customer":
elm.text = (cusName) # and changes the title (text element "Customer") to selected name in table
###### Don't know how to code Extent, Scale and Refresh View for ArcPro
###### Old ArcMap code needing rewrite below this point
pdfMap = pdfFolder + "\\" + cusName + ".pdf"
if cusFreq == 1: # if there is only one customer record
arcpy.AddMessage("Name : " + cusName)
ext = lyr.getExtent()
df.extent = ext
arcpy.RefreshActiveView() # redraw the map
df.scale = 1000 # set the scale to 1000
arcpy.RefreshActiveView() # redraw the map
arcpy.mapping.ExportToPDF(mxd, pdfMap)
elif cusFreq > 1: # if there is more than 1 record
arcpy.AddMessage("Name2 : " + cusName)
ext = lyr.getExtent() # Find out the extent
df.extent = ext # zoom to it
arcpy.RefreshActiveView() # redraw the map
if df.scale < 1000: #set the scale to 1000 is extent is < 1000
df.scale = 1000
else:
df.scale = df.scale * 1.2 # otherwise make the scale 1.2 times the layers extent
arcpy.RefreshActiveView() # refresh the map
arcpy.mapping.ExportToPDF(mxd, pdfMap) # export the map
arcpy.AddMessage("more than one")
else:
arcpy.AddMessage("Name3 : " + cusName)
lyr.definitionQuery = ""
There are a few things you have to look out for.
With ArcGIS Pro and the "CURRENT" project, all changes to the arcpy.mp-API result in a direct update in ArcGIS Pro, so there is no need to call a refreshActiveView
-function.
Properties of data elements, such as layers, can be retreived using arcpy.Describe:
desc = arcpy.Describe(lyr)
etxent = desc.extent
In ArcGIS Pro you don't work with DataFrames anymore, instead use the classes MapFrame
(Page Layout element) and MapView
(active Map).
On both of these classes you have a property camera
which gives you access to the scale:
map_view = aprxMap.activeView
camera = map_view.camera
#get current extent:
current_extent = camera.getExtent()
#set extent
camera.setExtent(extent)
The scale is also a property of the camera-class (read and write) :
camera = map_view.camera
#read
scl = camera.scale
#write
camera.scale *= 1.5
Mayber you can narrow down the problems you have converting to ArcGIS Pro using this.