Toggle Layer Visibility Using URL Parameters in Web App Builder Developer Edition

ESRI’s developer edition of their Web App Builder (WAB) is a handy stand-alone tool for creating web mapping apps. While the WAB is a tool for building an app without needing to code anything, the developer edition allows users to create their own widgets and extend current functionality or themes. Even with this capability, however, there are some situations where the pre-formed development framework just doesn’t go far enough.

This was the situation I found myself in recently when trying to use the WAB to replace our custom built web map viewer at work. Our current viewer interfaces with a few third party apps by accepting url parameters that turn on or off layers and query various layers. The WAB does allow for querying layers using url parameters but it doesn’t have the ability to toggle layers using the url method.

I searched around the internet trying to find someone who has solved this problem but never found a useable solution. ESRI provides url parameter layer visibility functionality on their ArcGIS Online platform but this hasn’t made it to the WAB Developer Edition yet. I’m not sure when or if it will.

Since layer toggling is a must-have functionality for us I decided to work up a solution myself. Thankfully, the developers at ESRI named the WAB’s url handling module mapUrlParamsHandler.js so it was pretty easy to figure out what needed to be modified.

Parameter Modeling

To fix my problem I just had to add one new function. The actual turning on and off of the layers in this function was taken care of by the WAB api. The biggest concern for me was deciding on how the parameters should be passed in the url so they would be easy to use on the client side and easy (and fast) to process on the server.

I considered using the esri ArcGIS Online model of ?layers=show:0,1,2,3 for passing in layer visibility parameters. However, this becomes very cumbersome when considering showing and hiding both layers and sublayers. It would look something like ?layers=show:0,1.0-2-5,3,4;hide:6,7 or some other cryptic looking mash of numbers and characters. I wasn’t even sure the online api accepted a hide parameter. They don’t show one in their documentation.

I then considered using two separate parameters for showing and hiding (?showLayers=1,2,3&hideLayers=1,2,3) but this just adds more complexity to the code on the back side as well as the parameters the client has to plug in. Ultimately I settled on using a single parameter called layers. But then I needed to decide how to reference those layers.

If I used a zero based index url parameter list, then if the layers in the web map ever change position, I’ll have to go in and change the url references to those layers. On the other hand, if I used the titles of the layers, it wouldn’t matter what the index position of the layer is. The name of the layer and the title would still be the same.

It’s true that the title of the layer could change too. In that case we’d still have to update the urls we’re passing in to the app. But in our situation this is less likely to happen than the positon changing. Using titles has another advantage of making it clear to the casual observer exactly what layers are being acted upon. This wouldn’t matter that much since the public isn’t going to be encouraged to pass parameters into the url. But it might be nice for us developers to know what we’re doing.

I ended up using layer titles since they’re human readable and don’t rely on positioning within the web map that drives the web app. However, I created both versions of my modifications so that someone else who wants to use layer indices can do so just as easily.

In my parameter, layers are separated by commas with layers to be shown represented by the layer title (or positive index integers) and layers to be hidden represented by layer titles with a minus(-) symbol in front of them (or negative index integers).

Toggling Sub Layers

I also wanted to be able to toggle sub layers on and off. Sublayers to be toggled will be shown by separating the parent layer from the sublayers with a colon. The sublayers themselves will be separated by semicolons.

In WAB apps, sublayers are 0 index based underneath their parent. Suppose you have an active layer called School Boundaries with a map index position of 6 and it has three sublayers for High Schools, Middle Schools and Elementary Schools. These sub layers would be indexed as 0, 1, 2.

I decided to stick with index references for the sublayers since it was easy to do so and makes sense. It’s also easier to read in and understand within the url since the parent layer is text so there’s some contrast. 

With the above model of building your url for layer toggling, you can take care of almost any layer manipulation scenario you can think of.

This would turn on the Schools layer as well as the first, second and third sublayers: 
?layers=Schools:0;1;2

This would turn off the Schools layer and deselect sublayer 0, then turn the schools back on and select sub layers five and six:
?layers=-Schools:0,Schools:5;6

Edit: Having to turn an entire layer off and then on again, just to get at the sublayer, was cumbersome. Now you can use the minus symbol in front of the layer title or the sublayer index to turn themon and off independently. For example – ?layers=Schools:-0;5;6


Multiple Params


Another problem I have with the URL parameter handling capabilities of the Web App Builder is that you can’t add multiple parameters. In other words, you can’t pass in layers to turn on and do a query on a layer at the same time. To solve that problem I just modified the main function in the module to check all url parameters rather than stopping after finding the first one.

mo.postProcessUrlParams = function(urlParams, map){
    //urlParams have been decoded.
    for(var key in urlParams){
      //Loop through the urlParams object
        if(urlParams.hasOwnProperty(key)){
          //For each parameter found, run its function
          if('layers' === key){
            toggleLayers(urlParams, map);
          }else if('extent' === key){
            setExtent(urlParams, map);
          }else if('center' === key){
            setCenter(urlParams, map);
          }else if('marker' === key){
            createMarker(urlParams, map);
          }else if('find' === key){
            sendMessageToSearch(urlParams);
          }else if('query' === key){
            queryFeature(urlParams, map);
          }
        }
    }
  };

How to Use

In order to use the modified mapUrlParamsHandler module in your WAB project you first need to download the appropriate one (index driven or title driven) from Github at https://github.com/RyanDavison/WAB_URL_Parameters. Then replace the native file located in \WebAppBuilderForArcGIS\server\apps\4\jimu.js .

If you’ve already exported your app and are hosting it on your own server just find the jimu.js folder and paste the file in there. Alternatively you could just copy the code out of the files on Github and paste it right into the native mapUlrParamsHandler.js file. That’s all you have to do to get layer toggling functionality through your url.

In the future, ESRI might enable this same functionality in the WAB Developer Edition. If they do, it’s a good bet they won’t have thhe same url structure as me. As I’m writing this, The Web App Builder is at version 2.9. So if you start using my modified code now, you might be changing your own url structures to match the ESRI api. My modifications 

If you have and questions, comments or problems feel free to leave them in the comments section below or contact me on Github.

EDIT:
When I first wrote the modification You could only turn sub layers on and off along with their parent layer. So, if you wanted to turn off sub layer 2  but turn on sub layer 3 of LayerX you would have to write

?layers=-LayerX:2,LayerX:3

It was a two-step process that was very clunky. Now, you can turn off sublayers independently. So the query above would now simply read:

?layers=LayerX:-2;3

Of course you can still turn off an entire layer like this:

?layers=-LayerX

Custom Color Ramps For ArcGIS

Back in 2012 I wrote a post about loading custom color ramps into ArcGIS. It’s been a consistently popular post but is very outdated. In that post I suggested downloading and installing ESRI’s ColorRamps2.o package. ColorRamps2.0 was replaced with ColorRamps3.0 around the time I wrote the post. Today, although there’s a link to download ColorRamps3.0 it doesn’t seem to be functioning.

Instead of simply updating an old blog post, I thought it would be helpful to write an updated post. I’ll show you how to create color ramps on the fly in ArcGIS and how to import custom color ramps into ArcGIS 10.5. I’ll also provide a list of color ramp creation and download sources.

If you already have a color ramp .style file, you can follow the steps below to add them into ArcMap:

  1. Copy the .style files to C:\Program Files (x86)\ArcGIS\Desktop10.5\Styles. Your Styles will be different depending on your operating system and version of ArcGIS.
  2. Open ArcMap.
  3. Click the customize dropdown and select Style Manager.
  4. On the right side of the Style Manager click on the Styles… button. At this point your custom style name should just show up in your style manager. However, if it doesn’t because you put your style file in a different directory or some other reason, you need to follow two more steps. First, click Add Style to List. Navigate to the directory where you placed the .style files and select your custom file. Highlight the file and click Open. You will have to do this for each .style file you want to add.
  5. After all of the styles are shown in the Style References list, make sure they are check marked and click the Set as Default List button.
  6. Click OK and you should see your styles on the left side of the Style Manager. Close the style manager. At this point you can go to the symbology tab of your Layer Properties for a given raster and select one of the new color ramps. If you want to see the text descriptions of the ramps, click on the color ramp dropdown and uncheck ‘Graphic View’.

So where can you find alternative .style files with color ramps? It seems to be getting harder to find them these days. As I mentioned above, you used to be able to get them from the ESRI mapping center but that resource seems to be abandoned. Let me know if you know where to find ColorRamps3.0 or 2.0 today.

ColorBrewer2.org used to be another good resource but the site has removed the option to download ramps in the .style format. Fortunately, you can still access them by going to http://www.reachresourcecentre.info/arcgis-colorbrewer-color-ramp-style and downloading the zip file.

You can check out Fred Lott’s color ramps on GitHub too. Of course, if you aren’t finding quite the ramp for your needs and you’re trying to show quantities, you could always build your own.

To set your own quantities ramp for your layer, follow these steps:

  1. Right click on your layer and go to the symbology tab.
  2. Click on Show Quantities and select Graduated Colors.
  3. Choose your field’s value and normalization and how many classes you want your data broken into. Your classes will already have a color ramp assigned
  4. Double click on the first class symbol color. Choose another color that you want for the start of your custom ramp.
  5. Next, double click on the last class symbol color and choose the last color in your ramp.
  6. Right click on any of the symbols and select Ramp Colors. This will generate the color ramp between the top and bottom colors you chose.

 

So there you have it. If you’re not happy with what ESRI has already provided you for styles you have a few options for customization. If you know of any other style resources I didn’t mention, please feel free to let me know in the comments. Thanks for reading.

 

Five Things I Love About the ESRI Javascript API

Having worked with both the ArcGIS Silverlight and Javascript APIs I have to say Javascript has been much more fun. There is just something about working on the front end of a web map and being able to have it do so many amazing things. Here are my top five reasons I enjoy working with this API.

1. Your maps are device independent. Unlike the Flex and Silverlight APIs, Javascript and HTML5 can be viewed on almost any device. The obvious advantage here is that you can reach more people with your spatial data.  Of course having the ability to code for multiple devices means having to customize your code for different screen sizes which can turn into a lot of work. Check out this post from the Treehouse Blog for a great primer on responsive web design.

2. Plenty of code samples and live examples. Code samples are a great way to get your own map up and running quickly without having to figure everything out first. While the samples are not perfect they are a good way to discover map functionality that you might want to incorporate.

3. Support for a ton of layer and data formats. From GeoRSS and GeoJSON to KML and shapefile, this API pretty much covers it.

4. Well written API reference documentation. If you are going to use an API (any API) you want to be able to understand it so you can use it effectively. Good documentation is critical for this. The Esri JS API is (in my own humble opinion) extremely easy to read and understand. Each class has all the information you need to use it without having to decode any meanings. Furthermore, there are links from each class to samples that use it.

5.  Editing tools for online editing of SDE data. Let’s be honest, online editing through a web browser is not a great idea if you are trying to build accurate data. However, there is definitely a place for it. If you are trying to outline an area inhabited by a herd of elk or mark an area of weed infestation, browser editing is probably fine.  It is great just to be able to have this ability so more diverse mapping applications can be developed.

Wow, this list was a lot harder to write than 5 Things I Hate About the ESRI Javascript API. One reason is that there are other APIs out there that do a lot of what the ESRI API does (yes I am thinking about OpenLayers). Another reason is that as I write I think about things I would like ESRI to do better or differently. Oh well, you can’t have everything. Let me know what your thoughts are on the ESRI Javascript API – good or bad.

5 Things I Hate About the ArcGIS Javascript API

Building a mapping application with ESRI’s Javascript API is a lot of fun. But it can also be a real pain. Here are five things that absolutely drive me crazy when writing an ArcGIS Javascript map.

1. It is based on Dojo. It’s probably just my lack of Javascript programming sophistication but I find Dojo a little hard to work with. Although the API documentation has improved in recent versions, I don’t find it very intuitive. If you are a beginner or new to Javascript, the getting started documents are just plain frustrating. Ben Farrell thinks there are seven stages of learning Dojo including anger and acceptance. I’m not sure if there are really only seven stages but I can attest to the anger and acceptance.

2. It uses multiple versions of Dojo. Here I go again with the Dojo thing. Half of the developer samples on the ArcGIS.com developer’s site seem to be written pre version 1.7 while the others are post 1.7 and rely on the AMD module format.  I understand that version transitions of supporting libraries can be difficult but this is ridiculous. Since the ArcGIS API updated to version 3.6, many of the developer samples have been updated to show the AMD require format. Unfortunately, the transition has been slow and there is still a lot of mixed version code and a lot of live samples are broken. If you are going to upgrade to a new version of your API, let’s have things ready to go.  

3. No built-in label engine for dynamic, on-screen annotationIt seems obvious to me that the users of a map would want to mark it up with text; especially in conjunction with a draw toolbar. Apparently it isn’t obvious to the ESRI developers. Instead we are left to work with with the labelPoints function which uses the geometry server to create an unseen point and then puts a text symbol on top of it.

4. The label engine problem above leads me to my next gripe. The LabelPoints function doesn’t allow line breaks. That means that if you want to label a polygon with something like, oh say, area and perimeter, you have to have it all on one line or call the labelPoints function twice and use an offset. How about we get the ability to at least use a newline character (\n) and be done with it.

5. No out-of-the-box support for a table of contents. There is a lot of debate about whether an ArcGIS-like table of contents is a good thing in a web map. No matter what side of the debate you fall on, the fact is that people are used to using them and users often want the ability to turn layers on and off. There are a few projects out there that attempt  to solve the problem but each has its own limitation and problems.  It is a little surprising that ESRI doesn’t have a solution for this one yet. Or, maybe it isn’t really that surprising.

I have plenty more gripes with the Javascript API than the ones listed above but I don’t want to get too depressing. Also, I actually enjoy developing with the API (most days) and there are some great things about it. If you want to add to my list put it in the comments.