Saturday 3 December 2016

Replacing OpenLayers

When OS released their Open Data I created a simple map that showed a few of their offerings as overlays on an OSM base layer oscompare.raggedred.net. At the time my maps were driven by OpenLayers. OpenLayers v2 works well but is a lot harder to use than LeafletJS. As soon as Leaflet arrived I started to use that and it has only got better as time has passed. There is OpenLayers v3 available I think, but I doubt I'll use it.

OpenLayers has a permalink option that changes the URL in the browser to include a query string describing the location of the centre of the map and the zoom level. This lets you bookmark or send a link that will open the map in the right place. Leaflet has a plugin to create a hash on the URL that does a similar thing.  It works well but there is a bit of a problem.

The OpenLayers permalink adds a 'layers=' bit to the URL. An example would be BOTFF. This means the first base layer is shown and not the second one, then the first overlay is visible but not the second or third. This great, because not only does the URL make map show the right place, but the overlay you wanted to show will also appear too. Leaflet's hash plugin doesn't do this and that is a problem for me.

I decided to replace the map showing the OS overlays using Leaflet. It was quick to do and works well, but I can't use it as the replacement for the OpenLayers map because Leaflet doesn't have a built-in way to show the layers that were selected. People link to my map, according to the logs, with the query string to select the place and layers. If I just replaced it with the Leaflet-based map their links would all fail. They couldn't create a new bookmark that includes the layers to show either. I decided to fix this.

I looked into the documentation for the latest version of Leaflet (1.0.2 at the time of writing). The documentation is very useful. If there are overlays on a map a layers control can be added that allows the overlays to be selected. There can also be more than one base layer that the control allows you to select.

I thought about a generic way to create a similar effect to the OpenLayers permalink. For a one-off map I can code up the layers to do as I need, but a generic version would be useful. I can get at the layers that a map is currently showing, but Leaflet's way of hiding a layer is to remove it from the map. The definition of that layer is then not accessible from the map object. I couldn't see how to find the list of layers including the ones not displayed. The layers control has a list of the layers it uses, which would be ideal, but I couldn't find any way to find a a reference to that from the map object. There doesn't seem to be any way to find any controls from the map object. A map method that returns a list of controls might be useful.

So far I have created a bespoke version of the Leaflet map I wanted. It will accept an OpenLayers-style URL, display the map and create a Leaflet-style URL. I'm thinking about how to duplicate the OpenLayers feature more generically. I have ideas ...

No comments: