OL3 an alternative feature select solution

I had a simple task at hand – find a solution to highlight selected feature/s on a map. Those of you that have dabbled with desktop GIS software will no doubt be familiar with the default yellow highlight feature in QGIS and the cyan equivalent in ArcMap. You can’t really argue with this approach, it works, but, in certain situations it might be important to maintain your selected features style properties rather than override them with the highlight style.

So what other options are available to us? First stop, the official OL3 solution, great if your features are in a vector format but what if you are working with WMS layers and then there’s that style override item again. What I love about the OL3 environment, is that typically there are a few ways to get you where you want to go – a little more digging and I came across the OL3 vector source class ol.source.Vector().

The vector source class can be instantiated and used directly and can support feature updates – so lets put this class to work in a demo that will include the following functionality:

  • Add pointLayer styled according to value based on a json file (does not have to be a vector layer)
  • Add a vector layer called highlightLayer
  • Setup a map click function that determines nearest pointLayer feature to user click
  • Dynamically update content of highlightLayer based on selected feature of pointLayer
  • Position and style highlightLayer for desired effect

Typically, this solution will most likely involve calls to the server, which may not appeal to some, but it doesn’t have to. The following example will provide a simple non server solution with a view to scalability for larger projects.

Let’s start with some styles, we will need a style to color up our pointsLayer then I have included three additional style options for the highlightLayer.

In the istyles variable, there are five style options, the first two are for the highlightLayer: highlight_under is a solid purple circle with a radius of 12, the idea here being to highlight a feature/s by displaying the highlightLayer underneath the selected feature – to achieve this, the highlightLayer would need to be added to the map before the pointLayer. The second style: highlight_over places the highlightLayer over the pointLayer so requires the highlightLayer to be added after the pointLayer and so would also require some transparency so it does not hide the pointLayer. The advantage of the highlight_over style is that, if it is the last layer added to the map there is no chance of it being hidden underneath another layer. Order is key so give it some thought depending what effect you are after.

underhighlight_under style


overhighlight_over style

The final three styles in the istyles variable are responsible for coloring up our pointsLayer. After the istyles variable you will see a pointsFunction variable, this is where the point features are assigned a color style based on their value property in the json.

The final style item is the highlight_icon variable, I thought I would add this to our highlight styles option so that you can see that we can just as easily add an icon style item.

iconhighlight_icon style


Next, let’s setup our highlightLayer and pointLayer, assign them some styles and add them to the map.

You will notice the vectorSource and geojsonFormat variables, these provide us with the tools we need to manipulate our highlightLayer. The highlightLayer is assigned the style istyles[“highlight_over”] and the source: vectorSource which we will use to dynamically populate content but, at this stage it has not been assigned any features.

The pointLayer is assigned the pointsFunction style and hooked up with a highlight.json file that contains 10 features and their associated values that will determine their style allocation.

Finally, we setup the map and add three layers, the Open Street Map OSM base layer, the pointLayer and the highlightLayer – this order is important, because we are using the highlight_over style we need the highlightLayer to be added to the map after the pointLayer. If we wanted to use the highlight_under style then we would need to add the highlightLayer before the pointLayer. Lastly we center the map on New York City’s Central Park.

At this stage we have our pointsLayer displaying in full color thanks to our pointsFunction style, but we do not yet have any way to activate our highlightLayer, so, let’s get a click handler setup.

The click handler converts the user click into a point geometry, we then transform the point into EPSG:4326 and pack up the point coordinates to send to the highlightFeature function which we will take a look at next.

The highlightFeature function takes in the coordinates from the map click listener and compares them to each set of coordinates corresponding to each of our points in the pointLayer to determine the nearest point which we then add to the highlightLayer to display. To do this, we need to loop though the same highlight.json file used to display our pointLayer and get a distance between the user click coordinate and each point, we keep the lowest distance and populate our highlightLayer with the coordinates associated with that distance. The result will be to highlight a point from the pointLayer that is nearest to the user click location.

In this example we are highlighting the nearest point by populating the highlightLayer with the nearest point coordinates. What I am hoping you will take away from this post, is that you can make a call however you like to return single or multiple features, whether point line or polygon and send them to the highlightLayer to display. This functionality will also lend itself nicely to GPS positioning.

To do the distance calculation I have included a function based on the haversine distance calculation.

To try the other highlightLayer styles simply change the var highlightLayer style: option to one of the following, remembering to alter the order in which the layers are added to the map if you select the highlight_under option.

And that’s it! I have included a working version, and have made the source files available on GitHub.

Leave a Reply

Your email address will not be published. Required fields are marked *