Welcome to ESRI Blogs

View technical workshops from the 2008 ESRI Developer Summit

Videos from the 2008 ESRI Developer Summit technical workshops are available on the EDN Conferences page for everyone to view. Select a session and in the right-hand menu you'll see links to slides, video, and in some cases sample code.

These workshops are presented primarily by ESRI development staff and include best practices, examples, and tips.

Below are direct links to some of the ArcGIS Server session pages:

General ArcGIS Server development topics

Developer's Road Map to ArcGIS Server 9.3
Using the ArcGIS Server REST API
Building Mashups Using the ArcGIS JavaScript APIs
Working with ArcGIS Server Services Using the SOAP API
ArcGIS Server for ArcIMS Developers
Moving Desktop Applications to ArcGIS Server

.NET development topics

Building .NET Applications Using the ArcGIS Server Web ADF and ASP.NET AJAX
Building and Extending Tasks for .NET Web Applications
Implementing Security for ArcGIS Server .NET Solutions

Java development topics

Building Java Applications Using the ArcGIS Server Web ADF and AJAX
Building and Extending Tasks for ArcGIS Server—Java Web Applications
Implementing Security for ArcGIS Server—Java Solutions
Developing Advanced Java Web Applications
Architecting ArcGIS Server Solutions for Linux and Solaris

Administration and performance topics

Leveraging the OGC Capabilities of ArcGIS Server
Building and Optimizing Geoprocessing Services for ArcGIS Server
Implementing and Optimizing ArcGIS Server Map Caches
Architecting ArcGIS Server Solutions for Performance and Scalability
Using and Managing Raster Data in Server Applications

Feedback or questions about the videos are welcome as comments to this post.

Posted by sterlingdq | 0 Comments

.NET serialization and the Web ADF

Rex Hansen, a Product Engineer on the ArcGIS Server development team, contributed this post.

Although Web applications are designed on inherently stateless technologies, the applications themselves are often used more than once by multiple users and may need to share information with other applications. As a result, information must often be persisted outside of the application where it can be retrieved and reused in the future. For Web applications the onus falls on the Web developer to implement a persistence mechanism to maintain information across sessions and applications. Serializing information using built-in .NET support makes persistence easy and reusable. In this post, we will review the serialization options in .NET and discuss some of the limitations and best practices for utilizing serialization with the Web ADF.

So, what is serialization? In general, serialization is the process of converting the state of an item (e.g. object) into a form that can be stored or transported and eventually retrieved. The Microsoft .NET Framework contains three built-in options for serialization:

.NET Class Name Description
XmlSerializer Serializes and deserializes objects into and from XML documents.
SoapFormatter Serializes and deserializes an object, or an entire graph of connected objects, in SOAP format.
BinaryFormatter Serializes and deserializes an object, or an entire graph of connected objects, in binary format.

Both BinaryFormatter and SoapFormatter can serialize/deserialize Web ADF objects (including geometry, graphics datasets, and graphics layers) successfully. XmlSerializer is not fully supported for use with the Web ADF.

To illustrate, let’s use Web ADF geometry types. Web ADF geometry can be serialized if it does not define a spatial reference. However, if a spatial reference is defined, the following exception (or derivative thereof) is returned:

ESRI.ArcGIS.ADF.Web.SpatialReference.IDSpatialReferenceInfo cannot be serialized because it does not have a parameterless constructor.

The XmlSerializer requires information about complex types contained by the object to be serialized. If the complex types are not null, they must have a parameterless constructor. You cannot change the source code for Web ADF classes, but you can subclass the base class and create a parameterless constructor. However, even if you define a parameterless constructor for the complex type (in this case, IDSpatialReferenceInfo), the following exception is returned:

The type ESRI.ArcGIS.ADF.Web.SpatialReference.IDSpatialReferenceInfo was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically.

In general, the object to be serialized must also know about the complex types it may reference. This can be defined in the object’s class as an XmlInclude statement or provided to the XmlSerializer in a Type[] array. You can manually add XmlInclude statements in the derived class and/or traverse the object graph and add the types on the fly to the XmlSerializer. In any case, this will likely be a labor intensive process to support each Web ADF type. Additionally, Web ADF graphics datasets and layers cannot be serialized because the geometry column references a Web ADF geometry type that does not implement IXmlSerializable. Object serialization in the Web ADF is supported through the use of the Serializable attribute, which does not require explicit implementation. Implementing IXmlSerializable on a Web ADF geometry type changes how the Serializable attribute functions because it requires writing code to explicitly handle the serialization of the class to and from xml. If serialization is not explicitly handled (the implementation methods are empty) then all serialization options, including XmlSerializer, will not generate content.

What does this mean? Considering the limitations with XMLSerilizer, if you want to serialize Web ADF types to XML, you need to use SoapFormatter. While the XML generated will have the extra overhead associated with a SOAP message, you can be confident that it will work. From the performance and storage perspective, the BinaryFormatter will provide the most efficient means for serializing\deserializing Web ADF objects, but it is not designed to be human readable. Note, the serialized content generated by the SoapFormatter and BinaryFormatter will work with SQL Server. The code examples below demonstrate all three serialization options with a Web ADF Point:

[C#] 
// Sample Web ADF Point			
ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = new ESRI.ArcGIS.ADF.Web.Geometry.Point(-120, 30);

// === Serialize to XML using XmlSerializer ===
System.Xml.Serialization.XmlSerializer xmlSerializer =  
  new System.Xml.Serialization.XmlSerializer(adfPoint.GetType());
System.Text.StringBuilder builder = new System.Text.StringBuilder();
System.IO.StringWriter writer = new System.IO.StringWriter(builder);
xmlSerializer.Serialize(writer, adfPoint);
string xmlADFPoint = builder.ToString();

//Deserialize from XML
System.IO.StringReader reader = new System.IO.StringReader(xmlADFPoint);
System.Xml.XmlTextReader xmlTextReader = new System.Xml.XmlTextReader(reader);
ESRI.ArcGIS.ADF.Web.Geometry.Point newXMLADFPoint =
  (ESRI.ArcGIS.ADF.Web.Geometry.Point)xmlSerializer.Deserialize(xmlTextReader);


//=== Serialize to SOAP using SoapFormatter ===
System.Runtime.Serialization.Formatters.Soap.SoapFormatter soapFormatter =
  new System.Runtime.Serialization.Formatters.Soap.SoapFormatter();
soapFormatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
soapFormatter.FilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Low;
soapFormatter.TypeFormat = System.Runtime.Serialization.Formatters.FormatterTypeStyle.XsdString;

string soapADFPoint = null;
using (System.IO.MemoryStream fs = new System.IO.MemoryStream(8000))
{
  soapFormatter.Serialize(fs, adfPoint);
  byte[] outBytes = fs.ToArray();
  soapADFPoint = Encoding.UTF8.GetString(outBytes);
}

// Deserialize from SOAP
byte[] inBytes = Encoding.UTF8.GetBytes(soapADFPoint);
System.IO.MemoryStream stream = new System.IO.MemoryStream(inBytes);

ESRI.ArcGIS.ADF.Web.Geometry.Point newSoapADFPoint = (ESRI.ArcGIS.ADF.Web.Geometry.Point)
soapFormatter.Deserialize(stream);


//=== Serialize to Binary using BinaryFormatter ===
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter binaryFormatter =
  new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
byte[] binaryADFPoint = null;
using (System.IO.MemoryStream memoryStreamIn = new System.IO.MemoryStream(8000))
{
  binaryFormatter.Serialize(memoryStreamIn, adfPoint);
  memoryStreamIn.Position = 0;
  binaryADFPoint = memoryStreamIn.ToArray();
}

// Deserialize from Binary
ESRI.ArcGIS.ADF.Web.Geometry.Point newBinaryADFPoint = null;
using (System.IO.MemoryStream memoryStreamOut = new System.IO.MemoryStream(8000))
{
  memoryStreamOut.Write(binaryADFPoint, 0, binaryADFPoint.Length);
  memoryStreamOut.Seek(0, System.IO.SeekOrigin.Begin);
  newBinaryADFPoint = (ESRI.ArcGIS.ADF.Web.Geometry.Point)
  binaryFormatter.Deserialize(memoryStreamOut);
}
Posted by sterlingdq | 2 Comments
Filed under: ,

New blog focuses on geodatabases and ArcSDE

Last month the ESRI geodatabase development team revealed their new blog Inside the Geodatabase. Visit this blog to get news and tips about ESRI geodatabases directly from development team members.

The blog is moderated by Product Engineers Brent Pierce and Jonathan Murphy, who have already published a number of posts that you’ll find useful if you work with geodatabases and ArcSDE technology. As an example, check out the recent post Five best practices for maintaining an ArcSDE geodatabase.

Be sure to e-mail Brent and Jonathan your ideas for future posts. Just like with this blog, you’ll need to sign in with your ESRI Global Account to send e-mail.

Posted by sterlingdq | 0 Comments
Filed under: ,

Taskbar scripts for administering services

Bryan Baker, a Product Engineer on the ArcGIS Server development team, contributed this post:

Working with ArcGIS Server requires you to stop and start services on occasion. In fact, the server object manager (SOM)itself is represented by the Windows service ArcGIS Server Object Manager, which you may sometimes want to stop or restart. On Windows, it can be painful to open Control Panel, open Administrative Tools, then the Services panel, and finally use the tools there to stop and start the service. You can make this a lot easier on Windows by creating scripts and shortcuts accessible from the desktop, or even better, from a toolbar on your Taskbar. Once created, you click on the toolbar menu in the Taskbar, and then on your script or shortcut, like this:

Shortcuts on Windows taskbar

These examples make it simple to restart, start, and stop ArcGIS Server. These kinds of scripts can perform many operations on your server. Let's see how to create these toolbar scripts and shortcuts.

Create a toolbar folder

First, use Windows Explorer to create a new folder to hold the shortcuts and scripts. The folder can be anywhere on your system. I'll create my folder at C:\Toolbars\Scripts.

Create the script or shortcut

Inside the new Scripts folder, add the script or shortcut you want to appear. A script can use any of several available environments in Windows, including batch files, Windows Script Host, and the new Windows PowerShell. Let's take the example of the Restart ArcGIS Server item shown above. This is actually a simple batch file. Here's an easy way to create the batch file:

  1. Open Windows Explorer and navigate to the Scripts folder you created.
  2. In the right side of Windows Explorer, right-click an empty area and choose New - Text Document.
  3. Rename the document: Restart ArcGIS Server.bat. Windows warns you about changing the extension--go ahead and confirm.
  4. To open the batch file for editing, right-click on it and select Edit. It'll open in Notepad.

Note: You can also add a shortcut to a program, either by copying an existing shortcut or creating a new one (right-click and choose New-Shortcut). For example, you can add a shortcut to ArcCatalog by navigating to it in the Start menu, then right-click and drag the ArcCatalog shortcut into the Windows Explorer folder for Scripts, and in the pop-up menu choose Copy Here.

Enter the script commands

With the script batch file open in Notepad or other text editor, add the commands you want to run. Batch files have a number of commands you can use, and can run anything you can do at a command line. To start and stop services, you can use the Windows "net start" and "net stop" commands. These commands start or stop the service you name in the command. You can get the name of the service from the Services dialog in Control Panel (some services have shorter names, for example, the World Wide Web Publishing Service is also W3SVC).

For the Restart ArcGIS Server batch file, we can enter these commands in the batch file, one per line:

net stop "ArcGIS Server Object Manager" 
net start "ArcGIS Server Object Manager"

Save the file and close Notepad.

Note: You might need to add commands for other services that are related to the service. For example, if you use SQL Server in your ArcGIS Server, you can add a command to start or stop that service if necessary.

Add the folder as a new toolbar

Finally, add the toolbar to the Taskbar. To do this:

  1. Right-click on any open spot on the Taskbar.
  2. In the context menu, choose Toolbars - New Toolbar...
  3. In the New Toolbar dialog that opens, navigate to the Scripts folder you created earlier.
  4. Click OK.

The folder should appear in the Taskbar as in the image below. You can then click the >> on the toolbar to run the scripts or shortcuts in it.

Running the batch file from the taskbar

Optional: Set icons for scripts

The example above showed icons for the scripts, rather than the default batch file icon. If you want to change the icon, you need to create a shortcut to the batch file and use the shortcut instead. Here's one approach:

  1. In Windows Explorer, create a new folder to hold the actual batch files. Within the Scripts folder, create a subfolder called Batch.
  2. Move the batch file(s) to the new Batch folder.
  3. Right-click on the batch file and drag it into the Scripts folder. Upon releasing the mouse, choose to Create Shortcuts Here.
  4. In the Scripts folder, right-click on the new shortcut and choose Properties.
  5. In the Properties dialog, on the Shortcut tab, click Change Icon... (dismiss the warning that no icons are in the batch file).
  6. Navigate to the icon or the program (.exe or .dll) that contains an icon to use. In the example above, I used the ArcCatalog icon, available at <ArcGIS install>\bin\ArcCatalog.exe.
  7. Optionally, change the name of the shortcut in the General tab.
  8. Click OK in the two dialogs to confirm the icon selection.

More options

If you create lots of scripts and shortcuts, you can create folders within your toolbar folder, and add scripts or shortcuts within these subfolders. The subfolders will then be available to mouse-over and expand when you click on the toolbar.

These scripts and shortcuts can be very handy for many operations. Other examples include

  • Restarting other services, such as the IIS Web server or ArcIMS
  • Shortcuts to programs, such as ArcCatalog or ArcMap
  • Shortcuts to files or folders, such as a log folder or a configuration file
  • Connecting network drives ("net use" command)
  • Backup commands

As a more complex example, I have a script that starts several services after a delay of 5 minutes (using the Sleep command in the Windows Server 2003 Resource Kit Tools); I have that script set to run on machine startup, so that I can start working on other tasks without the overhead of a lot of service startups, which is useful on a development computer. I'm sure you can think of many more creative uses of toolbars, scripts and shortcuts!

A zip file with the scripts and shortcuts discussed above is available here. It includes some additional sample scripts for ArcIMS and IIS, plus shortcuts to some commonly used Windows utilities.

Posted by sterlingdq | 4 Comments
Filed under:

SP5 offers IBM Portal Server ArcGIS Portlet development

In this post Dan O'Neill describes an enhancement for ArcGIS Server Java developers in 9.2 Service Pack 5:

ArcGIS Server 9.2 Service Pack 5 includes an enhancement to the ArcGIS Server Java ADF which provides support for IBM Portal Server ArcGIS Portlet development. This gives you the ability to create and publish GIS Mapping Portlets inside IBM Portal Server. In conjunction, SP5 includes a plug-in for the IBM Rational Application Developer (RAD) environment so that you can create and deploy those ArcGIS Portlets more efficiently. The following documents have been added related to this SP5 enhancement.


New article - Install ArcGIS RAD plug-in
Programming language(s): Java
Development platforms: ArcGIS Server

After installing SP5 you will neeed to update the IBM RAD IDE to leverage the ArcGIS RAD plug-in. This article walks you through that process.


New article - Developing ArcGIS Portlet applications in RAD
Programming language(s): Java
Development platforms: ArcGIS Server

This article takes you through the basic steps required to create an ArcGIS Portlet application using the plug-in. The sample application displays a map, toolbar, table of contents, map overview, results, results details, and an empty task pane.

Posted by sterlingdq | 0 Comments
Filed under: ,

Publishing a geoprocessing Select tool to ArcGIS Explorer

In this post, guest author Jeff Barrette of ESRI Olympia explains how to create a geoprocessing service for selecting features in ArcGIS Explorer.

ArcGIS Explorer users may want to zoom to specific locations based upon data that is available to them either locally or from a server. In ArcGIS Desktop, users can simply select features of interest based upon feature attribute values and then zoom to the extent of the resulting selected features. ArcGIS Explorer does not have the equivalent of a Select By Attribute function available but it can easily be added as a custom task. This post discusses the steps necessary to build a geoprocessing select task that can be added into ArcGIS Explorer to give users zoom to selected features functionality.

The general steps include first using ArcGIS Desktop to build a map document (MXD) that contains the feature layers that need to be queried along with the resulting selection symbology. The next step involves building a geoprocessing model or script that performs the selection capabilities. Next, the geoprocessing tool and the results map document need to be published and served using ArcGIS Server. Finally, the new capabilities are added into ArcGIS Explorer as a new, custom task.

For this example, the data referenced in the steps below is the States feature class that is available from the ESRI Data and Maps data collection. The data is located on the ArcGIS 9 Data & Maps StreetMap USA DVD under the usa\census\ folder. This post is written for use with ArcGIS Desktop 9.2 (SP5), ArcGIS Server 9.2 (SP5), and ArcGIS Explorer (build 440).

Setup

  1. Create a new folder on the file system called "SelectTask". It is best to organize all of the components necessary to publish a geoprocessing task (file based data, SDE connection files, MXDs, toolboxes, etc) in a single location to minimize file access and permission issues. The graphic below also includes a folder called Publish. It is used to organize all published tasks as individual project folders.
    Publish folder
  2. Copy the states feature class to this new location.
  3. Set the appropriate permissions. Ideally, this folder is located on the same machine that ArcGIS Server is installed on. If the data is on the server, then permissions on the data should be all set. If on a different network drive, this folder should be shared and the SOC account should be granted access to it.
  4. Create a connection to the ArcGIS Server as an admin user. If this is the first time you are publishing something to ArcGIS Server, you are first required to establish a connection to the server.
  5. In ArcCatalog, expand GIS Servers. This is a node in the Catalog Tree.
  6. Double-click Add ArcGIS Server.
  7. Select Manage GIS Services and click Next.
  8. Provide the necessary connection information and click Finish.

Note: It is also recommended that you read through the Troubleshooting Tips section at the end of this post before proceeding with the steps below to ensure user accounts and permissions are set appropriately.

Designing a Map Document (part 1)

  1. Open a new ArcMap session and add the States layer. It is not necessary to modify the symbology because with the steps in this document, we will not be consuming and displaying the map service, but rather using the layers in it to query against its features. In the steps to follow, you will symbolize the results layer to control how the results appear in ArcGIS Explorer (or in other applications).

    Note: If your data source is an ArcSDE geodatabase, then see the Working with ArcSDE Geodatabase Data Sources section below for some suggestions on how to manage the ArcSDE server connections. There are some additional steps that should be taken to ensure ArcGIS Server can connect to the data. Copying the SDE connection file to the project folder makes access much easier to manage rather than having to set permissions on your personal profile folders.

  2. Set relative paths for the data sources. This can be set via File > Document Properties > Data Source Options. Relative paths are not necessary if the ArcMap and ArcGIS Server applications are on the same machine but they do make it much easier to move a project folder from one server to another or to multiple servers all with the same data and models. Hard-coded paths are best if there are multiple SOC machines but all pointing to a single drive to access data.
  3. Check the "Overwrite the outputs of geoprocessing operations" option. This can be set via Tools > Options > Geoprocessing tab. It is important that the output file name remain the same after multiple executions. If this option is left unchecked the output name would change (i.e., increment by one each time the model is run) and the applications would not be able to reference the correct output result.
  4. Uncheck the "Results are temporary by default" option. This can be set via Tools > Options > Geoprocessing tab. If the results are going to be used in subsequent applications, it is important the results are not immediately cleared.
  5. Save the MXD to the new folder location and name it "SelectStates.MXD".
  6. Keep ArcMap open. You will come back to the same MXD in a few steps.

Building a geoprocessing model

  1. In ArcCatalog, create a toolbox called "CustomToolbox". Right-click the SelectTask folder and click New > Toolbox. Your folder should look similar to the following:
    Folder with toolbox
  2. In ArcMap, open ArcToolbox.
  3. Add your CustomToolbox. Right-click ArcToolbox > Add Toolbox, browse to the Select Task folder, and click Open.
  4. Set the ScratchWorkspace environment variable to the location of your project folder (Example: C:\Publish\SelectTask). Right-click ArcToolbox > Environments > General Settings > Scratch Workspace. It is important to do this at the application level and not just at the tool or model level because it is the ArcMap application that needs to manage the output data.
    Setting the Scratch Workspace
  5. Create a new model. Right-click your CustomToolbox and click New > Model.
  6. Change the Name property to "SelectStates". Select Model > Model Properties > General Tab. The name property cannot include spaces or underscores.
  7. Also change the Label property to "SelectStates" and click OK. The label property is what gets displayed in the client application and can contain spaces.
  8. Drag and drop the States layer onto the model.
  9. Drag and drop the Select tool onto the model. You can find this tool in ArcToolbox Analysis Tools > Extract > Select.

    Note: The Select By Attribute tool can't be used by itself because it does not create an output result that gets written to disk that can then be accessed by other applications. In a model, Select By Attribute can be connected to the Copy Features command to generate the necessary file output. The Select command accomplishes the same end result.

  10. Open the Select tool. Right-click on the tool and select Open.
  11. Set States to be the Input Features. Select the layer with the blue recycle symbol next to it. This represents the data source added into the model. The yellow icon represents a layer located in the Table of Contents (TOC). If you choose the latter, you will have two references to the same data and one will need to be removed.
  12. Set the %SCRATCHWORKSPACE% inline variable for the Output Feature Class. The input should look similar to the graphic below:
    Set the SCRATCHWORKSPACE inline variable

    Note: It is best to use the ScratchWorkspace inline variable when output results are going to be referenced from other applications. The Managed option works great for intermediate results but does not work well on permanent output results. The Managed option will automatically increment the output name with each successive execution therefore making it difficult for other applications to reference the correct data. The ScratchWorkspace inline variable should be used instead. In addition to ScratchWorkspace, also use the "Overwrite the outputs of geoprocessing operations" option and make sure the "Results are temporarily by default" option is turned off. These settings will ensure the resulting output is correctly accessed by other applications.

  13. Build a default, optional expression (Example: "STATE_ABBR" = 'AK'). This can be left blank but it makes it a much easier for a user to modify an already existing expression (i.e., its SQL structure) than it is to type one from scratch. Click OK.
  14. Create Expression variable/parameter for Select tool. Right-click the Select tool and choose Make Variable > From Parameter > Expression.
  15. Click the Auto Layout and Full Extent buttons. This will better organize your view of the model.
  16. Set the Expression as a Model Parameter. Right-click the Expression object and choose Model Parameter. This will enable a user to enter a custom expression within the published task inside the client application.
  17. Right-click the Expression and rename it "Enter Expression:". How the expression is labeled will control how it appears in the client application. This is also true for how you label the model. The following graphic shows how the task will appear in ArcGIS Explorer.
    The task in ArcGIS Explorer
  18. Right-click the model output States_Select.shp and check Model Parameter. This will persist an output result on disk. The result is what will be sent back to the ArcGIS Explorer application. Note, when output is set as Model Parameter it cannot also be set to intermediate (temporary data). Therefore any results you want to send back to ArcGIS Explorer should not be intermediate.
  19. Check Add to Display. This parameter is only necessary for displaying the result in ArcGIS Desktop. This is not necessary when publishing the model as a task.
    Model options checked

    When completed, the model should look similar to the following graphic:
    The completed model

  20. Save the model. Click Model > Save.
  21. Close the model. Click Model > Close.

Designing a Map Document (part 2)

  1. Drag and drop the Select States tool from ArcToolbox into the top portion of the ArcMap TOC. This is called a Tool Layer and it can be executed from the TOC. The Tool Layer will also include inputs and outputs to the model once it is executed.
  2. Run the model from the tool layer. Right-click the Select States tool layer and select Open to open the model. Then click OK to run the model. A layer named States_Select.shp displaying the default selected state of Alaska should have been added to your TOC as part of the tool layer.
  3. Set the symbology for the States_Select.shp layer. However this layer is symbolized is how it will appear in a client application. If you only want the result to appear in the ArcGIS Explorer results list but you don’t want the feature(s) to display in the view, then set the symbology to be nothing.
  4. Uncheck the top level tool layer. The tool layer is really intended only to be used for publishing purposes. If it is turned on while running the model from ArcMap, it won’t be consistent with the layer returned from the result via Add to Display. The TOC should look like the following graphic:
    Map document TOC

Note: Models can be published in one of two ways:

First, publish an MXD containing geoprocessing tool layers. Each tool layer becomes a task in the geoprocessing service. This method is a little easier because all the symbology can be directly set within the MXD. Also, geoprocessing capabilities are automatically recognized when the MXD is published to ArcGIS Server. Both the data and tools can be consumed by client applications. This will be the method used in the following sections.

Second, a geoprocessing toolbox can be directly published. Each tool in the toolbox becomes a task in the geoprocessing service. If you want to control the appearance of the input and output results, then you would need to create additional layer files with the desired symbology that are referenced by the tools. Publishing stand alone tools does have an advantage over publishing tool layers.

Publishing the map with geoprocessing capabilities

  1. In ArcCatalog, browse to the SelectTask folder.
  2. Right-click the SelectStates MXD and choose Publish to ArcGIS Server. The first panel allows you to select an ArcGIS Server, specify the name of the service, and select or create a folder to organize your new service. You can optionally change these settings. Click Next.
  3. Verify that the Mapping and Geoprocessing capabilities are checked and click Next. Optionally, this service could be made available to KML, WMS, or mobile clients.
  4. Click Finish. To dismiss the summary page. A new map service and a new geoprocessing service are added to the GIS Server. Both services should be started and ready to go. The GIS Server connection in ArcCatalog should look similar to the graphic below:
    GIS server connection in ArcCatalog
  5. Verify the service is running. A quick way to determine the service is working before continuing is to make sure you can preview the service in ArcCatalog. Simply select the SelectStates map service and click on the preview tab. If you can see the States displayed, then the service is running properly. If you don’t see anything display, then refer to the Troubleshooting Tips section near the end of this document.

Adding the custom task into ArcGIS Explorer

  1. Open ArcGIS Explorer.
  2. Click Select Tools > Manage Tasks This dialog allows you to control access to the tasks that can be used within ArcGIS Explorer. The tasks listed on the left are all those currently available to the application, the tasks on the right are those that are actually being used.
  3. Click the Get Tasks button. This allows you to browse locally for tasks or to connect to other servers to add additional tasks.
  4. Make sure the Servers option is selected and click ArcGIS Server.
  5. Enter the appropriate connection information. If you are not sure of the server name or path, then look at the properties of the SelectStates map service via a right-click > Service Properties > Capabilities tab. Copy the URL information up to and including "/Services".
    Connecting to the server in ArcGIS Explorer
  6. Expand the resulting SelectStates toolbox, click the Select States tool, and click Open. The task has been made available to the application but is still not available to the current map.
    Adding the task in ArcGIS Explorer
  7. Click the Select States task on the left side and move it right to make it available to the current map. Then click OK.

Using the task in ArcGIS Explorer

  1. Click the Select States task in the Tasks list. This will open the custom task in the task window. The labels and text display exactly how you set them up in the model.
  2. Modify the expression found in the Task Center. Because a default expression was created, it is easy to manipulate. Keep in mind that this expression could be modified however someone would need it to be (Example: "STATE_ABBR" = 'WA' OR "STATE_ABBR" = ‘RI’).
    The completed task running in ArcGIS Explorer
  3. Click Run. Then double-click the result in the Results list to zoom to the feature extent (ArcGIS Server Service Pack 5 is required to zoom to the results).

Troubleshooting Tips

  • ArcGIS Server must be properly installed using an Administrators account and both the GIS Server and Web Applications post installs must be completed.
  • The ArcGIS SOM and SOC accounts (the defaults are ArcGISSOM and ArcGISSOC) must be a member of the Users group.
  • The ArcGIS Web Services account (the default is ArcGISWebServices) must be a member of the agsadmin group.
  • Be sure that your account (the person publishing the services) is a member of the agsadmin group.
  • It may be necessary to reboot your machine in order for permissions to take effect.
  • The ArcGISSOC account must have at least read-only access to the file-based data, the MXD files, toolboxes, and SDE connection files. If the local Users group has access, then the ArcGISSOC account also does because it is a part of the Users group. You would need to explicitly add ArcGISSOC if you wanted it to have a different set of permissions than Users (e.g., read vs read/write).
  • If these files (above) are on a separate network drive, then the folder must be shared and the ArcGISSOC account must have at least read access to this shared drive.
  • The ArcGISSOC account must have read/write access to the ArcGISServer directories. This is where the cache, jobs and output are written too.
  • Confirm that IIS is properly installed and running.
  • Confirm that the IIS virtual directories (argisoutput, arcgisjobs, and arcgiscache) exist and their permissions and local path are correct.
  • Confirm that a folder that matches your ArcGIS Server instance name exists. This folder is created during the post install of ArcGIS Server and is found by default in C:\Inetpub\wwwroot.
  • If you’ve made changes to the MXD (e.g., selection symbology), then you will need to stop and restart both the map service and the geoprocessing service.
  • If you’ve made changes to the model, then remove the tool layer, rerun the model and add the tool layer again. Be sure to follow the steps again as indicated in the steps above.

Working with ArcSDE Geodatabase Data Sources

When a connection is made to an ArcSDE geodatabase data source, an SDE connection file (*.SDE) is typically created in your Documents and Settings folder under Application Data\ESRI\. This folder would need to be shared and the ArcGIS Server SOC account would need to be given permissions to the folder. An easier way to manage this is to create a copy of the *.SDE file and copy it to the SelectTask folder as outlined below:

  1. Expand Database Connections. This is a node in the ArcCatalog Tree.
  2. Copy the SDE connection file. Right-click the SDE connection file and select Copy.
  3. Paste the SDE connection file into the SelectTask folder. Browse to and right-click the SelectTask folder and select Paste.
  4. Update all ArcMap ArcSDE geodatabase data sources to use the new connection file. This can be done via the layer properties Source tab. Right-click the layer, select properties. Select the Source tab, click the Set Data Source button and browse to the new connection file. Do this for each ArcSDE connection.

Video: Creating a web application with ArcGIS Server Manager

This video demonstrates how to use ArcGIS Server Manager to create a web application. You’ll find it useful if you’re getting started with ArcGIS Server, or if you just want to see what ArcGIS Server can do.

If you want to follow the steps in this video, you’ll need to install ArcGIS Server, create at least one map service, and log into Manager.

What other video topics would you find interesting for the blog or for the ArcGIS Server Help? Leave us a comment with your ideas.

Eclipse plug-in for debugging ArcObjects code

Divesh Goyal, a Product Engineer on the ArcGIS Server Java team, contributed this post:

As we approach another Developer Summit, I am glad to announce the availability of an Eclipse plug-in for ArcGIS Server and ArcGIS Engine Java developers that will greatly simplify debugging ArcObjects code.

About the plug-in

One of the most valuable tools that developers have at their disposal is a debugger through which they can step through code one statement at a time and inspect objects in the application. As many of you may already know, Java classes in the ArcObjects API are really only proxies to underlying COM ArcObjects. As a result, examining these proxies in the debugger only reveals their internal details and not the state of the ArcObjects. This makes it difficult to find out information such as the coordinates of a geometry, or the layers in a map service. Consequently, developers have to sprinkle their code with System.out.printlns and analyze traces on the console to get this information. This approach can be inconvenient and time consuming.

With this new Eclipse plug-in, Java developers can examine the state of the underlying ArcObjects right in Eclipse IDE's Debug Perspective by enabling the "Show Logical Structure" option on the Expression and Variables window. Here's an example of a Point object without the "Show Logical Structure" option enabled.

Without "Show Logical Structure"

This information provides little insight into the underlying ArcObject and is not helpful in reasoning through a workflow while debugging. Now here's the logical representation of the same object with the "Show Logical Structure" option enabled.

With "Show Logical Structure"

The logical representation presents more comprehensible information about the underlying ArcObject's state. This state is defined by the no-argument getter methods on it. You might sometimes see exception messages like "Exception Occurred: com.sun.jdi.InvocationException occurred invoking method" in the logical representation. This is normal and happens when some property of the ArcObject is not valid in the current context of the application.

The underlying ArcObjects could be running remotely in a separate process as in the case of ArcGIS Server web applications, or in the same process like in ArcGIS Engine applications. Thus, both Engine and Server developers can take advantage of this plug-in to debug their applications. I am very excited to share this plug-in with you, and look forward to your feedback. Code on!

How to get the plug-in

Follow these steps to download and install the plug-in from the EDN Website:

  1. In the Eclipse workbench, go to Help > Software Updates > Find and Install
  2. Select Search for new features to install, and click Next
  3. Create a New Remote Site for the URL "http://downloads.esri.com/EDN/java/plugins/eclipse"
  4. Enable this remote site and click Finish.
  5. Expand the EDN tree in Search Results, and select the ArcGIS Debug feature.
  6. Proceed to install the plug-in, and restart the workbench when prompted.
Posted by sterlingdq | 4 Comments
Filed under: ,

Meet the development teams at the 2008 ESRI Developer Summit

The ESRI Developer Summit is just days away and we are very excited to visit with you in person and learn about your ArcGIS Server projects. Many of us will be presenting technical sessions throughout the conference, but a good place to catch us all together is in the ESRI Showcase area during the "Meet the Development Teams" event. This is a time for us to informally mingle and hear about your experiences with ArcGIS Server. It's a great time to ask questions because we can easily introduce you to the team members whose expertise matches your area of interest.

You can meet these ArcGIS Server-related teams at the following times:

  • ArcGIS Mobile: Tuesday, March 18, 1:30 PM
  • ArcGIS JavaScript and REST APIs: Wednesday, March 19, 10:30 AM
  • ArcGIS Server .NET: Wednesday, March 19, 11:30 AM
  • ArcGIS Explorer: Wednesday, March 19, 2:30 PM
  • ArcGIS Server Java: Wednesday, March 19, 3:30 PM
Posted by sterlingdq | 0 Comments
Filed under:

Using Web ADF controls in an ASP.NET Web Part and SharePoint 2007

Rex Hansen, a Product Engineer for the .Net Web ADF, contributed this post:

The organization of information within a Web site can be challenging, especially when attempting to accommodate multiple end users with different work habits and capabilities. To support this situation, many Web sites utilize some form a portal technology which can provide a framework to modularize information and personalize its presentation. First introduced in ASP.NET 2.0, the Web Parts framework fulfills this need by providing an ASP.NET solution for portal developers. In general, ASP.NET Web Parts are controls that enable developers to encapsulate related functionality and give end users the ability to modify the content, appearance, and behavior of Web pages directly in a browser.

There are a number of options for building an ASP.NET Web Part in Visual Studio 2005: drag and drop Web Part controls in a page, build a Web user control, or create a custom Web Part control. In most cases, Web Parts are supposed to be added\removed at runtime during a user session, so dragging and dropping Web Part controls in a page at design-time does not offer a realistic solution. Web ADF controls will work in user controls, but not if the user control is in a Web Part. This problem is rooted in managing state and control ids for callbacks and cannot be overcome in ArcGIS Server 9.2. This leaves the last option, a custom Web Part control, which also gives you the most control over how the Web Part functions. There are two stages to consider here: support for Web ADF controls in a custom Web Part and deployment of the Web Part. In essence, getting Web ADF controls to work in a custom Web Part involves building a custom composite Web control that inherits from System.Web.UI.WebControls.WebParts.WebPart. Other than the standard pattern for creating a custom composite Web control, such as adding controls during CreateChildControls(), a number of Web ADF control specific issues must be considered:

  • In a custom Web Part, Web ADF controls are added dynamically. During a request to a page, the page and its controls (including the Web Part) iterate through their lifecycle. This becomes important when dealing with resources added to a resource manager. Once added, they are maintained in state and retrieved when the resource manager is recreated during the control lifecycle. So as not to keep re-adding resources every time the resource manager is created during the Web Part lifecycle, you need to check session state for the presence of the resource items. If present, do not re-add the resources.
  • A set of HTML hidden input elements (fields) are injected in the page at runtime if a Web ADF control is present. These fields store information about the current tool, map mode, and screen coordinates associated with tool interaction in the map, etc. One field, ESRIWebADFHiddenFields, stores a list of all the other field names (input values). This list is used to include the other field values in a callback request. If the Web ADF controls are added after the initial request to the page (such as what happens when a Web Part is added during a full postback to the page), the ESRIWebADFHiddenFields value is empty. As a result, tool interaction with the map is not functional. To workaround this issue, you need to manually set the value of the ESRIWebADFHiddenFields element. Note this will only affect Web Parts that are added after initial page load. If a Web Part is added during initial page load, these fields will be set correctly. Adding more than one Web Part with a Web ADF Map and Toolbar will likely cause conflicts and render some tool interaction with the map non-functional. There is no easy way to overcome this in 9.2. As a result, it is best to add only one Web Part with a Map-Toolbar per page.

On to working with SharePoint - Building a portal site which uses Web Parts can be time consuming; integrating the site into other enterprise systems can be difficult and inefficient; and lastly, managing the site can be overly complex and convoluted. In an attempt to manage enterprise content, intelligence and search systems effectively, Microsoft has created Microsoft Office SharePoint Server 2007, or MOSS for short. MOSS is good for what it claims to do (be an all encompassing enterprise system for sharing information), but it is not simple. Like many software products, more capability means greater complexity. One option for customizing the presentation of content and providing access to business logic is developing custom ASP.NET Web Parts and deploying them on a SharePoint server. An ASP.NET Web Part can be deployed relatively easily with SharePoint 2007. The SharePoint SDK includes a WebPart class which derives from the ASP.NET WebPart. The SharePoint WebPart class offers a few benefits, such as cross-page and non-WebPart connections, which primarily facilitate backward compatibility with SharePoint 2003. For more information on Web Part development with SharePoint 2007, Scott Guthrie provides a bevy of valuable information and links in his blog post Writing Custom WebParts for SharePoint 2007. You can use Sahil Malik’s walkthrough at the beginning of the post to get started creating a custom ASP.NET Web Part.

There are a few issues to consider when deploying a Web Part that contains Web ADF controls in SharePoint 2007:

  • SharePoint 2007 was designed to function using the full page postback pattern. As a result, tools in a Web ADF Toolbar may need to trigger a full postback within a custom Web Part to communicate with other parts in the page. Unfortunately the postback event never gets to the tool, so some additional code is required to raise the post back event to the correct control (e.g. Map). See the sample code for more details.
  • The SharePoint 2007 server may not have session state enabled, which is necessary for the Web ADF controls to function. If not enabled, SharePoint will return a fairly ambiguous error when attempting to add your custom Web Part to the SharePoint server.

The 9.3 Web ADF will resolve many of the limitations and issues encountered when working with 9.2 Web ADF controls in a Web Part. 9.3 Web ADF controls will be fully supported for use in custom user and composite controls, both of which may be deployed as a Web Part. Multiple Web Parts containing multiple Web ADF controls can function within the same application. The use of ESRIWebADFHiddenFields will be reduced if not removed. And full postbacks initiated by toolbar items will be supported internally.

The sample code includes two projects. The class library project contains the custom Web Part with a MapResourceManager, Map and Toolbar control. The file system Web application contains a simple aspx page designed to emulate a runtime scenario where an end user wants to add a Web Part within the current session. Note, to personalize the page (e.g. add a Web Part at runtime) the current session must be associated with an authenticated user. By default, a file system Web site will used integrated authentication. If deploying as a Web application in IIS, you will need to disable anonymous access to the Web application in IIS. Enabling integrated authentication may offer the easiest solution since you do not need to configure or explicitly set authentication details, instead the authenticated user will be the user account under which the client (browser) is running.

The default personalization provider for ASP.NET 2.0 is SQL Express. If you do not have SQL Express installed, a personalization store will not be created (upon initial execution of the application) and an error will be returned when attempting to add the custom Web Part to the page at runtime. To alleviate this requirement, I have added a custom personalization provider that uses text files. The code, markup, and discussion for this technique is provided here: http://msdn2.microsoft.com/en-us/library/aa479037.aspx

Download the sample code

Creating a utility library (Part II): Creating and adding resources

Morten Nielsen, a developer on the .NET Web ADF team, contributed this series:

This post is the second in a series on creating a set of reusable helper methods that tries to make some of the common developer tasks when working with the .NET Web ADF easier. This specific article shows how to create a few static methods that you can use to create, add and initialize resources to your map.

The simplest way of creating resources is by using the resource definition string. If you use the designer in Visual Studio and add a resource to the MapResourceManager, then switch to source view, you can see what the resource definition string looks like:

<esri:MapResourceManager ID="MapResourceManager1" runat="server">
<ResourceItems>
<esri:MapResourceItem Definition="<Definition DataSourceDefinition="http://myserver/arcgis/services" DataSourceType="ArcGIS Server Internet" Identity="" ResourceDefinition="(default)@Counties" DataSourceShared="True" />"
DisplaySettings="visible=True:transparency=0:mime=True:imgFormat=PNG8:height=100:width=100:dpi=96:color=:transbg=False:displayInToc=True:dynamicTiling="
Name="MapResourceItem0" />
</ResourceItems>
</esri:MapResourceManager>

The definition string has been encoded to remove quotes and < and > characters, so the "real" definition string for the above actually reads:

<Definition DataSourceDefinition="http://myserver/arcgis/services" DataSourceType="ArcGIS Server Internet" Identity"" ResourceDefinition="(default)@Counties" DataSourceShared="True">

We can create a resource based on this string using the constructor on GISResourceItemDefinition:

MapResourceItem mri = new MapResourceItem();
mri.Definition = new GISResourceItemDefinition(definition);

Let’s take this concept further and create two helper methods for inserting and adding resources to the MapResourceManager:

public static class Common
{
public static MapResourceItem AddResource(string definition, string name, MapResourceManager mapResourceManager)
{
return InsertResource(definition, name, mapResourceManager, mapResourceManager.ResourceItems.Count);
}
public static MapResourceItem InsertResource(string definition, string name, MapResourceManager mapResourceManager, int index)
{
//Ensure unique name by appending a number to it if it already exists
string uniqueName = name;
int counter = 1;
while (mapResourceManager.ResourceItems.Find(uniqueName) != null)
{
uniqueName = String.Format("{0}_{1}", name, ++counter);
}
//Create resource
MapResourceItem mri = new MapResourceItem();
mri.Definition = new GISResourceItemDefinition(definition);
mri.Name = name;
//Add and initialize resource
mapResourceManager.ResourceItems.Insert(index, mri);
IMapResource mr = mapResourceManager.CreateResource(mri);
mapResourceManager.Initialize(mri);
return mri;
}
}

The library that you can download takes this helper method a little further. Instead of using the MapResourceManager as a parameter, it takes the map instead. The method will take care of zooming to the first resource you add, return error messages if the resource was not available, etc. I also added several overloads to give you more fine-grained control of the resources you added.

So this gives us an easy way of adding any kind of map resource to the Map. By analyzing the definition string we can also create some data source-specific methods that will create the definition strings based on for instance the server endpoint and service name. Here are a few for ArcGIS Server Internet, ArcGIS Server Local and ArcIMS:

public static class ArcGISServer
{
public static MapResourceItem AddLocalResource(string servername, string servicename, MapResourceManager mapResourceManager)
{
return AddLocalResource(servername, servicename, mapResourceManager, string.Empty);
}
public static MapResourceItem AddLocalResource(string servername, string servicename, MapResourceManager mapResourceManager, string identity)
{
string definition = string.Format("<Definition DataSourceDefinition=\"{0}\" DataSourceType=\"ArcGIS Server Local\" Identity=\"{1}\" ResourceDefinition=\"(default)@{2}\" DataSourceShared=\"True\" />",
servername, identity, servicename);

return Common.AddResource(definition, servicename, mapResourceManager);
}
public static MapResourceItem AddHttpResource(string serverURI, string servicename, MapResourceManager mapResourceManager)
{
return AddHttpResource(serverURI, servicename, mapResourceManager, string.Empty);
}
public static MapResourceItem AddHttpResource(string serverURI, string servicename, MapResourceManager mapResourceManager, string identity)
{
string definition = string.Format("<Definition DataSourceDefinition=\"{0}\" DataSourceType=\"ArcGIS Server Internet\" Identity=\"{1}\" ResourceDefinition=\"(default)@{2}\" DataSourceShared=\"True\" />",
serverURI, identity, servicename);

return Common.AddResource(definition, servicename, mapResourceManager);
}
}

public static class ArcIMS
{
public static MapResourceItem AddResource(string servername, int port, string servicename, MapResourceManager mapResourceManager)
{
string definition = string.Format("<Definition DataSourceDefinition=\"{0}@{1}\" DataSourceType=\"ArcIMS\" Identity=\"\" ResourceDefinition=\"(default){2}\" DataSourceShared=\"True\" />",
servername, port, servicename);

return Common.AddResource(definition, servicename, mapResourceManager);
}
}

If we combine this with the previous post on how to simplify callback results, we can easily create a callback button that adds a resource, updates the table of contents etc.

protected void CallbackButton1_Clicked(object sender, EventArgs args)
{
//Add ArcGIS Server resource
ArcGISServer.AddHttpResource("http://myserver/arcgis/services", "Counties",
Map1);

Toc1.Refresh(); //Refresh TOC

//Disable the CallbackButton so user cannot click the button again
CallbackButton1.CallbackResults.Add(
Callbacks.CreateJavaScript(
String.Format("document.getElementById('{0}').disabled = -1;",
CallbackButton1.ClientID)));

//Ensure CallbackResults from all controls are returned to the client
WebADF.Utilities.Callbacks.AutoMoveCallbackResults();
}

Download the Web ADF Utility Class

Posted by sterlingdq | 4 Comments
Filed under: , ,

Creating a utility library (Part I): Simplify working with callback results

Morten Nielsen, a developer on the .NET Web ADF Team, contributed this series:

This post is the first in a series on creating a set of reusable helper methods that tries to make some of the common developer tasks when working with the .NET Web ADF easier.

The AJAX behavior of the .NET Web ADF has been built on top of the ASP.NET Callback Framework. The framework allows us to do a call from the browser to a server-side web control carrying a string as argument, perform some processing on the server based on this argument, and then return a new string to a javascript method on the client. The argument string coming from the browser could for instance be a key/value pair separated by ampersands, but can technically be anything you want, for instance a JSON formatted object that you later deserialize on the server.

Each web control has its own client-side method that can be executed to do the callback to the server-side instance of the control. The Web ADF’s web controls all have a ‘CallbackFunctionString’ property that returns the javascript method needed to do this callback to server.

Most of the Web ADF’s web controls use the ‘CallbackResult’ type to specify what we want to send back to the client. The Callback Result basically consists of a control id if applicable, an argument type and a set of parameters. The ‘ToString()’ method on the ‘CallbackResultCollection’ serializes this to a return string that the client-side method ‘processCallbackResults’ knows how to parse.

An important thing to remember here is that the control that received the callback is the one responsible for returning all the callback results. If you for instance use the CallbackButton to call back to the server page, make some changes to the map, refresh the Table of Contents, etc, you are responsible for picking up all the callback results from the various controls that you changed and return them though the CallbackButton’s CallbackResults collection. The way this usually is done is by copying the callback results from all other modified controls in the ‘GetCallbackResults’ method, or in the case of the CallbackButton in its click handler method. Example:

CallbackButton1.CallbackResults.CopyFrom(Map1.CallbackResults);
CallbackButton1.CallbackResults.CopyFrom(Toc1.CallbackResults);
CallbackButton1.CallbackResults.CopyFrom(TaskResults1.CallbackResults);

Where this can get tricky is that you might not realize that certain controls contain callback results. For instance if you add a new ResourceItem to the MapResourceManager, that Map will contain new CallbackResults, because it automatically listens for the ResourceItemAdded event.

Since it is possible to figure out what control did the callback, and also search for all controls that contain results, why not create a small utility method that does this search and copy them over for you? This way you just do a simple call to a static method instead of doing all the copying.

The first step is finding the control that performed the callback. The page request will contain the unique ID of the control stored in the parameter ‘__CALLBACKID’, and we can use the UniqueID to search for the control in the page:

public static Control GetCallingControl()
{
HttpContext context = HttpContext.Current;
if (context == null) return null;
Page page = context.CurrentHandler as Page;
if (page == null) return null;
else if (page.IsCallback)
{
string controlid = context.Request.Params["__CALLBACKID"];
Control c = page.FindControl(controlid);
return c;
}
else return null; //Not an asyncronous request
}

The next step is to search for all controls in the page that contain callback results. We do this by doing a recursive search through the page tree to find any control that inherits from ESRI.ArcGIS.ADF.Web.UI.WebControls.WebControl or ESRI.ArcGIS.ADF.Web.UI.WebControls.CompositeControl and copy the CallbackResults. The recursive search will clear out any CallbackResults that have been copied over, so you don’t risk copying the same results if you do this search more than once:

/// <summary>
/// Searches for and moves all <see cref="CallbackResults"/> to the
/// calling control's <see cref="CallbackResultCollection"/>.
/// Note that callbackresults on all other controls will be cleared out.
/// </summary>
/// <param name="page">Page where the asyncronous call originated.</param>
public static void AutoMoveCallbackResults()
{
Control callingControl = GetCallingControl();
if (callingControl == null)
return;
CallbackResultCollection results = null;
if (callingControl is WebControl)
{
results = (callingControl as WebControl).CallbackResults;
}
else if (callingControl is CompositeControl)
{
results = (callingControl as CompositeControl).CallbackResults;
}
else return;

autoMoveCallbackresultsRecursive(callingControl.Page.Controls, results, callingControl);
}

private static void autoMoveCallbackresultsRecursive(ControlCollection controls, CallbackResultCollection results, Control callingControl)
{
foreach (Control control in controls)
{
if (control is WebControl && callingControl != control)
{
CallbackResultCollection controlresults = (control as WebControl).CallbackResults;
results.CopyFrom(controlresults);
controlresults.Clear();
}
else if (control is CompositeControl && callingControl != control)
{
CallbackResultCollection controlresults = (control as CompositeControl).CallbackResults;
results.CopyFrom(controlresults);
controlresults.Clear();
}
if (control.Controls.Count > 0)
{
autoMoveCallbackresultsRecursive(control.Controls, results, callingControl);
}
}
}

All you need to do now is call AutoMoveCallbackResults after doing processing and all controls in the page that contains callbackresults will automatically be copied to the calling control’s callbackresult collection:

protected void CallbackButton1_Clicked(object sender, EventArgs args)
{
//Do your processing and generate callback results...
//...

WebADF.Utilities.Callbacks.AutoMoveCallbackResults();
}

You can download the code below. We also included some static helper methods for creating some of the standard callback results. Example:

WebADF.Utilities.Callbacks.CreateJavaScript("alert('Hello World');");
WebADF.Utilities.Callbacks.CreateSetInnerContent(this, "This is the inner content of this control");
WebADF.Utilities.Callbacks.CreateSetImageSource(myImage, "http://www.mydomain.com/images/picture.jpg");

Download the Web ADF Utility Class

Posted by sterlingdq | (Comments Off)
Filed under: , ,

Ask the Development Team

In our first year anniversary post, many of you liked the idea of having an "Ask the development team" thread, in which you could post questions about ArcGIS Server and we would post answers. This week we’re giving it a try.

How it works

  • Post your question as a comment to this post.
  • The blog moderators will select relevant questions and send them to the appropriate members of the development team.
  • Development team members will post comments in reply. We’ll try to answer all questions that are appropriate.
  • The thread will be open for questions through Friday, February 22. We’ll continue posting responses after that date.

    Question

Please note

The development team cannot address questions about pricing or licensing. Please contact your ESRI representative if you have a question about that.

Also, we may direct you to ESRI Support if your question is related to a bug or unexpected behavior. They are better equipped to help you troubleshoot the problem.

Update: This post is now closed to new questions but we will attempt to answer all of the questions we received while the thread was open.
 

Posted by sterlingdq | 56 Comments
Filed under:

ArcGIS JavaScript and REST APIs: "Super Tuesday" results

Boy, time goes fast and the Developer Summit is already upon us. This year's conference coincides with the release of ArcGIS 9.3 Beta. We are very excited to share with you all the work we put into this release. We have improved the documentation in our SDKs, made map caching easier, added tools to manage security, optimized the web mapping applications, and many other things.

Today, we just want to talk a bit about the new ArcGIS JavaScript and REST APIs. We built this new JavaScript API because many of you have asked for a simple way to share your GIS data and tools over the internet. Here is an example built on top of the ArcGIS JavaScript API.

We have kept this ArcGIS JavaScript API very simple; to make sure that everyone could take advantage of it without being a hardcore programmer. But at the same time, you'll quickly learn that this API will let you go beyond mapping and incorporate advanced GIS functionality into your applications. You’ll have access to a complete online SDK with many samples for getting started and using this API. The example above goes beyond your simple "Hello World" mapping application and includes interactive charting of feature attributes using the Google Chart API.

For those of you who are familiar with REST, at 9.3 you'll be able to REST-enable your GIS services. Once you enable REST on your GIS services, you’ll be able to access them with any scripting language such as Python, PHP, Ruby and why not, with JavaScript. In fact, the ArcGIS JavaScript API is a collection of JavaScript libraries that use ArcGIS REST resources. We built it for you so you can get the most common tasks, accessing map, geoprocessing, and geolocator services, done with minimum effort. For those who want to go the extra mile or use REST directly we are fully documenting the REST API as well.

We look forward to seeing you at the Developer Summit where you can learn more about ArcGIS Server 9.3. In the meantime, if you are curious, listen to these podcasts about sessions on ArcGIS Server REST services and ArcGIS JavaScript APIs.

Mark your calendars: March 17-20 in Palm Springs

-The ArcGIS Server Development Team

Deconstructing the map cache tiling scheme (Part II): Working with map caches programmatically

This post explains ways to access cached map service tiles programmatically. This is useful if you don’t have access to a Web ADF Map control but you still want to quickly retrieve map images for a certain area. Another reason to retrieve tiles programmatically is if you want to overlay them on other services, such as Google Maps…but that’s a topic for another post. Today we’ll be focusing on how to get a tile of interest.

Before you continue, you should be familiar with how the tiling scheme works. See the archived post Deconstructing the map cache tiling scheme (Part I) if you need a review.

There are lots of ways to retrieve tiles from an ArcGIS Server map cache. The way that you use is affected by several factors which are listed here. This post shows two of the fastest ways to retrieve tiles:

  1. Using a simple HTTP Get request to the virtual cache directory of the Web server
  2. Requesting a tile from the ArcGIS Server map service tile handler

First let’s look at an example of each URL.

Virtual cache directory

If the virtual directory is exposed, you can request a tile from the Web server via the public cache directory. Here’s an example of a URL for a tile retrieved from the virtual cache directory:

http://serverx.esri.com/arcgiscache/dgaerials/Layers/_alllayers/L00/R0000029f/C00000280.jpg

Let’s break this URL down.

  • http://serverx.esri.com/arcgiscache: Root URL of one of your virtual cache directories
  • dgaerials: Map service name
  • Layers: The name of the data frame of interest in the map service
  • _alllayers: All layers in the map. This is always the case for single fused caches, if you have a multi-layer cache it will correspond to the specific group layer that was cached in the multi-layer cache
  • L00: Level ID
  • R0000029f: Cache tile row in padded hexadecimal format
  • C00000280.jpg: Cache tile column in padded hexadecimal format

To programmatically discover the virtual cache directory you can call:

MapServer.GetVirtualCacheDirectory(defaultMapName,layerNumber);

Where defaultMapName is the data frame name and layerNumber is -1 for fused caches or the index of the layer of interest for multilayer caches.

Map service tile handler

If the virtual directory is not exposed, you can still request a tile from the web server, but in this case you need to use the map service tile handler. Here’s an example of a URL for a tile retrieved by the map service tile handler:

http://serverx.esri.com/arcgis/services/dgaerials/MapServer?mapName=Layers&format=JPEG&level=0&row=671&column=640

Here is the breakdown of this URL:

  • http://serverx.esri.com/arcgis/services/dgaerials/MapServer: URL to the map service of the cache
  • mapName=Layers: Map name of the cached map service
  • format=JPEG: Image type of the cache
  • level=0: Level ID
  • row=671: Cache tile row in decimal format
  • column=640: Cache tile column in decimal format

The SOAP API and cached tiles

The accompanying code example shows how to use the ArcGIS Server SOAP API to get information about a cache and create a URL to retrieve a specific tile. You don’t need any ESRI software installed to program with the SOAP API. You just need a running ArcGIS Server whose services are enabled for Web access. In Microsoft Visual Studio, you can add a Web reference to one of these services and access a number of methods.

If you’re not familiar with adding a Web reference to your project or working with SOAP, you should definitely read the ArcGIS SOAP API Overview. It also explains how the SOAP API uses proxy classes and value objects to expose GIS functionality through Web services. Some of the most important value objects to know about when working with cached map services in the SOAP API are:

  • TileCacheInfo: Contains spatial reference information, as well as the width and height of the tile in pixels.
  • LODInfo: Contains information about the resolution and scale for a level of detail in the cache. You can access an array of LODInfos from TileCacheInfo.
  • TileImageInfo: Contains information about the cache image format

Getting a tile

When using the SOAP API, you might be tempted to get a tile by calling MapServerProxy.GetMapTile( ). It’s actually faster to construct the URL and get the tile directly, as we show in the code example.

Finding the specific tile that covers your point of interest requires a little bit of math. These are some important things to know:

  • The tiling origin

    Remember that the tiling origin is the upper-left point of the tiling scheme grid. You can get it using TileCacheInfo.TileOrigin.

  • The width and height of a tile in ground units

    You can get this by multiplying the tile width (TileCacheInfo.TileCols) or height (TileCacheInfo.TileRows) by the resolution (LODInfo.Resolution)

  • The row and column of your point of interest on the tiling grid

    Columns are zero-based and increase as you move to the right from the tiling origin. Rows are also zero-based and increase as you move down from the tiling origin.

    For example, in the map below, if you were traveling from the tiling origin to Salt Lake City, you would have to move five tiles to the right and four tiles down. This puts Salt Lake City in Column 4, Row 3.

Tiling grid 

Here’s some math you can use to find any tile:

Column = Floor((Point of interest X – Tile origin X) / Ground width of a tile)

and

Row = Floor((Tile origin Y – Point of interest Y) / Ground height of a tile)

Example

This example application does the following things using the ArcGIS Server SOAP API:

  1. Connects to a map service and discovers whether it has a cache
  2. Computes the number of tiles needed to cover the map horizontally and vertically. This is useful if you have an empty tiling scheme and you want to find out how many tiles will need to be created as part of the caching process.
  3. Creates a URL to get the center tile directly from the virtual cache directory
  4. Creates a URL to get the center tile using the tile handler

See the example application

Download the code (See authors' comments in Default.aspx.cs)

-Jeremy Bartley and Sterling Quinn

More Posts Next page »