odoe

Find the right layer in your Maps

Blog Post created by odoe on May 20, 2015

esri-list.jpg

Recently I was asked about how one might go about working with finding layers in the map. This is one of those things that can be approached in different ways.

 

  1. Manage layers (Tiled/Dynamic/Feature) added to map.
  2. Find layers in a service by Name, not just ID.

 

In particular is number 2 above. I've been there. You put an awesome app together, you've got queries built, maybe some custom search functionality, cool spatial analyses based on the returned results. things are working awesome and then someone adds a new layer to a map service and all your hopes and dreams come shattering around you. Yeah, it happens. The needs of a map service change and services can be used for multiple applications. If you are the one handling the server updates as well as development, it's annoying, sure, but not so bad to maintain. If you are the poor soul who is at the will of the ArcGIS Server admin who seems to relish in rearranging the order of the layers just to feast on your tears, I feel for you.

 

Managing Map Services

I can't offer you some grand solution or quick fix, but I can offer up some tips on how to get to know your data and ways you can search it. Let's start simple, just managing services in a map.

 

The documentation has a real easy sample on how to get all the layers from map. This is a great first step, because now you are not dependent on layerIds to find your data. Fantastic! But you should also get in the habit of providing an id property to your layers when you create them.

Something like this:

var dLayer = new ArcGISDynamicMapServiceLayer(url, {
  id: "HydroStuff" // useful for searching later on
});

 

This lets you do this:

var layer = map.getLayer("HydroStuff");

 

Ok, not groundbreaking stuff I know, but when working with your apps, this makes it very simple to make sure you are doing queries or selections on the correct layers. You can also provide the id in the JSON of the WebMap Spec of the layer. It should be noted, the docs say the id is for the position in the map, but so far (crosses fingers) I haven't had issue tweaking this on my own.

 

That's all pretty cool, but you can also get a little fancy with your searching if the names are similar or you don't trust your ArcGIS Server admin not to mess with the names too...

var getLayersFuzzySearch = function(m, term) {
  var queries = arrayUtils.filter(m.layerIds, function(x) {
    return x.toLowerCase().indexOf(term.toLowerCase()) > -1;
  });
  return arrayUtils.map(queries, function(x) {
    return m.getLayer(x);
  });
};
var fuzzy = getLayersFuzzySearch(map, "hydro");

 

This may not be ideal in all situations, but it does come in handy.

 

Getting to the layer of the matter

But how, you ask, do you deal with actual layers in a service that may change position? Well, I'll throw this little sample out there to give you an idea.

var layerMap = {}; // A layer map to hold a reference to all layers by name
// List out the layers in a service
// Useful when working with FeatureServices
esriRequest({
  url: url,
  content: { f: "json" },
  handleAs: "json",
  callbackParamName: "callback"
}).then(function(x) {
  return x.layers;
}).then(function(x) {
  return arrayUtils.map(x, function(item) {
    layerMap[item.name] = item.id; //dictionary that sucker!
    return domConstruct.create("li", {
      "data-layer-id": item.id,
      innerHTML: "ID: " + item.id + " | Name: " + item.name
    });
  });
}).then(function(x) {
  var node = document.getElementById("layer-items");
  arrayUtils.map(x, function(item) {
    node.appendChild(item);
  });
});

 

This little sample writes the layers out to the page for you, but what is cool is the layerMap object being populated. This is now set up with the names to point to layer ids. So if you want to get the id of a layer, just reference it by name, such as layerMap["Rivers"], which will return 1 in this scenario.

 

If your ArcGIS Server admin is changing positions of your layers and the names, you probably got them a lousy Secret Santa gift and should make amends.

 

I put a quick JSBin to help demonstrate some of the stuff above. There is no super solution to reference layers by name in a service most of the time, but the data is there for you to write up a solution of your own. The above just happens to be how I like to handle it when I'm unsure of finalness (that can't be a real word) of the map services to mitigate any pains down the road. If you have some other sleeker solutions, I'd love to see them. Your pains may have been greater than my own.

 

For more geodev tips tricks, check out my blog.

Outcomes