I'm trying to export selected pages from a map series (by manually selecting/highlighting them in the Contents pane, or using a SQL query on the index layer) to PDF using Python. The MapSeries Documentation mentions parameters {page_range_type}, {page_range_string}, and {multiple_files} that sound like exactly what I need, but the code examples on that same page don't utilize those parameters. They instead use loops, which would be unnecessary if the above parameters actually worked(?). When using the interactive Python window in Pro, the code completion also does not utilize them. Attempting to use them just throws an error. Am I missing the proper context for these parameters? Are they not implemented (yet)? Please advise. Thanks!
Edit: sorry, I was using the wrong terminology. It is parameters for the exportToPDF method that are missing. I changed all use of the word method to parameter.
Solved! Go to Solution.
Hello Jeff. We unfortunately don't have samples for all possible parameter combinations but this would be a good one.
Here is a snippet that I just recently used for a project I was working on:
map_series = layout.mapSeries
if map_series.enabled:
output = os.path.join(policy_folder, layout_name + ".pdf")
indexLyr = map_series.indexLayer
where_clause = f"{policy_field} = {policy_number}"
arcpy.SelectLayerByAttribute_management(in_layer_or_view=indexLyr,
selection_type="NEW_SELECTION",
where_clause=where_clause)
map_series.exportToPDF(out_pdf=output,
page_range_type="SELECTED",
resolution=300)
I hope this helps you,
Jeff - arcpy.mp and Layout teams
You will have to provide sample lines Jeff for what you have tried. There are some which are obvious and some that aren't (ie the string format for multiple_files)
Since I barely know what I'm doing with Python 😀, I've only tried to write code that is very similar to the examples. I was attempting to write a cross between example 2 (which writes each page to a separate PDF) and example 3 (which exports selected pages):
import arcpy, os, sys
PDFpath = 'V:\\projects\\DevSvcs\\Planning\\HistoricDistrict\\HPC\\'
aprx = arcpy.mp.ArcGISProject('CURRENT')
HPCcase = aprx.listLayouts('HPC Case Layout')[0]
relpath = os.path.dirname(sys.argv[0])
if not HPCcase.mapSeries is None:
ms = HPCcase.mapSeries
if ms.enabled:
ms = HPCcase.mapSeries
indexLyr = ms.indexLayer
arcpy.management.SelectLayerByAttribute(indexLyr, "NEW_SELECTION", "'HPCDate'= '2021-05-13'")
pageName = ms.pageRow.ConcatAddr
HPCcase.exportToPDF(os.path.join(PDFpath, "20210513", f"HPC_20210513_{pageName}.pdf"))
I have run this in the interactive Python window. It exports only the page active in the map frame, even if I have multiple pages selected/highlighted in the Contents pane. It also ignores my SQL query.
If I try to insert the {page_range_type}, {page_range_string}, and {multiple_files} parameters, I get an error that the value for the image_quality parameter — the parameter that should come next if you ignore the page_range parameters — isn't valid:
if not HPCcase.mapSeries is None:
ms = HPCcase.mapSeries
if ms.enabled:
ms = HPCcase.mapSeries
indexLyr = ms.indexLayer
arcpy.management.SelectLayerByAttribute(indexLyr, "NEW_SELECTION")
pageName = ms.pageRow.ConcatAddr
HPCcase.exportToPDF(os.path.join(PDFpath, "20210513", f"HPC_20210513_{pageName}.pdf"),'SELECTED','','PDF_MULTIPLE_FILES_PAGE_NAME',300, 'BEST','True', 'ADAPTIVE','True', 'LAYERS_ONLY','True',80,'False','False','False','True')
<Result 'Sites'>
Traceback (most recent call last):
File "<string>", line 8, in <module>
File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\utils.py", line 163, in fn_
arg_name].keys())))
ValueError: Invalid value for image_quality: '' (choices are: ['BEST', 'BETTER', 'NORMAL', 'FASTER', 'FASTEST'])
Hello Jeff. We unfortunately don't have samples for all possible parameter combinations but this would be a good one.
Here is a snippet that I just recently used for a project I was working on:
map_series = layout.mapSeries
if map_series.enabled:
output = os.path.join(policy_folder, layout_name + ".pdf")
indexLyr = map_series.indexLayer
where_clause = f"{policy_field} = {policy_number}"
arcpy.SelectLayerByAttribute_management(in_layer_or_view=indexLyr,
selection_type="NEW_SELECTION",
where_clause=where_clause)
map_series.exportToPDF(out_pdf=output,
page_range_type="SELECTED",
resolution=300)
I hope this helps you,
Jeff - arcpy.mp and Layout teams
From MapSeries—ArcGIS Pro | Documentation
lets break down some of the required and optional parameters. If you are starting out, you can provide the parameter name and the value as shown below.... You don't need to if you never need to go back and figure out what your variables are or never need to document what you have done (hence
snip ......
exportToPDF (
out_pdf = (os.path.join(PDFpath, "20210513", f"HPC_20210513_{pageName}.pdf"),
page_range_type = 'SELECTED',
page_range_string = "",
multiple_files = 'PDF_MULTIPLE_FILES_PAGE_NAME' ,
resolution = 300,
image_quality = "BEST",
compress_vector_graphics = True, ******** not 'True'
etc.
booleans are True or False
strings would be "True" or "False
Thank you, @JeffBarrette and @DanPatterson.
I'm realizing a few good nuggets of information from your responses.
A few outstanding questions: Why are the page_range parameters not included in the full, non-named parameter array for the method? Are there other (hidden) parameters? Is it common to have additional parameters that can only be called by name?
Thanks!
Jeff,
There are no hidden parameters in Python. The autocomplete should should you the full list of parameter names and their order. What makes this function a little unique is that you won't always specify all parameters in their order because some are conditional. For example page_range_string is ONLY evaluated IF page_range_type is set to RANGE. This is documented in the help but I certainly understand your confusion. I'm happy to see you got it figured out. I realized after that example 3 is very similar to the code I sent you.
Jeff - arcpy.mp and Layout teams
I'm trying to actually implement the knowledge this morning I got from this thread yesterday. I'm getting an error when I try to run my script. I can't figure out what I've done wrong.
import arcpy, os, sys
aprx = arcpy.mp.ArcGISProject('CURRENT')
HPCcase = aprx.listLayouts('HPC Case Layout')[0]
ms = HPCcase.mapSeries
if ms.enabled:
ms = HPCcase.mapSeries
indexLyr = ms.indexLayer
PDFpath = 'V:\\projects\\DevSvcs\\Planning\\HistoricDistrict\\HPC\\'
HPCdate = '20210513'
arcpy.management.SelectLayerByAttribute(in_layer_or_view=indexLyr,
selection_type="NEW_SELECTION",
where_clause=f"'HPCDate'='2021-05-13'")
pageName = ms.pageRow.ConcatAddr
HPCcase.exportToPDF(out_pdf=os.path.join(PDFpath, HPCdate, f"HPC_{HPCdate}_{pageName}.pdf"),
page_range_type="SELECTED",
multiple_files="PDF_MULTIPLE_FILES_PAGE_NAME",
resolution=300)
Traceback (most recent call last):
File "<string>", line 19, in <module>
File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\utils.py", line 191, in fn_
return fn(*args, **kw)
TypeError: exportToPDF() got an unexpected keyword argument 'page_range_type'
In addition to the export error, I'm pretty sure nothing is getting selected in my index layer. Since a date is the selecting criterion, it's an additional syntax hurdle to make sure I'm doing it exactly right. When I create the features, I only care about the date, not the time. (Time should always be 00:00:00, but I'd rather it not be a factor just in case.)
Also, I want to make sure I understand how the selected page range works for exporting in Python. Does it only work by selecting index features also in Python? Is it possible to select one or more pages manually in the Contents pane, then export with Python without further specifying a selection?
Thanks!
Jeff, I see two mistakes.
1) your where clause is forcing single quotes around the field name. I don't think you want them. A simple way to validate your where clause is to try to build the same query via the Definition Query interface. Build the query you want there and click the SQL button to see the correct formatting. Then use print statements in your code to make sure the query is correct.
2) You are exporting the LAYOUT object, NOT the MS object. The layout does NOT support page_range_type, the MS object does.
Jeff - arcpy.mp and Layout teams