Monday, 12 December 2016

Leaflet plugin

I have been trying to replace a long-standing map based on the OpenLayers 2 library to LeafletJS. The main sticking point was that OpenLayers has a useful permalink function that changes the URL to include a query string that identifies the map location and which layers should be shown. 

Leaflet has a neat plugin to show the location as a hash but that doesn't include the layers to show. After a bit of investigation I decided to try to write a Leaflet plugin to make all this easier.

If a map has optional base layers and some overlays it often will use the Layers control to make the choices easy to select. The layers are not easily accessible from the map object as only the currently displayed layers, not the hidden ones, are available. The Layers control has access to all the layers, but that control is not accessible from the central map object. The only way to have access to all of the layers is from the Layers control, so a new control, inherited from the Layers control seemed to be the right answer. HashLayers control was developed.

HashLayers does all that the Layers control does, of course, but adds the functionality of the URL hash. The hash looks like this:
#zoom/longitude/latitude/layers
This gets appended to the URL of the page that the map is on. Using the hash means the position and layers can be changed dynamically as the map is zoomed or scrolled around and as different layers are selected. Changing the hash value of a URL doesn't force a reload of the page and doesn't show up in browser history.

The zoom is the current zoom level and longitude and latitude are the centre of the map. The layers is a string representing the base layers and any overlays. If a base layer is selected 'B' is shown, 'O' shows an available base layer not selected. The overlays are shown as a string of 'T' or 'F' (true or false) showing if they are shown or not. A typical hash might be:
#12/-0.393105/53.775095/BOFFTF
 This has the first base layer visible, the second one not showing and four overlays available, but with only the third one visible. These selections will be reflected in the visible selection control too.

If a map is created with the HashLayers control on it and a hash is passed in the URL, the map will centre on the location and zoom specified and show the requested layers. If no hash is passed then the default location and zoom will be used from the setView() or map options as normal. Layers will be shown as they were added to the map. A hash to reflect all this will be appended to the URL which gets updated with every change. There is no need for the OpenLayers permalink control.

I now need to test it more carefully and decide if it is worth publishing as a Leaflet plugin.

2 comments:

Anonymous said...

hi, you may have missed this existing leaflet plugin :

https://github.com/shramov/leaflet-plugins/blob/master/examples/permalink.html

Chris Hill said...

Thanks for pointing out the plugin. I had missed it. The plugin is mixed up with other stuff, all of which could be useful but because it is not separated out into separate plugins it is easy to overlook. The plugin takes a different route to my (still potential) plugin, it tries to maintain compatibility with openlayers whereas I think mine is more in the Leaflet style. As always in open source there's room many approaches.