Where is IServerLayer?

Anytime you use an API you are going to find things that you like and things you want to work differently. After working against the Web ADF I was really pleased with the work the teams at Esri did on the Web APIs, particularly the Silverlight API which I have used on a variety of projects over the past 3 or so years. That isn’t to say it doesn’t have any quirks or issues, that’s just the nature of the beast, especially as more and more functionality is added as well as trying to prevent breaking changes to maintain backwards compatibility. I actually hope they make the changes they want with the next major release even if it does mean breaking changes as house keeping and replacing legacy code is better than working around it.

One of the more frequent issues I run into using the Silverlight API is converting server side layers into another type so I can use them for some custom operation e.g. running an identify task for each server side layer in the map. I determine a layer as being server side if it has a Url property. Here’s a way you can easily convert your layers with the aim of being able to extend the code for your own use.

First we’ll define our IServerLayer interface. This could easily be part of the core API which would take a lot of the hassle away here 🙂

public interface IServerLayer
{
    /// <summary>
    /// The url of the service endpoint.
    /// </summary>
    string Url { get; set; }

    /// <summary>
    /// The proxy url used by the service.
    /// </summary>
    string ProxyUrl { get; set; }
}

now the implementation and conversion

public class ServerLayer : IServerLayer
{
    public ServerLayer(string url, string proxyUrl)
    {
        if (string.IsNullOrEmpty(url))
            throw new ArgumentNullException("Url", "The layer url cannot be null.");
        Url = url;
        ProxyUrl = proxyUrl;
    }

    public static implicit operator ServerLayer(Layer layer)
    {
        if (layer is ArcGISTiledMapServiceLayer)
        {
            var tiledMapServiceLayer = (ArcGISTiledMapServiceLayer)layer;
            return new ServerLayer(tiledMapServiceLayer.Url, tiledMapServiceLayer.ProxyURL);
        }

        if (layer is ArcGISDynamicMapServiceLayer)
        {
            var dynamicMapServiceLayer = (ArcGISDynamicMapServiceLayer)layer;
            return new ServerLayer(dynamicMapServiceLayer.Url, dynamicMapServiceLayer.ProxyURL);
        }

        if (layer is ArcGISImageServiceLayer)
        {
            var imageServiceLayer = (ArcGISImageServiceLayer)layer;
            return new ServerLayer(imageServiceLayer.Url, imageServiceLayer.ProxyURL);
        }

        if (layer is FeatureLayer)
        {
            var featureLayer = (FeatureLayer)layer;
            return new ServerLayer(featureLayer.Url, featureLayer.ProxyUrl);
        }

        // TODO : add others layers you want to support, such as KmlLayer

        throw new NotSupportedException(string.Format("The type '{0}' for layer '{1}' is not supported", layer.GetType(), layer.ID));
    }

    public string Url { get; set; }

    public string ProxyUrl { get; set; }
}

and finally an example of calling it

foreach (var layer in MyMap.Layers)
{
    try
    {
        LayersList.Items.Add(string.Format("Url is {0}, for {1}", ((ServerLayer)layer).Url, layer.GetType()));
    }
    catch (NotSupportedException ex)
    {
        LayersList.Items.Add(ex.Message);
    }
}

which results in

serverlayer

This is just one way of achieving greater consistency throughout your code. As always thanks for reading and any feedback is appreciated.

Advertisements

4 comments

  1. I like this solution, it’s clean. We’ve created some extension methods for ILayer that will give us the Url or ProxyUrl if one exists.

    public static string Url(this ILayer source) {… }
    public static string ProxyUrl(this ILayer source) { … }

    I agree that the Silverlight/WPF API should already have this.

  2. Hi, I’m trying to extend this sample http://help.arcgis.com/en/webapi/silverlight/samples/start.htm#AddLayerDynamically
    such that on click of the button the Application checks the type of service (Tiled or dynamic) If dynamic, check if there are any subLayers and list them hierarchically if tiled set as mother node in the tree ToC-like display with check boxes. Very new to silverlight and I’m having major issues. Would what you’ve provided here work? If so could you help me out? Many thanks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s