Data-Driven Pages: Dynamic Layout Element

5749
15
07-22-2010 10:52 AM
NoahBullock1
New Contributor
I'm using data driven pages to build a map book for the 50 states (i.e., my index layer). The layout of each page is identical except that on each state's page, I want an image of that state's seal. The images are all identical in size and format, they are stored in a directory, and I've appended their paths to the index layer attribute table. There doesn't appear to be a way to get them to dynamically display by using the data-driven page tools.

Anyone have any ideas on how to do this, either in combination with the ArcPy module, or by some other method?

Thanks,

Noah
0 Kudos
15 Replies
JeffMoulds
Esri Contributor
This is certainly do-able with arcpy. The basic algorithm would be:

1.) set up a default state seal image in your layout
2.) loop through each page in your Data Driven Pages
3.) read the attribute that stores the path to the image
4.) change the default image path to that of the current page
5.) export or print the individual page (for example, export to PDF)
6.) if you are creating a PDF output of the map book, append all the individual state pages to a single PDF

The DataDrivenPages class help shows how to do 2 and 3:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/DataDrivenPages/00s300000030000000/

The PictureElement class help shows how to do 4:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/PictureElement/00s30000000s000000/

The ExportToPDF function help shows how to do 5:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/ExportToPDF/00s300000027000000/

The PDFDocument class help shows how to do 6:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/PDFDocument/00s30000002w000000/
RaymondWang
New Contributor III
Hi Jeff,

Need some assistance on nesting the for loop?

I have an "AreaScale" field in the DDP index.  It contains path to the different image/logo required to match the DDP scale.  In my half working script below.  I'm having trouble putting the sourceImage loop inside the ExportToPDF.  Please advise?

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\_rwFiles\MAPBOOK\v10\rwTest.mxd")
for elm in arcpy.mapping.ListLayoutElements(mxd, "PICTURE_ELEMENT"):
        if elm.name == "area_scale":
            fieldvalue = mxd.dataDrivenPages.pageRow.getValue("AreaScale")
            elm.sourceImage = r"" + fieldvalue
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):         
    mxd.dataDrivenPages.currentPageID = pageNum
    print "Exporting page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
    arcpy.mapping.ExportToPDF(mxd, r"C:\_rwFiles\MAPBOOK\PDF\Output" + str(pageNum) + ".pdf")
del mxd




This is certainly do-able with arcpy. The basic algorithm would be:

1.) set up a default state seal image in your layout
2.) loop through each page in your Data Driven Pages
3.) read the attribute that stores the path to the image
4.) change the default image path to that of the current page
5.) export or print the individual page (for example, export to PDF)
6.) if you are creating a PDF output of the map book, append all the individual state pages to a single PDF

The DataDrivenPages class help shows how to do 2 and 3:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/DataDrivenPages/00s300000030000000/

The PictureElement class help shows how to do 4:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/PictureElement/00s30000000s000000/

The ExportToPDF function help shows how to do 5:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/ExportToPDF/00s300000027000000/

The PDFDocument class help shows how to do 6:

http://help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#/PDFDocument/00s30000002w000000/
0 Kudos
maryandrews
New Contributor III
I am also trying to change the image based on the path in the field used to name the data driven page.  I can swap the image with a static image but I have not figured out how to access the name? 
I'll post what is not working in hopes that some python wizard can help me!  Thanks in advance.

import arcpy
mxd = arcpy.mapping.MapDocument(r"B:\2011Projects\ResearchDataDrivenPageImages.mxd")
# get the page id from the page name element
pageID = mxd.dataDrivenPages.getPageIDFromName("UNITID")
mxd.dataDrivenPages.currentPageID = pageID
for elm in arcpy.mapping.ListLayoutElements(mxd,"PICTURE_ELEMENT"):
  if elm.name == "unit1":
    elm.sourceImage = r"B:\2011Projects\unit" + str(pageID) + ".jpg"
# the next line will swithc to unit2 photo without a problem
#elm.sourceImage = r"B:\2011Projects\unit2.jpg"
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
  mxd.dataDrivenPages.currentPageID = pageNum
  print "Exporting Page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
  arcpy.mapping.ExportToPDF(mxd, r"B:\2011Projects\ResearchDataDrivenPageImages" + str(pageNum) + ".pdf")
del mxd
0 Kudos
maryandrews
New Contributor III
I was able to get my script to work so I thought I would share it!

import arcpy
mxd = arcpy.mapping.MapDocument(r"B:\2011Projects\ResearchDataDrivenPageImages.mxd")

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
  mxd.dataDrivenPages.currentPageID = pageNum
  pageName = mxd.dataDrivenPages.pageRow.getValue("UNITID")
  for elm in arcpy.mapping.ListLayoutElements(mxd,"PICTURE_ELEMENT"):
      if elm.name == "unit1":
     elm.sourceImage = ("B:\\2011Projects\\" + pageName + ".jpg")
  print "Exporting Page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
  arcpy.mapping.ExportToPDF(mxd, r"B:\2011Projects\ResearchDataDrivenPageImages.mxd" + str(pageNum) + ".pdf")
del mxd
0 Kudos
AndraBobbitt
New Contributor II
Looking at the final script it does not appear the script is reading an image name (and/or path) from the index layer's attributes.  Has anyone had success with the original question of reading an attribute value of the index layer that is storing the image name and replacing the PICTURE_ELEMENT source to automatically change the image?

Here's an example of my modified code trying to do this but fails to change the image:
(The image name is stored as an attribute: image4map; all the images are located in a directory
(G:\NEPacific\Data-types\Vent-locations\Axial\images); the original mxd has the image named 'photo1'.


Thanks for any help!

import arcpy
mxd = arcpy.mapping.MapDocument(r"G:\NEPacific\Data-types\maps\datadriven-test-map.mxd")
mxd.dataDrivenPages.currentPageID = pageNum
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
imageName = mxd.dataDrivenPages.pageRow.getValue("image4map")
for elm in arcpy.mapping.ListLayoutElements(mxd,"PICTURE_ELEMENT"):
  if elm.name == "photo1":
   elm.sourceImage = ("G:\NEPacific\Data-types\Vent-locations\Axial\images\\" + imageName)
print "Exporting Page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
arcpy.mapping.ExportToPDF(mxd, r"G:\NEPacific\Data-types\maps\datadriven-test-map.mxd" + str(pageNum) + ".pdf")
del mxd
0 Kudos
AndraBobbitt
New Contributor II
My mistake, it is reading the attribute value.  The failure in my script is in the syntax for
this line:
elm.sourceImage = ("G:\NEPacific\Data-types\Vent-locations\Axial\images\\" + imageName)

Verified with print that the elm.sourceImage is set for the first image, printed the imageName
in the loop...just can't get the two to work together.

Still can't get it to work, any help would be great!
0 Kudos
JeffBarrette
Esri Regular Contributor
Andra,

I've looked at your code and made a few corrections to it.  The currentPageID line needs to be in the loop and I think your output filename may have caused problems.  Here is code very simily to your code.

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Temp\Photo.mxd")
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
  mxd.dataDrivenPages.currentPageID = pageNum
  imageName = mxd.dataDrivenPages.pageRow.getValue("image4map")
  for elm in arcpy.mapping.ListLayoutElements(mxd,"PICTURE_ELEMENT"):
    if elm.name == "photo1":
      elm.sourceImage = "C:\\Temp\\" + imageName
      print "Exporting Page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
      arcpy.mapping.ExportToPDF(mxd, r"C:\Temp\\" + str(pageNum) + ".pdf")
del mxd


Because when switching out photos, the size and positing may change so I further modified the code to elimiate extra looping and included the orginal size/positioning info that is reapplied to each new picture.

import arcpy
mxd = arcpy.mapping.MapDocument(r"C:\Temp\Photo.mxd")
elm = arcpy.mapping.ListLayoutElements(mxd, "PICTURE_ELEMENT", "photo1")[0]
elmX = elm.elementPositionX; elmY = elm.elementPositionY
elmHeight = elm.elementHeight; elmWidth = elm.elementWidth

for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
  mxd.dataDrivenPages.currentPageID = pageNum
  imageName = mxd.dataDrivenPages.pageRow.getValue("image4map")
  elm.sourceImage = "C:\\Temp\\" + imageName
  elm.elementPositionX = elmX; elm.elementPositionY = elmY
  elm.elementHeight = elmHeight; elm.elementWidth = elmWidth
  print "Exporting Page {0} of {1}".format(str(mxd.dataDrivenPages.currentPageID), str(mxd.dataDrivenPages.pageCount))
  arcpy.mapping.ExportToPDF(mxd, r"C:\Temp\\" + str(pageNum) + ".pdf")
del mxd


I hope this helps,
Jeff
0 Kudos
LaraMiller
New Contributor
I tried to adopt the last code
import arcpy
mxd = arcpy.mapping.MapDocument(r"K:\ArcProjects\malpaifireplan\firehistroymapbook.mxd")
elm = arcpy.mapping.ListLayoutElements(mxd, "PICTURE_ELEMENT", "AcresBurned1")[0]
elmX = elm.elementPositionX; elmY = elm.elementPositionY
elmHeight = elm.elementHeight; elmWidth = elm.elementWidth
for pageNum in range(1, mxd.dataDrivenPages.pageCount + 1):
mxd.dataDrivenPages.currentPageID = pageNum
imageName = mxd.dataDrivenPages.pageRow.getValue("FireHistoryGraph")
elm.sourceImage = "K:\\GIS\arcdata\malpais\jpeg\\"+ imageName
elm.elementPositionX = elmX; elm.elementPositionY = elmY
elm.elementHeight = elmHeight; elm.elementWidth = elmWidth


and keep getting an error message that says Runtime error <type 'exceptions.IOError'>: LayoutElementObject: Unexpected error


Is there something I am missing? I just want the image to change with each data driven page.
0 Kudos
DarrenEnns
New Contributor
Hi there,

We're trying to achieve the same solution (unique image on each page, with the image name tied to an attribute field), but have limited Python scripting experience. If anyone can assist with writing a script for us we would be happy to modestly compensate. Please message me and I can send you the details of how our data structure is setup.

Cheers,

Darren
0 Kudos