Pages

Wednesday, June 6, 2012

A server object extension for performing dynamic segmentation


This post explains how I extended an ArcGIS Server map service to calculate the location of mile markers along a user-submitted polyline. This type of calculation of measurements along a line is called dynamic segmentation.
You can try it out in this app by drawing a polyline. The mile markers will appear on the line when you complete your sketch. You can alternatively choose to place kilometer markers.
Example web app for placing distance markers along a line 
In order to get my server to perform dynamic segmentation, I had to write a server object extension (SOE). This post explains what an SOE is, and how I went about designing this particular extension. If you like, you can download the source code and follow along.

What is an SOE, and why is one useful for this particular problem?

ArcGIS Server map services have a list of methods that they can perform, such as drawing a map, querying geographic features, or returning a list of layers. These methods cover the most common things that someone might do with a map.
Sometimes you may need your service to do something that’s not available with one of these out of the box methods. SOEs allow you to extend the map service with methods that use ArcObjects, fine-grained programming components that expose ArcGIS functionality. This really opens up the realm of things you can do with a service, since advanced ArcGIS functions like dynamic segmentation can be achieved through ArcObjects.
ArcObjects has an extensive object model that can be daunting to beginning programmers. If you’re worried about writing ArcObjects, check whether you can put your workflow into a model in ModelBuilder and publish a geoprocessing service. This is sometimes an easy alternative to building an SOE. In my situation, I could not find an easy way in ModelBuilder to take a single input polyline, assign m-values to it, and locate the mile markers. I had a good case for an SOE.

Designing the REST schema

One nice thing about SOEs is that they can be exposed through REST web services, allowing them to be easily used by the ArcGIS web APIs for JavaScript, Flex, and Silverlight. The ArcObjects SDK contains templates (Visual Studio) or wizards (Eclipse) to help you get started writing a REST web service. I planned to write my SOE with C# in Visual Studio, so I started with a template. The first thing I needed to do was build the REST schema for the web service.
A REST web service SOE exposes both resources and operations. Resources are items of information that can be returned by the SOE. Operations are things that the SOE can do. When you write a REST SOE, you need to determine which resources and operations you are going to expose. The REST SOE template has some example ones stubbed out for you.
In my case, I kept it real simple. I had one resource (the required root resource) which did not return any information beyond the name of the SOE, and one operation which located the mile markers. I called this operation LocateMarkers. I also had to define the parameters that LocateMarkers would take, which were a polyline graphic and a segment length (allowing me to find kilometer markers, too).

Writing the resource and operation handlers

Each resource and operation in your SOE must have a handler function. A typical operation handler function for a REST SOE does the following things:
  • Deserializes the web service request, which comes in as JSON. Going from JSON to ArcObjects types such as IPolyline can be tricky, so an SOESupport library is referenced in the template that has some deserialization and conversion classes for you.
  • Calls into your ArcObjects code to perform whatever GIS functions you need.
  • Serializes your results into JSON for the web service to send back as a response. Again, you can use the conversion and serialization classes in SOESupport to help you with this.
If you want to watch a more detailed explanation of this process with an example, see the workshop Extending ArcGIS Server Services using .NETrecorded from the 2011 Esri Developer Summit.
I followed these steps for my LocateMarkers operation handler. I began by deserializing the input polyline and segment length. I converted the polyline to IPolyline, assigned m-values to it, and added it to an in-memory feature class I had created. At that point, I was able to use methods in the ArcObjects Location library to find the marker locations given the input segment length. Finally, I had to serialize those locations into JSON so that they could be sent back as a web service response.
All of the above wound up taking a fair amount of code. I found that the ArcObjects Location library was well-documented when it comes to locating points with dynamic segmentation. Other things took longer to figure out, such as how to assign m-values to a single polyline. Thanks to the many generations of Esri developer documentation archived online, I was able to find answers to get past each hurdle. You might have a similar experience when developing your SOE.

Using the SOE in a web app

The most exciting thing about SOEs is that they allow your web applications to tap into advanced GIS functionality. With the flood of simple “points on a map” apps out there today, some may question whether any advanced GIS operations or analysis can be performed on the web. REST SOEs demonstrate that all the power of ArcObjects is accessible to your web apps.
Each web API has its own way of calling SOEs, but the common aspect of each technique is that they are making web service requests. The way to call an SOE from the ArcGIS API for JavaScript, for example, is to set up a JSON object with all the input parameters. Once you’ve got the parameters, use the esri.request() method included with the API to make the call to the SOE. You can then write handler functions to work with the response JSON. In my case, the handler function cycles through the returned JSON points and adds them to the map as graphics.
Using the ArcGIS API for JavaScript, I created the simple app mentioned at the beginning of this post. It allows the user to sketch a polyline on the screen and see the resulting distance markers. The app’s intent was to test the speed and usability of my SOE in a web setting.
I was pretty happy with how fast this SOE could place even hundreds of points. To test it yourself, zoom out until you can see the whole county, then sketch a very long freehand line (like a spiral). Usually the points are placed in under a second. (Note that I have placed a limit on this particular service to place only 500 points at a time.) This demonstrates that when ArcObjects code is invoked directly on the server through an SOE, it can run very quickly.

Download the example

There are a number of aspects of SOE development and deployment that I was not able to cover in this post, such as SOE properties and registration, and all the ArcObjects logic used in performing the dynamic segmentation. I have made all the source code of both the SOE and the JavaScript app available on ArcGIS Online so you can explore it yourself. The download comes with a detailed readme file.

No comments:

Post a Comment