Select to view content in your preferred language

Automating layout extent fail on one map

67
1
yesterday
DominicRobergeIADOT
Frequent Contributor

Hello,

I created a script that loop through 3 maps, update a definition query based on a parameter then change the extent of the layout and export the layout to PDF. It's "kind of working" however, every time I run the process ONE map (never the same) get stuck on the extent of the previous selection. Below is the code and the details info the process.

Weird thing is if I look in all 3 maps, the query definition has been updated...

import arcpy
import os
import sys
from arcgis import GIS
from datetime import datetime

# Get today's date
today = datetime.today()

formatted_date = today.strftime("%m%d%Y")

#********************************************************************************************

def GRMapExtent(MapName,LayerName,FieldNumber,FieldName, LayoutName):
    map_name = MapName  
    arcpy.AddMessage("         " +map_name)
    layer_name = LayerName  
    map_frame_name = 'Map Frame'  

    # Access the map
    map_obj = aprx.listMaps(map_name)[0]

    # Get the layer
    layer = map_obj.listLayers(layer_name)[0]

    # Use arcpy.Describe to get extent
    desc = arcpy.Describe(layer)
    layer_extent = desc.extent

    count_result = arcpy.management.GetCount(layer)
    record_count = int(count_result[0])
    arcpy.AddMessage("         number of records: " + str(record_count))

        # Access the layout and map frame
    layout = aprx.listLayouts(LayoutName)[0]  # or specify layout by name: aprx.listLayouts("LayoutName")[0]
    map_frame = layout.listElements("mapframe_element", map_frame_name)[0]
    
    cursor = arcpy.da.SearchCursor(layer, ['SHAPE@',FieldNumber,FieldName]) 
    arcpy.AddMessage("*****************")
    for c in cursor:
        arcpy.AddMessage(u'         {0},{1}'.format(c[1],c[2]))
        strName = c[2]
        arcpy.AddMessage("         Final Name: " + str(strName))
        extent = c[0].extent
        paddingFirst = extent.XMax-extent.XMin
        padding = (float(paddingFirst)/float(20))
        new_extent=arcpy.Extent(extent.XMin-padding,extent.YMin-padding,extent.XMax+padding,extent.YMax+padding,None,None,None,None,extent.spatialReference)

        # Set the map frame extent to the layer extent
        map_frame.camera.setExtent(new_extent)    
        arcpy.AddMessage("         " +"Mainframe extent done")

        GRLayoutTitle(SAGFieldNunber + " : "+strName+ " "+ l)
        arcpy.AddMessage("         " +"Title update")
        GRExportLayouttoPDF(template_name,strName,formatted_date)
        arcpy.AddMessage("         " +"Export to PDF done")
    #sys.exit(0)

def GRLayoutTitle(TitleName):
    elm_name = "SAG Title" # the name you assign to the title (TEXT) element
    p = arcpy.mp.ArcGISProject("CURRENT")
    for lyt in p.listLayouts(): # get the element
        for elm in lyt.listElements("TEXT_ELEMENT"):
            if elm.name == elm_name:
                elm.text = TitleName

def GRExportLayouttoPDF(layoutName,FieldName, strDate):
    layout_name = layoutName  # Name of the layout in your project
    output_folder= r"C:\GIS\OUTPUT_PDF"  
    output_name = layoutName+"_"+FieldName+"_"+strDate+".pdf"
    layout = aprx.listLayouts(layout_name)[0]
    layout.exportToPDF(output_folder+"\\"+output_name, resolution=200)

#********************************************************************************************

arcpy.AddMessage("Let's update the Definition queries")
aprx = arcpy.mp.ArcGISProject("CURRENT")
LyrName = arcpy.GetParameterAsText(0)  
FieldName = arcpy.GetParameterAsText(1)
name_field = 'SAG_FieldNumber'  #'SAG_SiteName'
SAGFieldNunber = arcpy.GetParameterAsText(2)
SAGFieldName = 'SAG_FieldName'
listMaps = ['2021 Ortho','2023 Ortho','LIDAR']  
for l in listMaps:
    arcpy.AddMessage(l + "-------------------------------------------")
    NewMapName = "SAG_Manure_Map_"+l
    template_name = "SAG_Manure_Layout_"+l
    newDefinitionQueryString = "SAG_FieldNumber = "+SAGFieldNunber      

    arcpy.AddMessage(newDefinitionQueryString)
    m= aprx.listMaps(NewMapName)[0]   
    arcpy.AddMessage(NewMapName)
    for lyr in m.listLayers():
        arcpy.AddMessage(lyr.name)
        if lyr.name ==LyrName:                                  
            arcpy.AddMessage("We found our layer to update")
            if lyr.supports('DefinitionQuery'):
                arcpy.AddMessage("here we go")

                # Updade Definition query
                
                dql = lyr.listDefinitionQueries()
                arcpy.AddMessage("original dql" + str(dql))
                for dq in dql:
                    arcpy.AddMessage("in dq")
                    dq['sql'] = newDefinitionQueryString
                lyr.updateDefinitionQueries(dql)
                arcpy.AddMessage("revised dql" + str(dql))

                
            count_result = arcpy.management.GetCount(lyr)
            record_count = int(count_result[0])
            arcpy.AddMessage("number of records: " + str(record_count))

    arcpy.AddMessage("Now let's change the extent of the map")
    GRMapExtent(NewMapName, LyrName,name_field,SAGFieldName,template_name)


arcpy.AddMessage("------------------------") 
arcpy.AddMessage("Definition query updated")   

 

This is the details from the proces

DominicRobergeIADOT_0-1752450689098.png

 

 I looked at this for too long:(

Any help would be much appreciated

0 Kudos
1 Reply
TonyAlmeida
MVP Regular Contributor

Try adding a delay between operations. Also try adding a clear election before export.

def GRMapExtent(MapName, LayerName, FieldNumber, FieldName, LayoutName):
    map_name = MapName  
    arcpy.AddMessage("         " + map_name)
    layer_name = LayerName  
    map_frame_name = 'Map Frame'  

    # Access the map
    map_obj = aprx.listMaps(map_name)[0]
    
    # Clear any existing selection
    for lyr in map_obj.listLayers():
        if lyr.isFeatureLayer:
            lyr.setSelectionSet(None)

    # Get the layer
    layer = map_obj.listLayers(layer_name)[0]
    
    # Refresh the map and layout
    aprx.save()
    time.sleep(1)  # Small delay

 

0 Kudos