Visual Basic (Declaration) | |
---|---|
Public Class LayoutOptions |
C# | |
---|---|
public class LayoutOptions |
Layout Templates
One common request by ArcGIS developers is the ability to produce a printed map with various marginalia. Marginalia are elements on a map that enhance its viewing and include items such as legends, titles, grids and graticules, scale bars, scale text, north arrows, spatial reference information, additional graphics and text items. For both asynchronous (via the PrintTask.SubmitJobAsync Method) and synchronous (via the PrintTask.ExecuteAsync Method) geoprocessing tasks on ArcGIS Server, it is the Printing.PrintParameters.LayoutOptions Property that controls the visual representation of the marginalia in the map that is returned from ArcGIS Server.
The LayoutOptions Class provides a mechanism to set various marginalia to augment what is seen in the Map Control on a printed map. Depending on the ArcMap graphic Elements in the Layout Template used to generate a printed map via the PrintTask Class, developers can set several LayoutOptions Class Properties to control the marginalia.
Note: An example of producing map with various marginalia using a Layout Template can be found in the example code section of this document.
A Layout Template is a map document (.mxd) that is used to define the placement of a map and marginalia for use by ArcGIS Server to generate an output image. The default location where the Layout Templates are stored on ArcGIS Server is <install_directory>\Templates\ExportWebMapTemplates (see the following screen shot):
The filename without the .mxd extension should exactly match the names of the Layout Templates that are listed in Layout_Template parameter of the ArcGIS REST Services Directory under the Choice List option (see the following screen shot):
The default Layout Templayes may not make use of every option available in the various LayoutOptions Class Properties. It is the developer’s responsibility to work with the ArcGIS Server manager/administrator to understand what graphic Elements of a specific Layout Template is available for customization via the LayoutOptions Class Properties. The following table provides a list of the ArcMap supported graphic Elements in the Layout Template and how they correspond to the LayoutOptions Class Properties:
ArcMap graphic Element in the Layout Template | ESRI.ArcGIS.Client.Printing.LayoutOptions Class Properties |
---|---|
Title | LayoutOptions.Title Property |
Text | LayoutOptions.CustomTextElements Property |
DynamicText | Author | LayoutOptions.AuthorText Property |
DynamicText | Service Layer Credits | LayoutOptions.Copyright Property |
Legend | LayoutOptions.LegendOptions Property |
Scale Bar | LayoutOptions.ScaleBarOptions Property |
Note: the ArcMap DataFrame graphic Element in the Layout Template corresponds to the Map Control and is automatically set using the Printing.PrintParameters.LayoutTemplate Property.
It should be mentioned that there are numerous other ArcMap graphic Elements in a Layout Template that can be used to create an output map via the PrintTask Class. Not all of these graphic Elements can be controlled from the client application; they are static in nature in that they are preset when the Layout Template is originally created and published as a PrintTask ExportWebMap service via ArcGIS Server. The following ArcMap screen shot shows all of the graphic Elements that can be used in a Layout Template with those that can be controlled/adjusted by the client application highlighted in red:
The default installed Layout Templates may be insufficient to generate maps for custom client applications. Esri provides the ability to create custom Layout Templates with ArcMap and publish them as a print service via the ExportWebMap Geoprocessing task. The ArcGIS Server manager/administrator should work closely with the client application developer to achieve desired results in generating the custom Layout Template. During this process it may be necessary to go through several iterations to get the desired result. It should be noted that once a particular ExportWebMap Geoprocessing task is published on ArcGIS Server, that a snapshot of the ArcMap Layout Template .mxd document is used to generate the service. It is not possible to make a modification to the ArcMap Layout Template .mxd document and have that change reflected in an existing ExportWebMap Geoprocessing task service. If a change to the ArcMap Layout Template .mxd document is made, the ArcGIS Server ExportWebMap Geoprocessing task service should be deleted and re-published to reflect the new changes in the Layout Template. The LayoutOptions.CustomTextElements Property document provides a code example with workflow of how to create a custom Layout Template and publish an ArcGIS Server print task via the ExportWebMap Geoprocessing task service.
How to use:
When the application loads, enter a correct Url to an ArcGIS Server PrintTask based on a 'synchronous geoprocessing task'. Use the default options (or specify your own) for generating an output map using the parameters of: Layout Template, image Format, Copyright information, and map Title. Then click the 'Make a map for printing' button to generate the output.
The XAML code in this example is used in conjunction with the code-behind (C# or VB.NET) to demonstrate the functionality.
The following screen shot corresponds to the code example in this page.
XAML | Copy Code |
---|---|
<Grid x:Name="LayoutRoot" Background="White"> <!-- Add a Map Control. Zoom to the Continental United States. --> <esri:Map Background="White" HorizontalAlignment="Left" Margin="4,253,0,0" VerticalAlignment="Top" Name="MyMap" WrapAround="True" Height="300" Width="566" BorderBrush="Black" BorderThickness="1" Extent="-15582663,1650611,-5474071,6991676"> <esri:Map.Layers> <esri:LayerCollection> <!-- Add an ArcGISDynamicMapServiceLayer as a backdrop. --> <esri:ArcGISDynamicMapServiceLayer ID="World_Light_Gray_Base" Url="http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer"/> <!-- Add a FeatureLayer that shows the United States unemplopment rate by state. --> <esri:FeatureLayer ID="USA_Unemployment_Rate" Url="http://services.arcgisonline.com/ArcGIS/rest/services/Demographics/USA_Unemployment_Rate/MapServer/4" /> </esri:LayerCollection> </esri:Map.Layers> </esri:Map> <!-- Get the PrintTask.Url. --> <sdk:Label Height="20" HorizontalAlignment="Left" Margin="8,100,0,0" Name="Label_Url" VerticalAlignment="Top" Width="31" Content="Url:"/> <TextBox Height="23" HorizontalAlignment="Left" Margin="8,118,0,0" Name="TextBox_Url" VerticalAlignment="Top" Width="562" FontSize="10" /> <!-- Button to perform the work. --> <Button Content="Make map for printing" Height="25" Width="229" HorizontalAlignment="Left" Margin="12,147,0,0" Name="Button_ExecuteAsync" VerticalAlignment="Top" Click="Button_ExecuteAsync_Click" /> <!-- Give the user options to specify different: Layout Templates, image Formats, Copyright information, and Title for the output PrintTask operation. --> <sdk:Label Height="19" Margin="12,178,0,0" Name="Label_LayoutTemplate" VerticalAlignment="Top" Content="Layout Template:" HorizontalAlignment="Left" Width="111" /> <TextBlock Height="19" HorizontalAlignment="Left" Margin="122,178,0,0" Name="TextBlock_LayoutTemplate" VerticalAlignment="Top" Width="448" Text="A3 Landscape"/> <sdk:Label Height="19" HorizontalAlignment="Left" Margin="11,194,0,0" Name="Label_Format" VerticalAlignment="Top" Width="52" Content="Format:"/> <TextBlock Height="19" HorizontalAlignment="Left" Margin="59,194,0,0" Name="TextBlock_Format" VerticalAlignment="Top" Width="511" Text="PDF"/> <sdk:Label Height="19" HorizontalAlignment="Left" Margin="12,212,0,0" Name="Label_Copyright" VerticalAlignment="Top" Width="63" Content="Copyright:"/> <TextBlock Height="19" HorizontalAlignment="Left" Margin="72,212,0,0" Name="TextBlock_Copyright" VerticalAlignment="Top" Width="498" Text="ACME company - all rights reserved."/> <sdk:Label Height="19" HorizontalAlignment="Left" Margin="14,229,0,0" Name="Label_Title" VerticalAlignment="Top" Width="36" Content="Title:"/> <TextBlock Height="19" HorizontalAlignment="Left" Margin="48,229,0,0" Name="TextBlock_Title" VerticalAlignment="Top" Width="522" Text="United States Unemployment Rate"/> <!-- Provide the instructions on how to use the sample code. --> <TextBlock Height="94" HorizontalAlignment="Left" Name="TextBlock1" VerticalAlignment="Top" Width="622" TextWrapping="Wrap" Text="When the application loads, enter a correct Url to an ArcGIS Server PrintTask based on a 'synchronous geoprocessing task'. Use the default options (or specify your own) for generating an output map using the parameters of: Layout Template, image Format, Copyright information, and map Title. Then click the 'Make a map for printing' button to generate the output." /> </Grid> |
C# | Copy Code |
---|---|
// Create Global (aka. Member) variable for the PrintTask object that will be // used in other parts of the application. public ESRI.ArcGIS.Client.Printing.PrintTask _PrintTask; public MainPage() { InitializeComponent(); // Provide a valid PrintTask.Url for a "synchronous geoprocessing task" TextBox_Url.Text = "http://localhost:6080/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export20Web20Map%20Task"; // Set the _PrintTask variable to a new instance of the PrintTask Class. _PrintTask = new ESRI.ArcGIS.Client.Printing.PrintTask(); // Prevent the internet browser from using a cache for the PrintTask operations. _PrintTask.DisableClientCaching = true; // Set the PrintTask.Url from what is entered in the TextBox. _PrintTask.Url = TextBox_Url.Text; // Wire up an Event Handler for the PrintTask.ExecuteCompleted Event. _PrintTask.ExecuteCompleted += printTask_ExecuteCompleted; } private void Button_ExecuteAsync_Click(object sender, System.Windows.RoutedEventArgs e) { // The user clicked the button to generate an output map image. // Define the PrintParameters. ESRI.ArcGIS.Client.Printing.PrintParameters myPrintParameters = new ESRI.ArcGIS.Client.Printing.PrintParameters(MyMap); // Set the PrintParameters.LayoutTemplate to a valid Layout_Template in the Export Web Map Task service. myPrintParameters.LayoutTemplate = TextBlock_LayoutTemplate.Text; // Set the PrintParameters.Format to a valid image Format in the Export Web Map Task service. myPrintParameters.Format = TextBlock_Format.Text; // Define the MapOptions. It is imperative that this Class be used but only the Map.Extent be provided // (either via the constructor or via the Property). Do not set the MapOptions.Scale Property! We want // the PrintTask on ArcGIS Server to maintain the same Extent between the Map Control and the Data Frame // in the Layout Template, the Scale on ArcGIS server will be adjusted according to the Extent and the // size of the Data Frame in the Layout Template. ESRI.ArcGIS.Client.Printing.MapOptions myMapOptions = new ESRI.ArcGIS.Client.Printing.MapOptions(MyMap.Extent); myPrintParameters.MapOptions = myMapOptions; // Specify the LayoutOptions to provide marginalia in the output map. ESRI.ArcGIS.Client.Printing.LayoutOptions myLayoutOptions = new ESRI.ArcGIS.Client.Printing.LayoutOptions(); // Set the Copyright text for the map. myLayoutOptions.Copyright = TextBlock_Copyright.Text; // Set the Title for the map. myLayoutOptions.Title = TextBlock_Title.Text; // --------------------------------------------------------------------------------------------- // Define the LegendOptions. This will show specified Layers in the printed map's legend area. ESRI.ArcGIS.Client.Printing.LegendOptions myLegendOptions = new ESRI.ArcGIS.Client.Printing.LegendOptions(); // Define a List<LegendLayer> objects to put in the LegendOptions. List<ESRI.ArcGIS.Client.Printing.LegendLayer> myLegendLayers = new List<ESRI.ArcGIS.Client.Printing.LegendLayer>(); // Loop through all of the Layers in the Map Control. foreach (var myLayer in MyMap.Layers) { // Create a new LegendLayer object to put in the List<LegendLayer> collection. ESRI.ArcGIS.Client.Printing.LegendLayer myLegendLayer = new ESRI.ArcGIS.Client.Printing.LegendLayer(); // Set the LegendLayer.LayerId to the Layer.ID to add it to the printed map's legend area. myLegendLayer.LayerId = myLayer.ID; // Add a single LegendLayer into the List<LegendLayer> collection. myLegendLayers.Add(myLegendLayer); } // Set the LegendOptions.LegendLayer to the new constructed List<LegendLayer> objects. myLegendOptions.LegendLayers = myLegendLayers; // Set the LayoutOptions.LegendOptions to manage what the Legend looks like in the output map. myLayoutOptions.LegendOptions = myLegendOptions; //-------------------------------------------------------------------------------------------------- // Define the ScaleBarOptions. This will modify the appearance of the ScaleBar in the map. ESRI.ArcGIS.Client.Printing.ScaleBarOptions myScaleBarOptions = new ESRI.ArcGIS.Client.Printing.ScaleBarOptions(); // Define the metric and non-metric display values and their units. myScaleBarOptions.MetricLabel = "KILOMETERS"; myScaleBarOptions.MetricUnit = ESRI.ArcGIS.Client.Printing.ScaleBarOptions.MetricUnits.Kilometers; myScaleBarOptions.NonMetricLabel = "MILES"; myScaleBarOptions.NonMetricUnit = ESRI.ArcGIS.Client.Printing.ScaleBarOptions.NonMetricUnits.Miles; // Set the LayoutOptions.ScaleBarOptions tp ,anage what the Scalebar looks like in the output map. myLayoutOptions.ScaleBarOptions = myScaleBarOptions; // Add everything to the PrintParameters.LayoutOptions. myPrintParameters.LayoutOptions = myLayoutOptions; // NOTE: // If you try to submit more that one 'synchronous geoprocessing task' via PrintTask.ExecuteAsync at a time // using the ExecuteAsync methadology you will get a Visual Studio (Runtime) error: // NotSupportedException was unhandled by user code. "Task does not support concurrent I/O operations. Cancel // the pending request or wait for it to complete." // In order to overcome this, use the PrintTask.IsBusy Property and take action accordingly. if (_PrintTask.IsBusy == true) { // There is an existing 'synchronous geoprocessing task' PrintTask running. // Wait a few moments for the output to be generated and click the button again. } else if (_PrintTask.IsBusy == false) { // There is not an existing 'synchronous geoprocessing task' PrintTask running. // Use the 'synchronous geoprocessing task' PrintTask.ExecuteAsync Method. _PrintTask.ExecuteAsync(myPrintParameters); } } private void printTask_ExecuteCompleted(object sender, ESRI.ArcGIS.Client.Printing.PrintEventArgs e) { // Use only for ExecuteAsync operations (i.e. synchronous geoprocessing tasks). // Get any error information (add your own enhancements if desired). System.Exception mySystemException = e.Error; if (mySystemException != null) { MessageBox.Show(mySystemException.ToString()); } // Get the PrintResult from the completed operation. ESRI.ArcGIS.Client.Printing.PrintResult myPrintResult = e.PrintResult; // Test is we have valid return PrintResults. if (myPrintResult != null) { // Get any messages returned from ArcGIS Server (add your own enhancements if desired). List<ESRI.ArcGIS.Client.Tasks.GPMessage> myListOfGPMessage = myPrintResult.Messages; // Get the location of the image/.pdf created by ArcGIS Server. System.Uri myUri = myPrintResult.Url; // Open a new internet browser window with the generated image from the PrintTask. System.Windows.Browser.HtmlPage.Window.Navigate(myUri, "_blank"); } } |
VB.NET | Copy Code |
---|---|
' Create Global (aka. Member) variable for the PrintTask object that will be ' used in other parts of the application. Public _PrintTask As ESRI.ArcGIS.Client.Printing.PrintTask Public Sub New() InitializeComponent() ' Provide a valid PrintTask.Url for a "synchronous geoprocessing task" TextBox_Url.Text = "http://localhost:6080/arcgis/rest/services/Utilities/PrintingTools/GPServer/Export20Web20Map%20Task" ' Set the _PrintTask variable to a new instance of the PrintTask Class. _PrintTask = New ESRI.ArcGIS.Client.Printing.PrintTask() ' Prevent the internet browser from using a cache for the PrintTask operations. _PrintTask.DisableClientCaching = True ' Set the PrintTask.Url from what is entered in the TextBox. _PrintTask.Url = TextBox_Url.Text ' Wire up an Event Handler for the PrintTask.ExecuteCompleted Event. AddHandler _PrintTask.ExecuteCompleted, AddressOf printTask_ExecuteCompleted End Sub Private Sub Button_ExecuteAsync_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) ' The user clicked the button to generate an output map image. ' Define the PrintParameters. Dim myPrintParameters As New ESRI.ArcGIS.Client.Printing.PrintParameters(MyMap) ' Set the PrintParameters.LayoutTemplate to a valid Layout_Template in the Export Web Map Task service. myPrintParameters.LayoutTemplate = TextBlock_LayoutTemplate.Text ' Set the PrintParameters.Format to a valid image Format in the Export Web Map Task service. myPrintParameters.Format = TextBlock_Format.Text ' Define the MapOptions. It is imperative that this Class be used but only the Map.Extent be provided ' (either via the constructor or via the Property). Do not set the MapOptions.Scale Property! We want ' the PrintTask on ArcGIS Server to maintain the same Extent between the Map Control and the Data Frame ' in the Layout Template, the Scale on ArcGIS server will be adjusted according to the Extent and the ' size of the Data Frame in the Layout Template. Dim myMapOptions As New ESRI.ArcGIS.Client.Printing.MapOptions(MyMap.Extent) myPrintParameters.MapOptions = myMapOptions ' Specify the LayoutOptions to provide marginalia in the output map. Dim myLayoutOptions As New ESRI.ArcGIS.Client.Printing.LayoutOptions ' Set the Copyright text for the map. myLayoutOptions.Copyright = TextBlock_Copyright.Text ' Set the Title for the map. myLayoutOptions.Title = TextBlock_Title.Text ' --------------------------------------------------------------------------------------------- ' Define the LegendOptions. This will show specified Layers in the printed map's legend area. Dim myLegendOptions As New ESRI.ArcGIS.Client.Printing.LegendOptions ' Define a List(Of LegendLayer) objects to put in the LegendOptions. Dim myLegendLayers As New List(Of ESRI.ArcGIS.Client.Printing.LegendLayer) ' Loop through all of the Layers in the Map Control. For Each myLayer In MyMap.Layers ' Create a new LegendLayer object to put in the List(Of LegendLayer) collection. Dim myLegendLayer As New ESRI.ArcGIS.Client.Printing.LegendLayer ' Set the LegendLayer.LayerId to the Layer.ID to add it to the printed map's legend area. myLegendLayer.LayerId = myLayer.ID ' Add a single LegendLayer into the List(Of LegendLayer) collection. myLegendLayers.Add(myLegendLayer) Next ' Set the LegendOptions.LegendLayer to the new constructed List(Of LegendLayer) objects. myLegendOptions.LegendLayers = myLegendLayers ' Set the LayoutOptions.LegendOptions to manage what the Legend looks like in the output map. myLayoutOptions.LegendOptions = myLegendOptions '-------------------------------------------------------------------------------------------------- ' Define the ScaleBarOptions. This will modify the appearance of the ScaleBar in the map. Dim myScaleBarOptions As New ESRI.ArcGIS.Client.Printing.ScaleBarOptions ' Define the metric and non-metric display values and their units. myScaleBarOptions.MetricLabel = "KILOMETERS" myScaleBarOptions.MetricUnit = ESRI.ArcGIS.Client.Printing.ScaleBarOptions.MetricUnits.Kilometers myScaleBarOptions.NonMetricLabel = "MILES" myScaleBarOptions.NonMetricUnit = ESRI.ArcGIS.Client.Printing.ScaleBarOptions.NonMetricUnits.Miles ' Set the LayoutOptions.ScaleBarOptions tp ,anage what the Scalebar looks like in the output map. myLayoutOptions.ScaleBarOptions = myScaleBarOptions ' Add everything to the PrintParameters.LayoutOptions. myPrintParameters.LayoutOptions = myLayoutOptions ' NOTE: ' If you try to submit more that one 'synchronous geoprocessing task' via PrintTask.ExecuteAsync at a time ' using the ExecuteAsync methadology you will get a Visual Studio (Runtime) error: ' NotSupportedException was unhandled by user code. "Task does not support concurrent I/O operations. Cancel ' the pending request or wait for it to complete." ' In order to overcome this, use the PrintTask.IsBusy Property and take action accordingly. If _PrintTask.IsBusy = True Then ' There is an existing 'synchronous geoprocessing task' PrintTask running. ' Wait a few moments for the output to be generated and click the button again. ElseIf _PrintTask.IsBusy = False Then ' There is not an existing 'synchronous geoprocessing task' PrintTask running. ' Use the 'synchronous geoprocessing task' PrintTask.ExecuteAsync Method. _PrintTask.ExecuteAsync(myPrintParameters) End If End Sub Private Sub printTask_ExecuteCompleted(sender As Object, e As ESRI.ArcGIS.Client.Printing.PrintEventArgs) ' Use only for ExecuteAsync operations (i.e. synchronous geoprocessing tasks). ' Get any error information (add your own enhancements if desired). Dim mySystemException As System.Exception = e.Error If mySystemException IsNot Nothing Then MessageBox.Show(mySystemException.ToString) End If ' Get the PrintResult from the completed operation. Dim myPrintResult As ESRI.ArcGIS.Client.Printing.PrintResult = e.PrintResult ' Test is we have valid return PrintResults. If myPrintResult IsNot Nothing Then ' Get any messages returned from ArcGIS Server (add your own enhancements if desired). Dim myListOfGPMessage As List(Of ESRI.ArcGIS.Client.Tasks.GPMessage) = myPrintResult.Messages ' Get the location of the image/.pdf created by ArcGIS Server. Dim myUri As System.Uri = myPrintResult.Url ' Open a new internet browser window with the generated image from the PrintTask. System.Windows.Browser.HtmlPage.Window.Navigate(myUri, "_blank") End If End Sub |
System.Object
ESRI.ArcGIS.Client.Printing.LayoutOptions
Target Platforms: Windows XP Professional, Windows Server 2003 family, Windows Vista, Windows Server 2008 family, Windows 7, Windows 8