Viglino / ol-ext

Cool extensions for Openlayers (ol) - animated clusters, CSS popup, Font Awesome symbol renderer, charts for statistical map (pie/bar), layer switcher, wikipedia layer, animations, canvas filters.
https://viglino.github.io/ol-ext/
Other
1.25k stars 462 forks source link

Layer Switcher and Swipe Tile Sharing Broken with OpenLayers 10.0.0+ #1112

Open WillieMaddox opened 3 days ago

WillieMaddox commented 3 days ago

I'm working on a project that combines two layer switchers with a swipe control, allowing users to switch map layers independently on the left and right sides. This setup provides flexibility without redundant data usage.

To optimize performance, tile sources are shared between layer switchers. For example, if the left side displays OpenStreetMap (OSM) and the right side is set to Google Maps, switching the right side to OSM won’t trigger additional downloads. The tiles are already cached from the initial download on the left side.

However, since the introduction of the ImageTile base class in OpenLayers version 10.0.0 and later, this tile-sharing functionality no longer works as expected. Before contacting the OpenLayers team, I wanted to ask here if there might be a potential fix or workaround within the ol-ext project.

Below is an index.html and an index.js that should be sufficient to reproduce the issue.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>ol-ext: Swiped Layerswitchers</title>
    <style>
      html, body {
        margin: 0;
        height: 100%;
      }
      .map {
        width: 100%;
        height: 100%;
        background: rgb(229, 227, 223);
      }
      .ol-control.ol-layerswitcher.layerSwitcherLeft {
        left: 0.5em;
        right: auto;
      }
    </style>
  </head>
  <body>
    <div id="map" class="map"></div>
  </body>
</html>
import 'ol/ol.css';
import 'ol-ext/dist/ol-ext.css'
import Map from 'ol/Map';
import View from 'ol/View';
import { OSM, XYZ } from 'ol/source';
import { Tile as TileLayer } from 'ol/layer';
import LayerGroup from 'ol/layer/Group';
import Swipe from 'ol-ext/control/Swipe';
import LayerSwitcher from 'ol-ext/control/LayerSwitcher';

const sourceOSM = new OSM();
const sourceGoogle = new XYZ({url: 'https://mt{0-3}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}'});

function StaticGroup () {
    return new LayerGroup({
        layers: [
            new TileLayer({
                title: "OSM",
                visible: false,
                baseLayer: true,
                source: sourceOSM,
            }),
            new TileLayer({
                title: 'Google',
                visible: false,
                baseLayer: true,
                source: sourceGoogle,
            }),
        ]
    })
}

let leftgroup = new StaticGroup();
let rightgroup = new StaticGroup();

let map = new Map({
    target: 'map',
    // view: new View({zoom: 16, center: [-12337600, 3783550]}),
    view: new View({ zoom: 5, center: [166326, 5992663] }),
    layers: [leftgroup, rightgroup]
});

let swipe = new Swipe()

function switchleft (layer) {
    let add_layers = [];
    let del_layers = [];
    swipe.layers.forEach( function(l) {
        if (!l.right) {
            add_layers.push(layer);
            del_layers.push(l.layer);
        }
    })
    swipe.removeLayer(del_layers);
    swipe.addLayer(add_layers, false);
}
function switchright (layer) {
    let add_layers = [];
    let del_layers = [];
    swipe.layers.forEach( function(l) {
        if (l.right) {
            add_layers.push(layer);
            del_layers.push(l.layer);
        }
    })
    swipe.removeLayer(del_layers);
    swipe.addLayer(add_layers, true);
}

let layerswitcherleft = new LayerSwitcher({
    reordering: false,
    switcherClass: "layerSwitcherLeft ol-layerswitcher",
    layerGroup: leftgroup,
    onchangeCheck: switchleft
});
map.addControl(layerswitcherleft);

let layerswitcheright = new LayerSwitcher({
    reordering: false,
    switcherClass: "layerSwitcherRight ol-layerswitcher",
    layerGroup: rightgroup,
    onchangeCheck: switchright
});
map.addControl(layerswitcheright);

function initlayerswitcher ({layergroup, is_right, idx = 0} = {}) {
    let layer = layergroup.getLayers().getArray()[idx];
    layer.setVisible(true);
    swipe.addLayer(layer, is_right);
}
initlayerswitcher({layergroup: leftgroup, is_right: false, idx: 0})
initlayerswitcher({layergroup: rightgroup, is_right: true, idx: 1})
map.addControl(swipe);

This package.json works:

{
  "name": "ol-ext: Swiped Layerswitchers",
  "dependencies": {
    "ol": "^9.2.4",
    "ol-ext": "^4.0.24"
  },
}

This one does not:

{
  "name": "ol-ext: Swiped Layerswitchers",
  "dependencies": {
    "ol": "^10.2.1",
    "ol-ext": "^4.0.24"
  },
}
mike-000 commented 3 days ago

Sources no longer have a cache https://github.com/openlayers/openlayers/pull/16221 which removes the advantage of sharing sources. It affects all source types as XYZ and OSM are not (yet) subclasses of ImageTile.

Viglino commented 2 days ago

No fix or workaround, sorry :disappointed: