How to enable map series using python in ArcGIS Pro?

2924
11
Jump to solution
02-26-2019 06:25 AM
AaronLaver
New Contributor II

Hi there, please bear with me as this is my first post and I'm relatively new to Python.

I'm currently constructing a tool which would create and export a map series. So far I've been able to create a strip map index, import a layout, and even export the series to PDF -- but only after I manually enable the mapseries from arcgis pro. How do I go about authoring the map series using python?

Thanks in advance if you're able to help with this. Code can be found below.

#    All of this code works

import arcpy
arcpy.env.workspace = r"somepath"
prodoc = arcpy.mp.ArcGISProject("CURRENT")
prodocmap = prodoc.listMaps("Map")[0]
feature_selection = arcpy.CopyFeatures_management("test_line", r"memory\erased")
scale = 24000 
horiz_line_buffer = "8.5 inches" 
vert_line_buffer = "5.5 inches"
strip_map = arcpy.StripMapIndexFeatures_cartography (feature_selection, "grid1", "USEPAGEUNIT", scale, horiz_line_buffer, vert_line_buffer, "HORIZONTAL", 0, "", "WE_NS")
arcpy.Delete_management ("erased")
prodoc.importDocument(r"layoutpath.pagx")
import arcpy
import os
import sys
relpath = os.path.dirname(sys.argv[0])
p = arcpy.mp.ArcGISProject("CURRENT")
l = p.listLayouts()[0]
mf = l.listElements("MAPFRAME_ELEMENT")[0]
first_map = p.listMaps()[0]

#    Need to inject mapSeries enable or similar here, can't get it to work




#    export mapseries as PDF - This Works
if not l.mapSeries is None:
  ms = l.mapSeries
  if ms.enabled:
    ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE", 150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
0 Kudos
1 Solution

Accepted Solutions
JeffBarrette
Esri Regular Contributor

I want to clarify terms:  "Create " or "Author" a map series vs "Enable" a map series.  The arcpy.mp API allows you to enable or disable an already existing map series.  

If a layout does NOT already have an existing map series, you can NOT create one.  You must use the UI to author the map series.

Since the beginning the arcpy.mapping/mp API was mostly designed to automate existing objects to avoid the complexities of providing an API that can author everything from scratch.  We do have plans to provide creation capabilities in the future but need to focus on arcpy.mapping equivalency first.

Jeff - arcpy.mp team

View solution in original post

11 Replies
MitchHolley1
MVP Regular Contributor

First, are you getting any errors?

I think you're simply checking to see if the map series is enabled (line 31) instead of enabling MapSeries if the layout does not already have it enabled.

Replace the lines 28 - 32 in your existing code with the snippet below and see if you get any results.

#export mapseries as PDF - This Works
if not l.mapSeries is None:
  ms = l.mapSeries
  if ms.enabled:
    ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE",      150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
  else:
    ms.enabled = True
    ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE", 150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
AaronLaver
New Contributor II

Thanks for your response, Mitch. When I run my original script in its entirety, I don't receive any errors, but nothing happens with regard to the mapseries script (I'm assuming because the "if not" statement didn't have an "else" statement following it). 

Running your lines of code produces the same result -- the script still seems to hit a dead end and l.mapSeries still equates to "None" (generated in the Python window) 

if not l.mapSeries is None:
	ms = l.mapSeries
	if ms.enabled:
		ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE",      150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
	else:
		ms.enabled = True
		ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE", 150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
print(l.mapSeries)
None‍‍‍‍‍‍‍‍‍

I also tried altering indentation so the "else" statement aligns with the "if not", which does generate the following traceback error (see below): 

if not l.mapSeries is None:
	ms = l.mapSeries
	if ms.enabled:
		ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE",      150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)
else:
	ms.enabled = True
	ms.exportToPDF(r"C:\EsriPress\Ex3_SelectedFeatures.pdf", "ALL", "", "PDF_SINGLE_FILE", 150, "BEST", True, "ADAPTIVE", True, "LAYERS_ONLY", True, 80, True, False)

Traceback (most recent call last):
  File "<string>", line 6, in <module>
AttributeError: 'NoneType' object has no attribute 'enabled'‍‍‍‍‍‍‍‍‍‍‍

So is the hangup here that we need syntax not only to enable the mapseries, but also to inject any required properties? For example, the ArcGIS Pro tool dialogue insinuates that the map frame, layer, name field, sort field are all required. 

Thoughts?

0 Kudos
MitchHolley1
MVP Regular Contributor

Aaron,

Perhaps the some code is broken prior to exporting the map series.  I have quickly written the code below to test the functionality of the MapSeries module, and it seems to be working okay.  This was completed without any errors and with a proper output.

import arcpy

datasource = r'path/to/aprx.aprx'

aprx = arcpy.mp.ArcGISProject(datasource)

l = aprx.listLayouts()[0]

if l.mapSeries.enabled is True:
    print ("Printing map series for layout: {}".format(l.name))
    ms = l.mapSeries
    ms.exportToPDF(r'desktop\path\MapSeries_Test.pdf',"ALL",
                   "",
                   "PDF_SINGLE_FILE",
                   150,
                   "BEST",
                   True,
                   "ADAPTIVE",
                   True,
                   "LAYERS_ONLY",
                   True,
                   80,
                   True,
                   False)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This was run with Python 3.6.6 with ArcGIS Pro 2.3.

AaronLaver
New Contributor II

Ugh, I'm not sure what the hangup is. The syntax above works, but similarly to the previous examples it only works if I manually enable the map series from the ArcGIS Pro UI first. I'm using the same python and ArcGIS Pro versions that you stated. 

Looks like I have some troubleshooting to do. Thanks for your help, if you have any other insights I'm all ears. In the meantime I'll try to work a solution and post if I find one.

****UPDATE****

I was not able to resolve this issue using Python, but I was able to workaround it by enabling the Layout Map Series using the ArcGIS Pro interface prior to running any scripts. Saving the Layout with MapSeries enabled carried over to the import process used within the script. This worked every time I ran it across multiple sessions and using multiple projects. I'm hoping to find a way to manually write the "enabled" property in the future, though. 

RoryMcPherson__Stantec_
New Contributor II

I'm trying to do the exact same thing, and can't figure it out either. I've tried the solutions offered above, but none of them actually 'enabled' a map series. Querying my layout.mapSeries just returns a None value.

I'm running a script to automate map production that adds shapefiles drawn by the user to the map. If the extent of the shapefile area is small (less than 1:500) it simply exports a single PDF. However, if the shapefile area is large, I want to create and export a map series (all maps need to be at 1:500 scale).

I have not enabled the Map Series on the project before running any scripts because, from my understanding, enabling the map series requires an index layer. In my case, I'm not creating this layer until my script has already run (adds the user's shapefile halfway through), so I have nothing to choose from for this required layer if that makes sense.

Would love to hear how anyone else has resolved this.

0 Kudos
AaronLaver
New Contributor II

Hi Rory,

I have unmarked the "Correct" answer as I'm still seeking a python-only option. I have had success getting the workaround to function, but only using very specific naming mechanisms. 

No updates as of yet, but I just wanted to let you know that I'm still in the weeds on this one and will post once I find a more robust solution. Or even better, hopefully someone who knows more about what they're doing than I do posts a solution!

0 Kudos
RoryMcPherson__Stantec_
New Contributor II

Thanks for the update Aaron.

In the meantime I found a different workaround solution. Instead of creating a map series I am creating a grid index feature from my input feature layer, then using arcpy.da.SearchCursor to go through each row in the grid index. With each row selected I then reset the camera extent and scale, and export a map of that grid index area under a unique name.

In turn, this means I had to write a bit of code for walking my directory and appending all the maps (pdfs) together, but this solution works fine for what I need!

AaronLaver
New Contributor II

Thanks, Rory. Good to have this in my back pocket.

0 Kudos
JeffBarrette
Esri Regular Contributor

I want to clarify terms:  "Create " or "Author" a map series vs "Enable" a map series.  The arcpy.mp API allows you to enable or disable an already existing map series.  

If a layout does NOT already have an existing map series, you can NOT create one.  You must use the UI to author the map series.

Since the beginning the arcpy.mapping/mp API was mostly designed to automate existing objects to avoid the complexities of providing an API that can author everything from scratch.  We do have plans to provide creation capabilities in the future but need to focus on arcpy.mapping equivalency first.

Jeff - arcpy.mp team