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
ArcGIS provides support for printing web maps from the ArcGIS web APIs. 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. For instance, properties of the service sublayers are transferred to the sublayers of the map service in the document. The map document can then be further modified before finally being printed or exported to a common format such as PDF.
The ConvertWebMapToMapDocument function is primarily intended for workflows where the web map needs to be modified using arcpy.mapping functions. It is useful for exporting a web map at different resolutions or printing to different page sizes which are options not available with the Export Web Map geoprocessing tool. Some example workflows that can be met using the ConvertWebMapToMapDocument function are as follows:
- Swapping out a service layer for local data—In arcpy.mapping scripts, service layers can be identified by name and swapped out for layers that point to local data. This is commonly desired when a vector output is wanted instead of service layers. One way to accomplish this 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 WebMap JSON.
- Exporting to a PDF and inserting into a set of other PDFs for a complete map book—The output map document can be exported as a PDF, then inserted into other PDFs using the PDFDocument class.
- Exporting and printing high-resolution and large-format maps—The arcpy.mapping export functions support exporting to a variety of sizes and resolutions including large-format exports at high DPIs (for example, greater than 600 DPI). The web map's notes overlays will also be supported in the high-resolution, large-format map output.
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 which will point to the REST url of the geoprocessing service that you created. For more information on using the ArcGIS web APIs, consult the help for your preferred developer platform at http://resources.arcgis.com/content/web/web-apis. For more information on geoprocessing services, see:
When using ConvertWebMapToMapDocument in a geoprocessing service in the ArcGIS web APIs, the parameter names of the script tool must match the web APIs 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. See the ExportWebMap specification to understand how this text should be formatted. The ArcGIS web APIs (for JavaScript, Flex, Silverlight, and so on) allow developers to easily get this JSON string from the map. |
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. For example:
|
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, scale bar, and so forth). |
![Tip Tip](rsrc/tip.png)
Any number of additional user-defined parameters can also be added. The ability to pass extra parameters into a custom print task is usefull as it allows you to collect any number of extra paramaters from the web application and pass it 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's 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 the 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 in order 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"}
![Tip Tip](rsrc/tip.png)
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, then republished to the server. Therefore, it is good practice to ensure that 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.
![Tip Tip](rsrc/tip.png)
As mentioned before, the JSON string that is 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 get updated with the titleText value. For more information, see the layoutOptions section in the 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:
When authoring template map documents in the registered folder, it is best practise 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.
![Caution Caution](rsrc/caution.png)
When using ConvertWebMapToMapDocument, relative paths to layers must be pointing to data at, below, or one level above the path of the template_mxd.
![Caution Caution](rsrc/caution.png)
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 pre-authored templates that ship with the software. They are located at <install_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 3 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.
Also see the overview of the Printing toolset for small format printing (for example, 8.5 by 11). This toolset contains the Export Web Map geoprocessing tool. A task that uses this tool is installed with ArcGIS for Server and can be started for use. Export Web Map also supports notes overlays.
Be sure to read the following tutorials. They demonstrate the entire high-quality printing/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 Specifications for more information. | 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'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 lets you 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:
(The default value is None) | Dictionary |
Data Type | Explanation |
tuple |
Returns a Python named Tuple of web map and request properties:
![]() ConvertWebMapToMapDocument will create temporary map documents (.mxds) 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, an output format, and a template map document. The output map document is then exported to either PDF or PNG.
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')
# Convert the web map 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 = '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, the script reads in a web map JSON, a template map document, and existing PDF Documents that the web map will be appended to. The output map document from the ConvertWebMapToMapDocument function is exported as a PDF, then inserted into other PDFs 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 Consolidate Map 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.
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 mutli-page 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)