Leaflet Zoom Switcher

Have you ever experienced an automatic layer switching when browsing on a map  ? Your current baselayer is a satellite view, and at the next zoom, baselayer becomes an aerial map or a road map.
Most of the time you have the choice for selecting the baselayer when you want, and at the scale you want.
But Sometimes, it's usefull to make this automatic.

We had to do this for a project, then we did it with Leaflet, just by adding 2 small classes.

First one is an extent of the TileLayer class. I named it TileLayerZoomSwitch. It defines only 3 more variables in the options, and set a few methods for settings of getting these variables.

L.TileLayerZoomSwitch = L.TileLayer.extend({
	includes: L.Mixin.Events,

	options: {
        // switchZoomUnder: when zoom < switchZoomUnder, then switch to switchLayer
        switchZoomUnder : -1,
        // switchZoomAbove: when zoom >= switchZoomAbove, then switch to switchLayer
        switchZoomAbove: -1,
        switchLayer: null
	},

    setSwitchLayer: function (layer) {
        this.options.switchLayer = layer;
    },    
    
    getSwitchZoomUnder: function () {
        return this.options.switchZoomUnder;
    },
    
    getSwitchZoomAbove: function () {
        return this.options.switchZoomAbove;
    },
    
    getSwitchLayer: function () {
        return this.options.switchLayer;
    }

});

L.tileLayerZoomSwitch = function (url, options) {
	return new L.TileLayerZoomSwitch(url, options);
};

Second one is a SwitchLayermanager class, where all the "magic" occurs. It just checks the current level of zoom when the user is zooming (in or out),
and automatically adds or removes base layers according to their configuration.

/*
 * SwitchLayerManager is a custom class for managing base layer automatic switching according to the current zoom level
 */

SwitchLayerManager = L.Class.extend({

    _map: null,

    options: {
        baseLayers: null
    },

    initialize: function (map, options) {
        this._map = map;
        L.Util.setOptions(this, options);
        
        this._map.on({
            'zoomend': this._update
        }, this)

    },
    
    _update: function (e) {
        var zoom = this._map.getZoom();
        
        for (var i in this.options.baseLayers) {
            var curBL = this.options.baseLayers[i];
            var zoomUnder = curBL.getSwitchZoomUnder();
            var zoomAbove = curBL.getSwitchZoomAbove();
            var switchLayer = curBL.getSwitchLayer();
            
            // If layer got a switchlayer, and if layer actually displayed
            if (switchLayer && curBL._map != null) {
                if(zoomUnder != -1 && zoom < zoomUnder) {
                    this._map.removeLayer(curBL);
                    this._map.addLayer(switchLayer, false);
                }
                
                if(zoomAbove != -1 && zoom >= zoomAbove) {
                    this._map.removeLayer(curBL);
                    this._map.addLayer(switchLayer, false);
                }
            }            
        }
    }
});

And that's it.
Now, how to use it ?
Here is an example :

var osmUrl='http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © openstreetmap contributors';
var cmUrl = 'http://{s}.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{z}/{x}/{y}.png';
var cmAttrib = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://cloudmade.com">CloudMade</a>;'

cloudmade = new L.TileLayerZoomSwitch(cmUrl,{attribution: cmAttrib, switchZoomUnder: 12});
osm = new L.TileLayerZoomSwitch(osmUrl,{minZoom:8, maxZoom:18, switchZoomAbove: 12, switchLayer: cloudmade, attribution:osmAttrib});

cloudmade.setSwitchLayer(osm);
var baseLayers = {
    "Cloudmade": cloudmade,
    "Osm": osm
};
switchManager = new SwitchLayerManager(map, {baseLayers: baseLayers});

The layer named cloudmade will be the active one till zoom 12. Layer osm will be the active one from zoom 12 to 1.
Note that the switchLayer option is defined directly for the osm layer, and we have to call setSwitchLayer() for cloudmade layer.

Votre notation : Aucun Moyenne : 5 (3 votes)
Étiquettes: