0

I would like to add a toggle control/switch for basemaps to my code. I tried something similar to this:

http://bl.ocks.org/iriberri/08abc420a376053c71d4

but it does not work in combination with CreateLayer.

I also found this:

https://groups.google.com/forum/#!topic/cartodb/IR5LSMj-Xio

where leaflets L.Control was used. But due to my limited JavaScript knowledge, I cannot get it to work... :/

NEW CODE (with layer selector and basemap selector):

    <div id="map"></div>
    <div style="display: block;" class="cartodb-fullscreen"><a href="#" target="_blank" title="Vollbild (empfohlen f&uuml;r mobile Ger&auml;te)"></a></div>
    <div id="cartocss" class="layer_selector"><div class="close">×</div>
        <p id="js-category-selector">XXXX</p>
        <ul class="LayerSelector-list">
            <li data="1" class="button noleg selected">XXXX
            </li>
            <li data="2" class="button">XXXX
            </li>
            <li data="4" class="button">XXXX
            </li>
            <li data="3" class="button">XXXX
            </li>
        </ul>
    </div>
    <div id='selector_menu'>
        <select id="selector">
            <option value="StreetMap">Stra&szlige</option>
            <option value="AerialMap">Satellit</option>  
        </select>
    </div> 
    <!-- include cartodb.js library -->
    <script src="http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js"></script>
    <!-- Place your code in the script tags below -->
    <script>
    $(document).ready(function(){
        $( document ).ready(function() {
            $( "#js-category-selector" ).click(function() {
                $( '.layer_selector' ).toggleClass( "is-active" );
            });
        });
    $(".close").click(function(){
    $("ul").toggle();
    var $this = $(this);

    $this.toggleClass('+');

    if ($this.hasClass('+')) {
    $this.text('+');
        } else {
    $this.text('×');
        }
    });
    });
    </script>
    <script type="text/javascript">

    function main() {
        "use strict";
        var map;
        //  center and zoom level
        var options = {
            center: [48.3,9.8], // Distribution area
            zoom: 9,
            minZoom: 3,
            maxZoom: 18,
            scrollWheelZoom: false        
        };
        // define map object
        var map_object = new L.Map('map', options);

        var densityLegend = new cdb.geo.ui.Legend.Density({
        // Put optional legend for noleg items here
        });

        // Hide legend for items with class noleg
        $(densityLegend.render().el).hide();

        var densityAltLegend = new cdb.geo.ui.Legend.Density({
            title: "Legende",
            left: "Weniger", right: "Mehr", colors: [ "#FFEDA0", "#FEB24C", "#F03B20" ]
        });
        $('#map').append(densityAltLegend.render().el);
        // Hide legend for items with class noleg at start
        $(densityAltLegend.render().el).hide();
        // Create layer selector
        function createSelector(layer,num,unfaellemap) {
            for (var i = 1; i < layer.getSubLayerCount(); i++) {
                if (i === num) {
                    layer.getSubLayer(i).show();
          } else {
                    layer.getSubLayer(i).hide();
            }
        }
            if (unfaellemap){
                $(densityAltLegend.render().el).hide();
                $(densityLegend.render().el).show();
        } else {
                $(densityLegend.render().el).hide();
                $(densityAltLegend.render().el).show();
            }
        }

        // add default basemap
        var basemap1 = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
            type: 'map',
            ext: 'jpg',
            subdomains: '1234',
            attribution: '<a href="http://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
        }).addTo(map_object);
        // add new basemap option
        var basemap2 =  L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
            attribution: '&copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
        });

        // For storing sublayer outside of createlayer
        // var sublayers;

        // Add data layer to your map
        cartodb.createLayer(map_object,'https://documentation.cartodb.com/api/v2/viz/236ecca6-8877-11e5-8a51-0ef7f98ade21/viz.json', {
            searchControl: false, legends: false, cartodb_logo: false, tooltip: true, infowindow: true, zoomControl: true, scrollwheel: false, layer_selector: false, layerIndex:1 })
        .addTo(map_object)
            .on('done', function (layer){
                var sublayer0 = layer.getSubLayer(0).setInteraction(true);
                layer.getSubLayer(0).infowindow.set('template', $('#infowindow_template').html());
                var sublayer1 = layer.getSubLayer(1);
                var sublayer2 = layer.getSubLayer(2);
                var sublayer3 = layer.getSubLayer(3);
                var sublayer4 = layer.getSubLayer(4);
                // hide sublayer1
                sublayer2.hide();
                sublayer3.hide();
                sublayer4.hide();               
                // define ZIndex of the CartoDB layer
                layer.setZIndex(9000);
                // define basemap options
                var LayerActions = {
                StreetMap: function(){
                // if map_object has already a basemap, remove it and add a new one
                    if (map_object.hasLayer(basemap1) || (map_object.hasLayer(basemap2))){
                        map_object.removeLayer(basemap1);
                        map_object.removeLayer(basemap2);
                    }
                map_object.addLayer(basemap1);
                return true;
                },
                // if map_object has already a basemap, remove it and add a new one
                AerialMap: function(){
                    if (map_object.hasLayer(basemap1) || (map_object.hasLayer(basemap2))){
                        map_object.removeLayer(basemap1);
                        map_object.removeLayer(basemap2);
                    } 
                map_object.addLayer(basemap2);
                return true;
                    }
                };
            $('#selector').change(function() {
                LayerActions[$(this).val()]();
            });
            $("li").on('click', function(e) {
                var num = +$(e.target).attr('data');
                    createSelector(layer,num,$(e.target).hasClass('noleg'));
            $( '.button' ).removeClass('selected');
            $(this).addClass('selected');
                });
            })
            .error(function(err) {
                console.log("error: " + err);
            });
        }
    window.onload = main;
    </script>

2 Answers 2

2

To toggle basemaps with the cartoDB createLayer() method you could use the leaflet addLayer(), removeLayer(), hasLayer() methods in order to add or remove the basemaps layers.

Here you can see an example of how to toggle basemaps with the createLayer() method.

http://bl.ocks.org/oriolbx/3e966eb01c31c806c271

In the example a HTML dropdown menu is used to switch the basemap layers.

4
  • Great! This actually worked - thanks a lot! I got one small problem though: As soon as I switch the basemaps and start selecting different layers with data in the layer selector again, it gets pretty slow. Data loads forever, sometimes it stalls completely. Could you look over my code again please? I edited my original post. Thanks a lot! Commented Nov 20, 2015 at 1:12
  • I cleaned up the code a bit. Now it works. Thanks again. Commented Nov 20, 2015 at 12:26
  • Happy to hear that it works! :)
    – oriolbx
    Commented Nov 20, 2015 at 16:34
  • @schwaebische do you mind marking the question as answered?
    – Jorge Sanz
    Commented Jun 5, 2016 at 21:53
1

Here's a function to remove the current basemap from the bottom layer, then add a new basemap and move it to the bottom layer. Careful, this is hot!

var basemap1 = L.tileLayer('http://{s}.tile.thunderforest.com/spinal-map/{z}/{x}/{y}.png', {attribution: '&copy; <a href="http://www.thunderforest.com/">Thunderforest</a>, &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',maxZoom: 11});

var basemap2 = L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {attribution: 'Stamen'});

function setBasemap(basemap) {
  if (currentBasemap) {
    map.removeLayer(currentBasemap);
  }
  currentBasemap = basemap;
  map.addLayer(basemap);
  basemap.bringToBack();
}
var currentBasemap = basemap1; // default map
setBasemap(currentBasemap); // Init

Then add the following in a click event to swap in a basemap:

   setBasemap(basemap2);

Add a new var for each additional basemap. (basemap3, basemap4, etc.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.