In this tutorial, you'll build a web GIS application, where the end user can navigate to an area of interest and click a Print button. The output will be a printer-friendly PDF document containing vector output for service layers.
Exporting from a web application using the out-of-the-box PrintingTools service and its client print widget in ArcGIS API for JavaScript can output a high-quality image of your service layers. However, you may want vector output. For example, vector PDF output supports the following in PDF viewing applications: switching layer visibility, viewing feature attributes, and viewing map coordinates. In the web application that you'll build, you'll output vector equivalents of the World Topographic basemap service. A vector subset of a small area of the World Topographic basemap service is publically available.
Note:
To generate an output document containing local vector data instead of an image of your service layers, you must have access to the corresponding vector data.
The illustration below shows the web application you'll build.
The code behind the Print button in the web application uses the ArcGIS API for JavaScript Print Task, which is available with ArcGIS 10.1 for Server and later. You'll create a Python script that will be published as a geoprocessing service that the Print Task will use. The Python script uses the ConvertWebMapToMapDocument function in the arcpy.mapping module, which will insert the full state of the web map into a staged template map document. The template contains vector equivalents of all the possible layers in the map service. The arcpy.mapping module also provides functionality to remove service layers—leaving local vector data that was staged in the template map document—and export to a PDF document.
The output will be a printer-friendly PDF document containing local vector data instead of an image of service layers.
To complete this tutorial, you should be familiar with the arcpy.mapping module, ArcGIS API for JavaScript, ArcGIS Desktop, and ArcGIS Server. You should also become familiar with printing in web applications. The following topics are helpful:
Obtain the vector data
Download a compressed file that contains the vector data used in the staged map document template. Before you do that, you need to make sure that a folder structure exists where ArcGIS Server can locate the template map document and data that will be used in the web application. It is assumed that you have a folder that's registered with ArcGIS Server. For more information on registering data with ArcGIS Server, see the following:
- Make your data accessible to ArcGIS Server
- About registering your data with ArcGIS Server
- Register your data with ArcGIS Server using ArcMap
Tip:
When using template map documents in the ConvertWebMapToMapDocument function, the best practice is to use data registered with ArcGIS Server. If you choose to use unregistered data, template map documents and data will be packaged and copied to the server. During packaging, data may be moved and resourced with relative paths to a folder structure that ConvertWebMapToMapDocument cannot resolve. For more information, see ConvertWebMapToMapDocument.
- Open a new, empty ArcMap session.
- In the Catalog window, browse to your registered folder.
- Create a new folder in the registered folder named BasicTutorial.
- In a web browser, go to the World Topographic Map Template download.
- Download the World Topographic Map Template compressed file to your computer by clicking the Open > Download buttons.
- When prompted, select Save as and save the compressed file to the BasicTutorial folder in your registered folder.
- In ArcMap, open the Extract Package geoprocessing tool.
This tool will unpackage the compressed map template to your registered folder. The in_package parameter will be the compressed file you just downloaded. The output_folder parameter will be the BasicTutorial folder in your registered folder.
- Click OK to execute the tool.
Your registered folder should look similar to the following screen capture:
Note:
In the screen capture above, the registered folder is named MyDataStore. You can name your registered folder anything you want.
The WorldTopo_103Templatev2_288k_to_1k.mxd map document is now ready to be used in the web application.
Create the Python script
Create a Python script that will be used as the custom geoprocessing print service.
The Python script in the custom geoprocessing print service executes the ConvertWebMapToMapDocument function, which converts a web map (in JSON format) to a map document. The script then removes the service layers in the output map document, leaving the vector layers that correspond to the service layer in the web map JSON. The web map JSON also contains the extent of the map in the web application. Finally, the script exports the map document to a PDF document.
- Open any Python IDE, such as IDLE (which comes with ArcGIS Desktop).
- Copy and paste the following code into a new Python script:
- Change the templateMxd variable to the UNC path to the folder in your registered folder that contains the template map documents.
- Save the Python script. Name the script BasicTutorial.py. Save it in a folder named WebApp in the registered folder.
import arcpy
import os
import uuid
# Input Web Map json
Web_Map_as_JSON = arcpy.GetParameterAsText(0)
# The template location in the server data store
templateMxd = r"\\MyComputer\MyDataStore\BasicTutorial\v103\WorldTopo_103Templatev2_288k_to_1k.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 data frame in the template_mxd "Webmap"
df = arcpy.mapping.ListDataFrames(mxd, 'Webmap')[0]
# Remove the service layer
# This will just leave the vector layers from the template
for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
if lyr.isServiceLayer:
arcpy.mapping.RemoveLayer(df, lyr)
# Use the uuid module to generate a GUID as part of the output name
# This will ensure a unique output name
output = 'WebMap_{}.pdf'.format(str(uuid.uuid1()))
Output_File = os.path.join(arcpy.env.scratchFolder, output)
# Export the Web Map
arcpy.mapping.ExportToPDF(mxd, Output_File)
# 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)
Note:
If the ArcGIS Server, ArcMap, and the registered folder are all on the same machine, the UNC paths to the registered folder are not required. Instead, absolute paths can be used.
Create a Python script tool
Create a custom geoprocessing tool that runs the BasicTutorial.py script.
- In the Catalog window in ArcMap, browse to the WebApp folder in your registered folder directory.
- Right-click the WebApp folder and click New > Toolbox.
- Name the toolbox BasicTutorial.
- Right-click the BasicTutorial toolbox and click Item Description.
- On the Item Description dialog box, populate the Tags and Summary options with the text of your choice. Optionally fill in other option descriptions.
- Click Save and close the Item Description dialog box.
- In the Catalog window, right-click the BasicTutorial toolbox and click Add > Script.
- On the Add Script dialog box, enter BasicTutorial for both the Name and Label options.
- Click Next.
- For Script File, browse to the WebApp folder in the registered folder and select BasicTutorial.py.
- Click Next.
- Add two parameters to the script tool.
- Add the Web_Map_as_JSON parameter.
This parameter takes in a JSON representation of the state of the map to be exported as it appears in the web application. The properties should match the following screen capture:
- Add the Output_File parameter.
This is the output file that will be created. The properties should match the following screen capture:
Caution:
The Web_Map_as_JSON and Output_File parameter names must be spelled exactly as shown so they match the tool signature of the Print Task in the ArcGIS Web APIs.
- Click Finish on the Add Script dialog box.
- Add the Web_Map_as_JSON parameter.
- Right-click the BasicTutorial script tool and click Item Description.
- On the Item Description dialog box, populate the Tags and Summary options with the text of your choice. Also populate the Dialog Explanation option for all four parameters in the Syntax section of the Item Description dialog box with the text of your choice. Optionally fill in other option descriptions.
Execute the tool
The tool must execute successfully to create a result in the Results window that can be published to ArcGIS Server.
- In the Catalog window, right-click the BasicTutorial script tool and click Open.
- Leave the Web_Map_as_JSON input parameter blank.
Tip:
For publishing purposes, you can leave the Web_Map_as_JSON input parameter blank, as ArcGIS API for JavaScript provides 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 search for web map layers by name.
- Click OK and wait for the tool to finish executing.
The result is now ready to be published as a geoprocessing service.
Publish the result
If you are unfamiliar with publishing geoprocessing services, see the following:
To publish the result, complete the following steps:
- Open the Results window.
- Expand Current Session.
- Right-click the BasicTutorial result and click Share As > Geoprocessing Service.
- Check Publish a service.
- Click Next.
- Choose a publish or administrator connection to your ArcGIS Server machine.
- Click Next.
- Click Next.
- Click Continue.
- On the Service Editor dialog box, click Publish.
The geoprocessing service is now ready to be used in ArcGIS API for JavaScript.
ArcGIS API for JavaScript sample code
Use the following sample code to build your web application.
In the ArcGIS API for JavaScript code sample below, change the URL to the geoprocessing service you created to match your server name. It is referenced on the following line:
var printUrl = "http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial";
Code for BasicTutorial.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Webmap Printing</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css">
<script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=3.0"></script>
<script type="text/javascript" language="Javascript">
dojo.require("esri.map");
dojo.require("esri.tasks.PrintTask");
var printTask, params;
function init() {
// set the extent of the web app to same extent as the template map document
var startExtent = new esri.geometry.Extent({
"xmin" : -13043333,
"ymin" : 3836078,
"xmax" : -13030585,
"ymax" : 3853683,
"spatialReference" : {
"wkid" : 102100
}
});
var map = new esri.Map("map", {
extent : startExtent
});
// add tiled map service to webmap
var tiledUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer";
var tiledLayer = new esri.layers.ArcGISTiledMapServiceLayer(tiledUrl);
map.addLayer(tiledLayer);
var printUrl = "http://MyServer:6080/arcgis/rest/services/BasicTutorial/GPServer/BasicTutorial";
printTask = new esri.tasks.PrintTask(printUrl, {
async : true
});
params = new esri.tasks.PrintParameters();
params.map = map;
}
function print() {
var ptemplate = new esri.tasks.PrintTemplate();
// use the extent of the webmap in the output PDF
ptemplate.preserveScale = false;
params.template = ptemplate;
printTask.execute(params, printComplete);
}
function printComplete(result) {
window.open(result.url);
}
dojo.addOnLoad(init);
</script>
</head>
<body class="claro">
<input type="button" id="print" value="Print" onclick="print();"/>
<div id="map" style="width:1000px; height:600px; border:1px solid #000;"></div>
</body>
</html>
Run the web application
Run the web application you created. Consult the ArcGIS API for JavaScript documentation for instructions on running web applications, if necessary. The following is a screen capture of the web application:
Zoom in to an area of interest and click Print. The output PDF document appears. The output is a printer-friendly PDF document containing local vector data that was staged in the layout templates instead of an image of service layers. The following is a sample output:
This concludes the basic web map printing and exporting using arcpy.mapping tutorial. For more advanced scenarios, see Advanced web map printing and exporting using arcpy.mapping tutorial.