Using ArcObjects in ArcPy to change map grids in Data Driven Pages

by Chars   Last Updated February 11, 2019 08:22 AM - source

I'm a newcomer to Python and have been working on using ArcPy scripts to automate Data Driven Pages in ArcGIS. I would like some help please to use ArcObjects in ArcPy and change map grids in DDP with different scale maps. I have copied two blocks of code below. The first block of code works (originally copied from Stack Exchange, please excuse my clumsy additions) and produces a single pdf of four maps. Because the first map is an Overview I would like to swap grids, with one for the Overview and another for the remaining three maps. The second block is my attempt at integrating Alex Tereshenkov's code for accessing ArcObjects in ArcPy (https://tereshenkov.wordpress.com/2017/04/16/access-to-arcmap-map-document-grid/), and so far I have managed to produce a 4 page map, but it is the same map on each page, with no change in map grid. Clearly I'm out of my depth! Is it even possible to make this work? And if anyone can explain the logic behind Alex's clever "for g in grids" 6 lines of code, that would be great too. Apologies for all the code...

Code 1:

import arcpy, os
import sys

# Create an output directory variable
#
outDir = r'C:\AA\Project\SCRATCH'

# Create a new, empty pdf document in the specified output directory
# This will be your final product
finalpdf_filename = outDir + r"\FinalMapBook.pdf"
if os.path.exists(finalpdf_filename): # Check to see if file already exists, delete if it does
 os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)

# Create a Data Driven Pages object from the mxd you wish to export

mxdPath = r'C:\AA\Project\SCRATCH\01M_Project_20190117.mxd'
tempMap = arcpy.mapping.MapDocument(mxdPath)
tempDDP = tempMap.dataDrivenPages

# Create objects for the layout elements and layers

sScaleBar = arcpy.mapping.ListLayoutElements(tempMap, "MAPSURROUND_ELEMENT", "1in3thou")[0]
lScaleBar = arcpy.mapping.ListLayoutElements(tempMap, "MAPSURROUND_ELEMENT", "1in20thou")[0]
tplayer = arcpy.mapping.ListLayers(tempMap, "testpits")[0]
balayer = arcpy.mapping.ListLayers(tempMap, "bsa_opf")[0]
bblayer = arcpy.mapping.ListLayers(tempMap, "bsa_ev")[0]
bmalayer = arcpy.mapping.ListLayers(tempMap, "bsa_opf_mat")[0]
bmblayer = arcpy.mapping.ListLayers(tempMap, "bsa_ev_mat")[0]

# Instead of exporting all pages at once, you will need to use a loop to export one at a time
# This allows you to check each index and execute code to add inset maps to the correct pages

for pgIndex in range(1, tempDDP.pageCount + 1, 1):

 # Create a name for the pdf file you will create for each page
 temp_filename = r'C:\AA\Project\SCRATCH\temp_pdfs\MB_' + \
                        str(pgIndex) + ".pdf"
 if os.path.exists(temp_filename):
   os.remove(temp_filename)

# The following if statements check the current page index against given  values

# overview page

pageNumList = [1]
if pgIndex in pageNumList:
  sScaleBar.elementPositionX = -10
  sScaleBar.elementPositionY = 3.8
  lScaleBar.elementPositionX = 2.8
  lScaleBar.elementPositionY = 3.8
  tplayer.visible = False
  balayer.visible = True
  bblayer.visible = True
  bmalayer.visible = False
  bmblayer.visible = False

# borrow material assessment pages

pageNumList = [2,3,4]
if pgIndex in pageNumList:
 sScaleBar.elementPositionX = 2.8
 sScaleBar.elementPositionY = 3.8
 lScaleBar.elementPositionX = 2.8
 lScaleBar.elementPositionY = -0.8
 tplayer.showLabels = True
 tplayer.visible = True
 balayer.visible = False
 bblayer.visible = False
 bmalayer.visible = True
 bmblayer.visible = True

# Code to export current page and add it to mapbook
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)

# Clean up your page layout

sScaleBar.elementPositionX = -10
lScaleBar.elementPositionX = 45
arcpy.RefreshActiveView()

# Clean up

del tempMap

# Update the properties of the final pdf

finalPdf.updateDocProperties(pdf_open_view="USE_THUMBS",
                         pdf_layout="SINGLE_PAGE")

# Save your result

finalPdf.saveAndClose()

Code 2:

import sys
from comtypes.client import GetModule, CreateObject
import arcpy, os
import arcpy.mapping as mp
from snippets import GetStandaloneModules, InitStandalone
esriCarto = GetModule(r"C:\Program Files (x86)\ArcGIS\Desktop10.6  \com\esriCarto.olb")

# Running this code for the first time, you would need to import
# the ?StandaloneModules?. Can comment out later.
GetStandaloneModules()
InitStandalone()

# Create an output directory variable

outDir = r'C:\AA\Project\SCRATCH'

# Create a new, empty pdf document in the specified output directory
# This will be your final product

finalpdf_filename = outDir + r"\FinalMapBook.pdf"
if os.path.exists(finalpdf_filename):
  os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)

# Create a Data Driven Pages object from the mxd you wish to export

mxdPath = r'C:\AA\Project\SCRATCH\01M_Project_20190117.mxd'
tempMap = mp.MapDocument(mxdPath)
tempDDP = tempMap.dataDrivenPages

for pgIndex in range(1, tempDDP.pageCount + 1, 1):

  # Create a name for the pdf file you will create for each page

    temp_filename = r'C:\AA\Project\SCRATCH\temp_pdfs\MB_' + \
                        str(pgIndex) + ".pdf"
    if os.path.exists(temp_filename):
        os.remove(temp_filename)

#......................

def export_map(show_scale):
handle_grids(show_scale)

tempMap = mp.MapDocument(mxdPath)
tempDDP = tempMap.dataDrivenPages
df = mp.ListDataFrames(tempMap,"Layers")[0]
sScaleBar = mp.ListLayoutElements(tempMap, "MAPSURROUND_ELEMENT", "1in3thou")[0]
lScaleBar = mp.ListLayoutElements(tempMap, "MAPSURROUND_ELEMENT", "1in20thou")[0]
tplayer = mp.ListLayers(tempMap, "testpits")[0]
balayer = mp.ListLayers(tempMap, "bsa_opf")[0]
bblayer = mp.ListLayers(tempMap, "bsa_ev")[0]
bmalayer = mp.ListLayers(tempMap, "bsa_opf_mat")[0]
bmblayer = mp.ListLayers(tempMap, "bsa_ev_mat")[0]

# overview page
if show_scale == 'large':
     pageNumList = [1]
     if pgIndex in pageNumList:
        sScaleBar.elementPositionX = 2.8
        sScaleBar.elementPositionY = -1.2
        lScaleBar.elementPositionX = 2.8
        lScaleBar.elementPositionY = 2.8
        tplayer.visible = False
        balayer.visible = True
        bblayer.visible = True
        bmalayer.visible = False
        bmblayer.visible = False


# Code to export current page and add it to mapbook

tempDDP.exportToPDF(temp_filename.format(show_scale), "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)

# remaining pages

if show_scale == 'small':
 pageNumList = [2,3,4]
 if pgIndex in pageNumList:
    sScaleBar.elementPositionX = 2.8
    sScaleBar.elementPositionY = 2.8
    lScaleBar.elementPositionX = 2.8
    lScaleBar.elementPositionY = -0.8
    tplayer.showLabels = True
    tplayer.visible = True
    balayer.visible = False
    bblayer.visible = False
    bmalayer.visible = True
    bmblayer.visible = True

 # Code to export current page and add it to mapbook

tempDDP.exportToPDF(temp_filename.format(show_scale), "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)

 # create grid objects

def handle_grids(show_scale):
#creating a map document object
mxdObject = CreateObject(esriCarto.MapDocument, interface=esriCarto.IMapDocument)
mxdObject.Open(mxdPath)

#accessing the map
IMap = mxdObject.ActiveView.FocusMap

activeView = mxdObject.ActiveView
pageLayout = activeView.QueryInterface(esriCarto.IPageLayout)
graphicsContainer = pageLayout.QueryInterface(esriCarto.IGraphicsContainer)

#IFrameElement
frameElement = graphicsContainer.FindFrame(IMap)

#IMapFrame
mapFrame = frameElement.QueryInterface(esriCarto.IMapFrame)

#IMapGrids
mapGrids = mapFrame.QueryInterface(esriCarto.IMapGrids)
[mapGrids.MapGrid(i) for i in xrange(mapGrids.MapGridCount)]

grids = [mapGrids.MapGrid(i) for i in xrange(mapGrids.MapGridCount)]

for g in grids:
    print g.Name
    if show_scale.lower() in g.Name.lower():
        g.Visible = True
    else:
        g.Visible = False

for g in grids:
    print g.Name, g.Visible

#......................

export_map('large')
export_map('small')

arcpy.RefreshActiveView()

# Clean up

del tempMap

# Update the properties of the final pdf

finalPdf.updateDocProperties(pdf_open_view="USE_THUMBS",
                         pdf_layout="SINGLE_PAGE")

# Save your result

finalPdf.saveAndClose()


Related Questions


data driven pages for multiple frames

Updated June 07, 2017 10:22 AM

Arcpy Data Driven Script no index layer

Updated July 13, 2016 08:09 AM



Pratical Grid Index for Data Driven Pages

Updated October 09, 2017 04:22 AM