Export selected data driven pages only

A common task I perform with the asset management data is to create mapbooks per service (Water, Electricity etc) per main town/area/grid. I normally do this at the start of the project, to display the data we currently have. The asset guys then take the maps to the client, who will mark up amendments and additions.

While I cringe at having to create hard copies of anything, it’s the quickest way to get the information out of the client. It’s also relatively easy for me to create the mapbooks – I just have to open my service templates, save a new copy, set the data sources and CS to my current area, and export. I could automate this part of the process also, but often I need to visually confirm that the “current” data I am using is actually “current”.

When I set up the data driven pages for an area, I switch on all the asset data layers I have, and see which towns they are grouped into. I create best-fit rectangles around them, either by eyeballing it and drawing it in graphics, or using the Strip Map Index Features tool. Often, some areas won’t have Electricity data, or the Water Supply data only covers 3 out of the 5 grid blocks which covers the town.

Before, I would manually check this, and create separate index layers for each service, which would be used for that service’s data driven pages. This was a terrible way to do things, but doing it that way is what made me determined to find a better way. To Python!


#
# @date 13/07/2015
# @author Cindy Williams
#
# Intersects feature layers with the index layer
# for selected data driven export to a multi-page
# PDF with embedded layers.
#
# For use as a standalone script.
#
import arcpy
import os
map_folder = r"C:\Some\Arb\Folder\mxd
pdf_folder = r"C:\Some\Arb\Folder\pdf"
kml_folder = r"C:\Some\Arb\Folder\kml"
# Get all the mxds in the map folder
(_,_, mapdocs) = os.walk(map_folder).next()
for md in mapdocs:
mxd = arcpy.mapping.MapDocument(os.path.join(map_folder, md))
df = arcpy.mapping.ListDataFrames(mxd)[0] # First data frame
ddp = mxd.dataDrivenPages
ddp_lyr = ddp.indexLayer
# Only get the layers in the Data group
data_lyrs = [lyr for lyr in arcpy.mapping.ListLayers(mxd) if lyr.isFeatureLayer and lyr.longName.split("\\")[0] == "Data"]
for lyr in data_lyrs:
# Selects the data driven pages that intersects all feature layers
# in the Data group
arcpy.management.SelectLayerByLocation(in_layer=ddp_lyr,
overlap_type="CONTAINS",
select_features=lyr,
selection_type="ADD_TO_SELECTION")
print("Data driven pages selected: {}.".format(len(ddp.selectedPages)))
pdf_name = os.path.join(pdf_folder, md[:-4] + ".pdf")
# Uses the PDF export function from the DataDrivenPagesClass
ddp.exportToPDF(out_pdf=pdf_name,
page_range_type="SELECTED",
multiple_files="PDF_SINGLE_FILE",
resolution=100,
layers_attributes="LAYERS_AND_ATTRIBUTES",
georef_info="True")
print("Exported " + md)
# Cannot export to KML with basemap in mxd. Remove layer
# first and add back in
kmz_name = os.path.join(kml_folder, md[:-4] + ".kmz")
# Converts the mxd to KML. Only the Data group layers are
# switched on, so only they will be exported. Can enforce
# the layer visibility by lyr.visible = True
arcpy.conversion.MapToKML(in_map_document=mxd,
data_frame=df.name,
out_kmz_file=kmz_name,
map_output_scale=10000)
print("KML conversion complete.")
print("Script complete.")

This script takes a folder containing the various service MXDs, which have been set up so that the operational data is in a group layer called Data. Each of these layers is intersected with the data driven pages index layer, to determine which DDP polys contain the operational data. In Line 35, I’ve specified the selection_type as ADD_TO_SELECTION, so as not to lose the previously selected pages.

In Line 39, instead of making the traditional call to arcpy.mapping.ExportToPDF, I used dataDrivenPages.exportToPDF instead. The funny thing about the ArcGIS documentation is that I can look at the same pages so many times, and still discover new things.

What I like about this method is that it allows a SELECTED page range to be exported. This allows me to only have one index layer for an area 🙂 At the end of the script, I put some code in to convert the entire map to a KMZ file. That portion currently does not work, because the imagery basemap needs to be removed from the mxd before it can be converted. This should be as simple as calling RemoveLayer on the basemap, but I always have fantastic problems working with the layer movement methods (insert, add, move etc).

Edit: I just saw that I actually posted this script in July as well, when I wrote it initially. I was just so excited.