Select to view content in your preferred language

Map Series with multiple map fames of different extents

264
5
4 weeks ago
Labels (1)
Jacob_Allred
New Contributor

Hi all, I have a linear feature I need to capture in a figure series. To cut down on the number of pages I would like to show two map frames on each page one showing the first hundred feet of a feature the second showing 100-200. The next figure showing 200-400 ft on the two map frames.  A map series seems ideal for this but haven't been able to find a way to make a map series with multiple map frames showing different areas. Im almost trying to run two map series on one layout. I'm open to a programmatic approach but my python is rusty and I'm not sure where to start.
(ArcgisPro 3.3.1)

0 Kudos
5 Replies
DavidSolari
MVP Regular Contributor

I don't think this is something you can do with an out-of-the-box map series, but if you're willing to use Python I can think of one possible way:

  1. Add the "pypdf" package to your Python environment.
  2. Generate the index layer for the full length.
  3. Create one map with the index layer and everything else you need. Set a definition query on the index that's MOD(page_count_field, 2) = 0 to only show the odd pages.
  4. Make a layout for this map with all of the required elements. Leave room for the other map and any other layout elements that is specific to the other map. You'll probably have to fudge the page numbers in your index layer as well.
  5. Clone the map and change the definition query from = 1 to = 0, this will only show the even pages.
  6. Create a complementary layout for the "even" map.
  7. Generate map series for both. Half the pages should be on the "odd" layout and the other half on the "even" layout.
  8. Export both PDFs, then use pypdf to merge each "even" page on top of the "odd" page to create a new PDF. The pypdf documentation is a bit sparse but it should cover all the methods uses to combine PDFs like this.

Unfortunately I don't have time to validate this workflow, but the hard part with pypdf is similar to a process I've done with other projects so I'm confident you'll get something, even if it looks a bit cruddy. Let us know how it goes!

0 Kudos
Jacob_Allred
New Contributor

Peace of mind that there isn't a setting in a spatial map series that would let me do this is still reassuring. Ultimately, I am afraid I would spend more time formatting my outputs then I would if I manually exported the maps (im only looking at 4000 ft).
I did find a reddit post with a similar workflow to what you described I'll leave it here in case anyone else stumbles into this problem: 

# Purpose: This script is designed to show 2 pages from a Map Series on

# one Layout. The first map frame runs through the odd numbered

# pages in the series, while the second frame runs through the even

# numbered pages.It then combines all pages into a single, multipage PDF.

 

import arcpy, os

 

#Filepath variables are machine specific. May need to change to execute sample

outputFolder = 'C:\\' ###CHANGE if needed

pdfFileName = 'InsertNameHere.pdf' ###CHANGE if needed

 

#Reference the current project, MUST be run in the ArcGIS Pro application

p = arcpy.mp.ArcGISProject('current')

 

#Reference the appropriate Map frames, Maps, Layers, and Layout

m = p.listMaps('MapNameHere')[0] ###CHANGE if needed

lyt = p.listLayouts("MapLayoutNameHere")[0] ###CHANGE if needed

df1 = lyt.listElements("MAPFRAME_ELEMENT","MapFrameNameHere 01")[0] ###CHANGE if needed

df2 = lyt.listElements("MAPFRAME_ELEMENT","MapFrameNameHere 02")[0] ###CHANGE if needed

lyr = m.listLayers("IndexLayerNameHere")[0] ###CHANGE if needed

 

####################

 

features = {row[0]:[row[1], row[2], row[3]] for row in arcpy.da.SearchCursor

(lyr,['Id', 'SHAPE@','Scale','Name'])}

 

#####################

 

#References the active map series

ms = lyt.mapSeries

 

#Create a new PDF that pages will be added into

#First remove the file if it already exists

if os.path.exists(os.path.join(outputFolder, pdfFileName)):

os.remove(os.path.join(outputFolder, pdfFileName))

pdf = arcpy.mp.PDFDocumentCreate(os.path.join(outputFolder, time.strftime("%Y%m%d") + pdfFileName))

 

 

 

 

#Iterate through the MapSeries

if ms.enabled:

#This part itertates on the first map frame (Odd Numbers only)

for pageNum in range(1,ms.pageCount,2):

ms.currentPageNumber = pageNum

 

#This part is supposed to iterate through the maps series on the second map frame (Even Numbers Only)

df2.camera.setExtent(df2.getLayerExtent(lyr, False, True))

#Export each page and append into the new PDF document

print('Exporting and appending: ' + pageName)

lyt.exportToPDF(os.path.join(outputFolder, pageName + '.pdf'))

pdf.appendPages(os.path.join(outputFolder, pageName + '.pdf'))

#Remove the single, exported page after appended into final PDF

os.remove(os.path.join(outputFolder, pageName + '.pdf'))

#Complete the creation of the PDF and commit to file

pdf.saveAndClose()

 

\```

DavidSolari
MVP Regular Contributor

Good work digging that post up, I always forget that arcpy has a decent PDF toolkit inside. Unfortunately, as I was tidying up the code it looks like it's unfinished. My assumption is the author wanted to grab the next odd page of the map series, index into the matching even page to get the geometry of the index and set the second frame to that extent. Here's what that looks like when finished:

 

# Purpose: This script is designed to show 2 pages from a Map Series on
# one Layout. The first map frame runs through the odd numbered
# pages in the series, while the second frame runs through the even
# numbered pages.It then combines all pages into a single, multipage PDF. 

import arcpy, os 

#Filepath variables are machine specific. May need to change to execute sample
output_folder = r"C:\Path\To\Folder"
pdf_file_name = "InsertNameHere.pdf"
pdf_path = os.path.join(output_folder, pdf_file_name)

#Reference the current project, MUST be run in the ArcGIS Pro application
p = arcpy.mp.ArcGISProject("current") 

#Reference the appropriate Map frames, Maps, Layers, and Layout
m = p.listMaps("All")[0]
lyt = p.listLayouts("Combo Layout")[0]
df1 = lyt.listElements("MAPFRAME_ELEMENT", "Left Frame")[0]
df2 = lyt.listElements("MAPFRAME_ELEMENT", "Right Frame")[0]
lyr = m.listLayers("index")[0]

# Lookup of index extents and page numbers
features = {row[0]: row[1:] for row in arcpy.da.SearchCursor(lyr, ["idx", "page_count", "SHAPE@"])}

# Get map series
ms = lyt.mapSeries
if not ms.enabled:
    arcpy.AddError("Cannot export layout without an active map series.")
    raise SystemExit(1)

#Create a new PDF that pages will be added into
#First remove the file if it already exists
if os.path.exists(pdf_path):
    os.remove(pdf_path)
pdf = arcpy.mp.PDFDocumentCreate(pdf_path)

# Iterate odd pages, set matching map frame to matching even page, export and append
for page_num in range(1, ms.pageCount, 2):
    ms.currentPageNumber = page_num    
    if page_num in features:  # Assume page_num is always idx + 1
        next_count, next_shp = features[page_num]
        df2.camera.setExtent(next_shp.extent)
    else:
        df2.camera.setExtent(df1.camera.getExtent())
    page_name = os.path.join(output_folder, f"{page_num}.pdf")
    lyt.exportToPDF(page_name)
    pdf.appendPages(page_name)
    os.remove(page_name)

pdf.saveAndClose()

 

This runs into issues if you want to add page numbers but the output I've attached is a good first start. Certainly easier than learning another Python library.

0 Kudos
ThomasHoman
Frequent Contributor

If you polish the ArcGIS Pro Roadmap and peer intently https://community.esri.com/t5/arcgis-pro-documents/arcgis-pro-roadmap-november-2024/ta-p/1558302 the third item in the near term might meet your need - Customize Layer Visibility per Map Frame. So I would guess Pro 3.5, 3.6 or whatever they move the numbering to. 

Until then @DavidSolari 's method might be your best route.

 

Regards,

Tom

0 Kudos
LindaGreen
Occasional Contributor

It'd be clunky and a pain to update, but could you set up a map that's just your second map frame, export those (every other page, I guess) as images, and and then attach the images in a layout that's driven by your first map frame/shows the odd pages?

I've only ever heard this is possible, never tried it myself, but this sounds like what I heard about.

0 Kudos