ConvertWebMapToMapDocument (arcpy.mapping)
Summary
Converts a web map (in JSON format) that you intend to print or export to a map document. The map document can be further modified before finally being printed or exported.
Discussion
The ConvertWebMapToMapDocument function will convert a web map that you intend to print or export to a map document. Once the document is converted, the full state of the web map exists in the map document. The map document can then be further modified before finally being printed or exported to a common format such as PDF. ConvertWebMapToMapDocument would most commonly be used when printing a map from a web application using the ArcGIS Web APIs.
The ConvertWebMapToMapDocument function is primarily intended for workflows where the web map needs to be modified or exported using arcpy.mapping functions. Some example workflows that can be met using the ConvertWebMapToMapDocument function are as follows:
- Swapping out service layers for local vector data—In arcpy.mapping scripts, service layers can be identified and swapped out for layers that point to local data. This is commonly desired when a vector output is wanted instead of service layers. For example, vector PDF output supports the following in PDF viewing applications: toggling layer visibility, viewing of feature attributes, and viewing of map coordinates. One way to accomplish swapping service layers for vector data would be to stage template map documents that contain vector equivalents of all the possible service layers. After executing the ConvertWebMapToMapDocument function, loop through all the layers in the output map document, removing all layers except the vector layers that correspond to the service layers in the web map. This workflow would be used when swapping your own services with the corresponding vector data that you already have.
- Creating map books—A map series can be generated if Data Driven Pages is enabled on the template_mxd. Moreover, the output map document can be exported as a PDF and inserted into other PDFs using the PDFDocument class to create a complete map book.
- Exporting using advanced options—All of the arcpy.mapping export functions have many advanced options. For example, the ExportToPDF function has parameters for controlling raster and vector compression, defining colorspace, embedding fonts, and so on.
- Controlling the appearance of the legend—The arcpy.mapping module provides the ability to remove legend items or modify their style items with custom settings using the LegendElement class and ListStyleItems function.
ArcGIS for Server also includes a geoprocessing service named PrintingTools. The PrintingTools service can be used in a web application to generate a high-cartographic-quality printable image. For more information regarding the PrintingTools service, see the following:
Once you have a Python script that prepares the map for printing, you can encapsulate it in a geoprocessing script tool. You can then publish the script tool as an ArcGIS Server geoprocessing service. Each ArcGIS Web API has a Print Task that you can use in your web applications. The Print Task has a URL property that will point to the REST URL of the geoprocessing service you created. For more information on using the ArcGIS Web APIs, consult the help for your preferred developer platform.
For more information on geoprocessing services, see the following:
When using ConvertWebMapToMapDocument in a geoprocessing service in the ArcGIS Web APIs, the parameter names of the script tool must match the ArcGIS Web API Print Task parameters:
Parameter Name | Data Type | Explanation |
---|---|---|
Web_Map_as_JSON | String | A JSON representation of the state of the map to be exported as it appears in the web application. The ArcGIS Web APIs (JavaScript, Flex, and Silverlight) allow developers to easily get this JSON string from the web application. |
Output_File | File | Output file name. The extension of the file depends on the Format parameter. |
Format | String | The format in which the map image for printing will be delivered. The following strings are accepted:
|
Layout_Template | String | Either a name of a template from the list or the keyword MAP_ONLY. When MAP_ONLY is chosen or an empty string is passed in, the output map does not contain any page layout surroundings (for example, title, legends, and scale bar). |
Any number of additional user-defined parameters can also be added. The ability to pass extra parameters into a custom print task is useful, as it allows you to collect any number of extra parameters from the web application and pass them into the Python script.
ConvertWebMapToMapDocument would most commonly be used when printing a map from a web application. When you use the ArcGIS Web API Print Task, you don't need to create the web map JSON; the APIs take care of it for you. However, before the script can be published and used in the web APIs, it has to be run locally. Any valid web map JSON string can be used when running the script locally. A JSON string similar to what your web application will be returning may be required for your script to run successfully. See ExportWebMap specification to understand how this text should be formatted. A sample string is below:
{
"layoutOptions": {
"titleText": "Simple WebMap JSON example"
},
"operationalLayers": [
{
"url": "http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer",
"visibility": true
}
],
"exportOptions": {
"outputSize": [
1500,
1500
]
},
"mapOptions": {
"extent": {
"xmin": -13077000,
"ymin": 4031000,
"xmax": -13023000,
"ymax": 4053000
}
},
"version": "1.4"
}
When running the script tool, the JSON string can be copied and pasted into the Web_Map_as_JSON input parameter. However, the line breaks must be removed for the string to be valid input. A sample JSON string with line breaks removed is below:
{"layoutOptions": {"titleText": "Simple WebMap JSON example"},"operationalLayers": [{"url": "http://maps1.arcgisonline.com/ArcGIS/rest/services/USA_Federal_Lands/MapServer","visibility": true}],"exportOptions": {"outputSize": [1500,1500]},"mapOptions": {"extent": {"xmin": -13077000,"ymin": 4031000,"xmax": -13023000,"ymax": 4053000}},"version": "1.4"}
For publishing purposes, you can leave the Web_Map_as_JSON input parameter blank, as the ArcGIS Web APIs will provide the web map JSON in the web application. You can leave the Web_Map_as_JSON input parameter blank provided the Python script was written in such a way as to not fail with blank input. For example, the script doesn't look for web map layers by name. If the script fails on the server due to an error in the script, it will have to be fixed locally and republished to the server. Therefore, it is good practice to ensure the script works locally before publishing by testing with a valid web map JSON string or using a debug map document that contains all the elements that would be in the web map JSON.
As mentioned before, the JSON string returned from the ArcGIS Web APIs contains the full state of the web map. The layoutOptions object in the JSON string warrants extra discussion, as it will automatically update layout elements that can be staged in the template_mxd. For example, if the JSON has a titleText setting, and the template_mxd has a Title dynamic text element, the title in the template map document layout will be updated with the titleText value. For more information, see the layoutOptions section in ExportWebMap specification.
When you encapsulate the Python script that uses ConvertWebMapToMapDocument in a geoprocessing service, you need to make sure that ArcGIS for Server can see the template map documents and data used in the web application. It is best practice to use a folder that is registered with ArcGIS for Server. For more information on registering data, see the following:
When authoring template map documents in the registered folder, it is best practice to use relative paths. That way, ArcGIS for Server will be able to find the data in the registered folder relative to the location of the map documents. See Referencing data in the map for more information.
When using ConvertWebMapToMapDocument, relative paths to layers must be pointing to data at, below, or one level above the path of the template_mxd.
If you choose to not use registered folders, template map documents and data will be packaged and copied to the server. During packaging, data may be moved and re-sourced with relative paths to a folder structure that ConvertWebMapToMapDocument cannot resolve. For this reason, usage of registered folders is recommended.
In addition to creating your own template map documents, you can also use the preauthored templates that ship with the software. They are located at <installation_directory>\Templates\ExportWebMapTemplates. These templates contain map elements such as a legend, current date dynamic text, a scale bar, and scale text.
By default, notes overlays or client-side graphics from the web application will be stored in an in-memory workspace. The in-memory workspace is temporary and will be deleted when the application is closed. To make a permanent copy of the output map document that contains notes overlays, specify a notes_gdb; then use the Consolidate Map or Package Map geoprocessing tools to make a copy of the output map document. The only time you would need to specify a notes_gdb is if you plan on making a permanent copy of the output map document. See code example 2 below. If the web map does not contain notes overlays, you can use the saveACopy method from the MapDocument class to make a permanent copy of the output map document.
The arcpy.mapping module also provides methods to control the appearance of the legend in the output map document's layout. See the removeItem method on the LegendElement class to remove legend items. The advanced tutorial listed below demonstrates this workflow. See the updateItem method on the LegendElement class and the ListStyleItems method to update legend items.
Be sure to read the following tutorials. They demonstrate the entire vector printing and exporting with ConvertWebMapToMapDocument workflow: authoring the staged template map documents, authoring the Python script, creating the geoprocessing service, and creating the web application.
Syntax
Parameter | Explanation | Data Type |
webmap_json |
The web map for printing in JavaScript Object Notation (JSON). See the ExportWebMap JSON specification for more information. The ArcGIS Web APIs (JavaScript, Flex, and Silverlight) allow developers to easily get this JSON string from the web application. | String |
template_mxd | A string representing the path and file name to a map document (.mxd) to use as the template for the page layout. The contents of the web map will be inserted into the data frame that was active at the time the template_mxd was saved. Layers in the template_mxd file's active data frame (and all other data frames) will be preserved in the output mapDocument. (The default value is None) | String |
notes_gdb | A string representing the path to a new or existing file geodatabase or an existing enterprise geodatabase connection where graphic features should be written. This parameter should only be used if graphic features from the web map JSON need to be preserved permanently. In most cases, this parameter is not required, as a temporary in-memory workspace will be used to store graphic features. This parameter allows you to save graphic features to persistent storage, which is essential if you plan to use the map document for operations that require saving or loading from disk (for example, packaging or consolidating). The path must end with a .gdb or .sde extension. (The default value is None) | String |
extra_conversion_options | A dictionary of credentials for secured services. This parameter is required if the services in the web map JSON require a user name and password to view. Keys accepted in the dictionary are as follows:
An example of key value pairs is as follows:
Lists of connection files can be used when there are multiple secured services:
(The default value is None) | Dictionary |
Data Type | Explanation |
tuple |
Returns a Python named Tuple of web map and request properties:
Caution: ConvertWebMapToMapDocument will create temporary map documents (.mxd files) in the system temp folder. On Windows Vista and 7, this is located at C:\Users\<user name>\AppData\Local\Temp. It is the user's responsibility to manage the map documents in this folder. To delete these temporary map documents in scripts, see the clean up section in the code samples below. |
Code Sample
In this example, the script reads in a web map JSON, a template map document, and existing PDF documents to which the web map will be appended. The output map document from the ConvertWebMapToMapDocument function is exported as a PDF and inserted into other PDF files using the PDFDocument class.
import arcpy
import os
import uuid
# The template location in the server data store
templatePath = '//MyMachine/MyDataStore/WebMap'
# Input WebMap json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Input Layout template
Layout_Template = arcpy.GetParameterAsText(1)
if Layout_Template == '#' or not Layout_Template:
Layout_Template = "Landscape11x17"
# PDF Title Page
PDF_Title = arcpy.GetParameterAsText(2)
if PDF_Title == '#' or not PDF_Title:
PDF_Title = "TitlePage.PDF"
# PDF End Page
PDF_End = arcpy.GetParameterAsText(3)
if PDF_End == '#' or not PDF_End:
PDF_End = "ContactInfo.PDF"
# Get the requested map document
templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
# Get the requested PDF files
PDF_Title_File = os.path.join(templatePath, PDF_Title)
PDF_End_File = os.path.join(templatePath, PDF_End)
# Convert the WebMap to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON,
templateMxd)
mxd = result.mapDocument
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
WebMapPDF = os.path.join(arcpy.env.scratchFolder,
'WebMap_{}.pdf'.format(str(uuid.uuid1())))
# Export the WebMap to PDF
arcpy.mapping.ExportToPDF(mxd, WebMapPDF)
# Create a new "master" output PDF Document
# Append Title, WebMap and End PDFs to it
Output_Name = os.path.join(arcpy.env.scratchFolder,
'OutputWithWebMap_{}.pdf'.format(str(uuid.uuid1())))
pdfDoc = arcpy.mapping.PDFDocumentCreate(Output_Name)
pdfDoc.appendPages(PDF_Title_File)
pdfDoc.appendPages(WebMapPDF)
pdfDoc.appendPages(PDF_End_File)
pdfDoc.saveAndClose()
# Set the output parameter to be the output PDF
arcpy.SetParameterAsText(4, Output_Name)
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)
In this example, the ConsolidateMap geoprocessing tool is used to make a permanent copy of the output map document, including the notes overlays.
import arcpy
import os
import uuid
# The template location in the registered folder
templatePath = '//MyMachine/Austin/WebMap'
# Input web map json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Format for output
Format = arcpy.GetParameterAsText(1)
if Format == '#' or not Format:
Format = "PDF"
# Input Layout template
Layout_Template = arcpy.GetParameterAsText(2)
if Layout_Template == '#' or not Layout_Template:
Layout_Template = "Landscape11x17"
# Get the requested map document
templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
# Since we are making a permanent copy of the notes overlays,
# we need to specify a notes geodatabase
notes = os.path.join(arcpy.env.scratchFolder, 'mynotes.gdb')
# Convert the web map to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd, notes)
mxd = result.mapDocument
# Save the web map and notes overlays to a new map document using ConsolidateMap
arcpy.ConsolidateMap_management(mxd.filePath,
os.path.join(arcpy.env.scratchFolder, 'ConsolidateWebMap'))
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)
In this example, a staged template map document is used that contains vector equivalents of all the possible service layers. After executing the ConvertWebMapToMapDocument function, the script loops through all the layers in the output map document, removing all layers except the vector layers that correspond to the service layers in the web map JSON. The output map document layout is then exported to either PDF or PNG.
import arcpy
import os
import uuid
# The template location in the registered folder
templatePath = '//MyComputerName/MyDataStore/USA'
# Input web map json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Format for output
Format = arcpy.GetParameterAsText(1)
if Format == '#' or not Format:
Format = "PDF"
# Input Layout template
Layout_Template = arcpy.GetParameterAsText(2)
if Layout_Template == '#' or not Layout_Template:
Layout_Template = "NorthwesternUSA"
# Get the requested map document
templateMxd = os.path.join(templatePath, Layout_Template + '.mxd')
# Convert the web map to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
mxd = result.mapDocument
# Reference the data frame that contains the web map
# Note: ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap"
df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
# Get a list of all service layer names in the map
serviceLayersNames = [slyr.name for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df)
if slyr.isServiceLayer and slyr.visible and not slyr.isGroupLayer]
# Create a list of all possible vector layer names in the map that could have a
# corresponding service layer
vectorLayersNames = [vlyr.name for vlyr in arcpy.mapping.ListLayers(mxd, data_frame=df)
if not vlyr.isServiceLayer and not vlyr.isGroupLayer]
# Get a list of all vector layers that don't have a corresponding service layer
removeLayerNameList = [vlyrName for vlyrName in vectorLayersNames
if vlyrName not in serviceLayersNames]
# Remove all vector layers that don't have a corresponding service layer
for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if not lyr.isGroupLayer \
and not lyr.isServiceLayer \
and lyr.name in removeLayerNameList \
and lyr.name in vectorLayersNames:
arcpy.mapping.RemoveLayer(df, lyr)
# Remove all service layers
# This will leave only vector layers that had corresponding service layers
for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if slyr.isServiceLayer:
arcpy.mapping.RemoveLayer(df, slyr)
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
output = 'WebMap_{}.{}'.format(str(uuid.uuid1()), Format)
Output_File = os.path.join(arcpy.env.scratchFolder, output)
# Export the web map
if Format.lower() == 'pdf':
arcpy.mapping.ExportToPDF(mxd, Output_File)
elif Format.lower() == 'png':
arcpy.mapping.ExportToPNG(mxd, Output_File)
# Set the output parameter to be the output file of the server job
arcpy.SetParameterAsText(3, Output_File)
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)
In this example, a staged template map document is used that contains vector equivalents of all the possible service layers. After executing the ConvertWebMapToMapDocument function, the script loops through all the layers in the output map document, removing all layers except the vector layers that correspond to the service layers in the web map JSON. The data view of the output map document is then exported to PNG using the DPI, output height, and output width values returned from the ConvertWebMapToMapDocument function, as specified in the web app.
import arcpy
import os
import uuid
# Input web map json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# The template location in the registered folder
templatePath = '//MyComputerName/MyDataStore/FederalLands'
# Get the template map document
templateMxd = os.path.join(templatePath, 'FederalLands.mxd')
# Convert the web map to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON, templateMxd)
mxd = result.mapDocument
# Reference the data frame that contains the web map
# Note: ConvertWebMapToMapDocument renames the active dataframe in the template_mxd to "Webmap"
df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
# Get a list of all service layer names in the map
serviceLayersNames = [slyr.name for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df)
if slyr.isServiceLayer and slyr.visible and not slyr.isGroupLayer]
# Create a list of all possible vector layer names in the map that could have a
# corresponding service layer
vectorLayersNames = [vlyr.name for vlyr in arcpy.mapping.ListLayers(mxd, data_frame=df)
if not vlyr.isServiceLayer and not vlyr.isGroupLayer]
# Get a list of all vector layers that don't have a corresponding service layer
removeLayerNameList = [vlyrName for vlyrName in vectorLayersNames
if vlyrName not in serviceLayersNames]
# Remove all vector layers that don't have a corresponding service layer
for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if not lyr.isGroupLayer \
and not lyr.isServiceLayer \
and lyr.name in removeLayerNameList \
and lyr.name in vectorLayersNames:
arcpy.mapping.RemoveLayer(df, lyr)
# Remove all service layers
# This will leave only vector layers that had corresponding service layers
for slyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if slyr.isServiceLayer:
arcpy.mapping.RemoveLayer(df, slyr)
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
output = 'WebMap_{}.png'.format(str(uuid.uuid1()))
Output_File = os.path.join(arcpy.env.scratchFolder, output)
# Export the web map
arcpy.mapping.ExportToPNG(mxd, Output_File, df, result.outputSizeWidth,
result.outputSizeHeight, result.DPI)
# Set the output parameter to be the output file of the server job
arcpy.SetParameterAsText(1, Output_File)
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)
In this example, the user supplies a page range that corresponds to the Data Driven Pages enabled in the template map document. The page range is then exported to a multipage PDF document.
import arcpy
import os
import uuid
# The template location in the registered folder
templatePath = '//MyComputerName/MyDataStore/WebMap'
# Input WebMap json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# Data Driven Page numbers as comma delimited string
DDP_Pages = arcpy.GetParameterAsText(1)
if DDP_Pages == '#' or not DDP_Pages:
DDP_Pages = "1, 3, 10-13"
# Get the template map document
templateMxd = os.path.join(templatePath, 'DDP.mxd')
# Convert the WebMap to a map document
result = arcpy.mapping.ConvertWebMapToMapDocument(Web_Map_as_JSON,
templateMxd)
mxd = result.mapDocument
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
Output_Name = os.path.join(arcpy.env.scratchFolder,
'WebMap_{}.pdf'.format(str(uuid.uuid1())))
# Export the WebMap Data Driven Pages to PDF
mxd.dataDrivenPages.exportToPDF(Output_Name, "RANGE", DDP_Pages)
# Set the output parameter to be the output PDF
arcpy.SetParameterAsText(2, Output_Name)
# Clean up - delete the map document reference
filePath = mxd.filePath
del mxd, result
os.remove(filePath)