ol-layerswitcher
ol-layerswitcher copied to clipboard
Remember enabled layers in localStorage
What would be the best way to approach saving the current state of enabled/disabled layers in browser localStorage, so that it persists across page-loads? Would this need to be implemented in the ol-layerswitcher library, or could it be done downstream in the app that uses ol-layerswitcher?
On 8/14/19 7:40 PM, Michael Stenta wrote:
What would be the best way to approach saving the current state of enabled/disabled layers in browser localStorage, so that it persists across page-loads? Would this need to be implemented in the ol-layerswitcher library, or could it be done downstream in the app that uses ol-layerswitcher?
Good question. I would like to have an option to save it together with the link, so that a permanent link with layers settings could be shared...
I was discussing something similar with AllRoads from the Netherlands OSM community.
My first thought was could https://github.com/tschaub/ol-hashed be used but I don't think layer state is included at the moment. The code for ol-hashed is nice and clear (https://github.com/tschaub/ol-hashed/blob/master/index.js) so you might be able to adapt it for your purpose? I think you'd probably need to assign each layer a persistent ID that can be used to track layer state, extend ol-hased config to add support support for serialize/ deserialize layer state and add an event listener similar to onMoveEnd for layer visibility changes.
Saving to LocalStorage would have same requirement regarding serialising layer state
Oh interesting ideas!
In my case, I may have cases where I have multiple maps on a single page, each with some common and some different layers. So I may experiment with an approach that saves a localStorage variable for each layer's visible state.
So slightly different case - ol-hashed probably wouldn't make sense in my case (but cool library to know about! might have other uses for it).
If I get something to work I'll share it here...
So I think maybe a first step would be to add some kind of event that can be listened for when layers are enabled/disabled via layer switcher.
Then my code could listen for that and save the layer state to localStorage. Right now that seems to be the challenge for me: picking up on the layers being enabled/disabled in a consistent way.
Does an event of this exist already in ol-layerswitcher?
@mstenta OpenLayers provides an event, I think the code in #30 is still relevant.
Thanks @walkermatt! I'll give that a try!
@walkermatt Is it possible to use the ol.control.LayerSwitcher.forEachRecursive()
function without having the global ol
object available? I am using Webpack to build my OL code, which means the global ol
object is not available. So the code that adds ol.control.LayerSwitcher
doesn't run.
To communicate with others about a map the string url is needed. Last week I saw the website of Brouter Osmoscope
with @walkermatt layerswitcher script github app.js page
Every layer a special ID, later when changing layers (new ones) old url links should still be working.
@mstenta if your using Webpack then forEachRecursive
is a static method of theLayerSwitcher
class:
import LayerSwitcher from 'ol-layerswitcher';
LayerSwitcher.forEachRecursive(map, function(l, idx, a) {
l.on("change:visible", function(e) {
var lyr = e.target;
console.log(lyr.get('title'), lyr.getVisible());
});
});
Thanks @walkermatt - makes sense!
Here is some code that seems to work to save/load layers:
import LayerSwitcher from 'ol-layerswitcher';
// Enable layer memory.
export default function enableLayerMemory(map) {
// Load saved layer visibility state from localStorage.
LayerSwitcher.forEachRecursive(map, (layer) => {
const title = layer.get('title');
if (title) {
const itemName = `farmOS.map.layers.${title}.visible`;
const savedValue = localStorage.getItem(itemName);
if (savedValue) {
const visible = (localStorage.getItem(itemName) === 'true');
layer.setVisible(visible);
}
}
});
// When layer visibility changes, save the layer's visibility state to
// localStorage.
LayerSwitcher.forEachRecursive(map, (layer) => {
layer.on('change:visible', (e) => {
const layer = e.target;
const title = layer.get('title');
if (title) {
const visible = layer.get('visible');
const itemName = `farmOS.map.layers.${title}.visible`;
localStorage.setItem(itemName, visible);
}
});
});
}
The only thing you'll want to modify is the farmOS.map.layers
local storage item name prefix, which is specific to my usage.
Couple of very vague thoughts/questions:
- is cookies not an option, rather than full-blown localStorage?
- I seem to remember @ThomasG77 coded on-the-fly unique layer id generation for the attribute search he wrote for qgis2web - if so, would this help?
Cookie is certainly another way of achieving the same thing.
I plan to implement the code from my comment above (with localStorage) within my application. So I'm not sure if we need to add layer memory directly to ol-layerswitcher or not. What are your thoughts @walkermatt ? Should this be a user-implemented thing? Or do you think it makes sense to add something to the library itself?