2

I am using the basic structure for layer toggling found in this CartoDB tutorial, with buttons wired to a ul navigation menu.

In the meantime, I was happy to implement the Marker Cluster Leaflet plugin as instructed here. However, now the navigation won't work.

Here is the js I have been trying:

var baseLayer = L.tileLayer('http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.jpg', {
attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA.</a>'
});
var markers = L.markerClusterGroup();
$.getJSON("http://username.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM table_name", function(data) {
var geojson = L.geoJson(data, {
  onEachFeature: function (feature, layer) {
    layer.bindPopup("<h2>" + feature.properties.label + "</h2><hr><p>Address: " + feature.properties.address +  "</h2><hr><p>" + feature.properties.href);
  }
});
markers.addLayer(geojson);

var map = L.map('map', {maxZoom: 18, center: [20, 40],
zoom: 2
});

baseLayer.addTo(map);
markers.addTo(map);
sublayers.addTo(map);

});

var sublayers = [];

cartodb.createLayer(map, layerUrl)
.addTo(map)
.on('done', function(layer) {
var subLayerOptions = {
sql: "SELECT * FROM table_name"
};

var sublayer = layer.getSubLayer(0);

sublayer.set(subLayerOptions);

sublayers.push(sublayer);
}).on('error', function() {
//log the error
});

$('.button').click(function() {
$('.button').removeClass('selected');
$(this).addClass('selected');
LayerActions[$(this).attr('id')]();
});


var LayerActions = {
group1: function(){
sublayers[0].setSQL("SELECT * FROM table_name WHERE group = 'Group 1'");
return true;
},
group1: function(){
sublayers[0].setSQL("SELECT * FROM table_name WHERE group = 'Group 1'");
return true;
},
category1: function(){
sublayers[0].setSQL("SELECT * FROM table_name WHERE category = 'Category 1'");
return true;
},

...

}
};

Any insight into how to merge button toggling and marker clustering would be helpful. With thanks.

UPDATE: I have a work-around, adding separate marker cluster groups for each 'Group 1', 'Group 2', ...

  var markers1 = L.markerClusterGroup();

$.getJSON("http://username.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM example_table WHERE group='Group 1'", function(data) {
var geojson = L.geoJson(data, {
  onEachFeature: function (feature, layer) {
    // ADD A POPUP WITH SOME INFO
    layer.bindPopup("<h2>" + feature.properties.label + "</h2><hr><p>Address: " + feature.properties.address );
  }
});
markers1.addLayer(geojson);
});


var markers2 = L.markerClusterGroup();

$.getJSON("http://username.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM example_table WHERE group='Group 2'", function(data) {
var geojson = L.geoJson(data, {
  onEachFeature: function (feature, layer) {
    // ADD A POPUP WITH SOME INFO
    layer.bindPopup("<h2>" + feature.properties.label + "</h2><hr><p>Address: " + feature.properties.address );
  }
});
markers2.addLayer(geojson);
// CONSTRUCT THE MAP
var map = L.map('map', {maxZoom: 18, center: [20, 40],
zoom: 2
});

baseLayer.addTo(map);
markers1.addTo(map);
markers2.addTo(map);
sublayers.addTo(map);

});

It's not a perfect solution—it basically separates the clusters so that you end up with overlapping cluster-dots. I'll probably need to use the leaflet layer selector instead of my current navigation menu for this project, like the DOC huts example provided on the thematicmapping site by Bjørn Sandvik.

UPDATE:

I am finding this answer helpful

UPDATE:

I have switched to the CartoDB clustering method and have added both the clustered layer (lyr0) and non-clustered layer (lyr1) to my map. Now I just want to turn on lyr1 only at a specific zoom level. I am currently unable to get zoom-based show/hide to work. Maybe someone will see the errors in the following ways:

      function main() {

    // create leaflet map
    map = L.map('map', { 
      zoomControl: true,
      center: [40.79, -111.9],
      zoom: 6
    });

    // add a base layer
    L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
      attribution: 'Stamen'
    }).addTo(map);

    var gridsize = 48;
    var baseSql = $('#sql_template').html().format(gridsize);
    var cartoCss = $('#cartocss_template').html().format(gridsize);
    var lyr0;
    $("#cluster_size").on('change',function(){
      $('.size').html($("#cluster_size").val());
    });
    $("#cluster_size").on('mouseup',function(){
    lyr0.setSQL($('#sql_template').html().format($("#cluster_size").val()));
    lyr0.setCartoCSS($('#cartocss_template').html().format($("#cluster_size").val()));
    });
    // add cartodb layer with one sublayer
    cartodb.createLayer(map, {
      user_name: 'username',
      type: 'cartodb',
      sublayers: [{
         sql: baseSql,
         cartocss: cartoCss,
         interactivity: 'cartodb_id'
      }]
    })
    .addTo(map)
    .done(function(layer) {
      sublayer = layer.getSubLayer(0);
      sublayer.setInteraction(true);
      addCursorInteraction(sublayer);
    });

    var lyr1 = [];
    cartodb.createLayer(map, layerUrl)
    .addTo(map)
    .on('done', function(layer) {
    // change the query for the first layer
   if (zoom <= 10) {
     layer.hide(lyr1);
    } else if (zoom >= 10) {
      layer.show(lyr1);
    } else {
      layer.show(lyr0);
    }
var subLayerOptions = {
sql: "SELECT * FROM table_name"

};


lyr1.set(subLayerOptions);

lyr1.push(lyr1);
}).on('error', function() {
//log the error
});

$('.button').click(function() {
$('.button').removeClass('selected');
$(this).addClass('selected');
LayerActions[$(this).attr('id')]();
});


var LayerActions = {
group1: function(){
lyr0.hide();
lyr1.getlyr0[0].setSQL("SELECT * FROM table_name WHERE group = 'Group 1'");
return true;
},
category1: function(){
lyr0.hide();
lyr1.getlyr0[0].setSQL("SELECT * FROM table_name WHERE category = 'Category 1'");
return true;
},
...

UPDATE:

I've decided to return again to the Leaflet markerCluster option because I couldn't get the fitBounds option to work on the sublayers in CartoDB, alas. I have been adding a marker cluster layer for every item in the layers control menu.

Is there a way to slim down the code for adding multiple cluster layers from geoJSON?

Here's what I have:

var group1 = new L.markerClusterGroup();
    $.getJSON("http://userid.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM table_name WHERE table_name.group='Group 1'", function(data) {
    var geojson = L.geoJson(data, {
      onEachFeature: function (feature, layer) {
        // ADD A POPUP WITH SOME INFO
        layer.bindPopup("<h2>" + feature.properties.label + "</h2><hr><p>Address: " + feature.properties.address +  "</h2><hr><p>" + feature.properties.href);
      }
    });
    group1.addLayer(geojson);
  });

var category1 = new L.markerClusterGroup();
$.getJSON("http://userid.cartodb.com/api/v2/sql?format=GeoJSON&q=SELECT * FROM table_name WHERE table_name.category='Category 1'", function(data) {
    var geojson = L.geoJson(data, {
      onEachFeature: function (feature, layer) {
        // ADD A POPUP WITH SOME INFO
        layer.bindPopup("<h2>" + feature.properties.label + "</h2><hr><p>Address: " + feature.properties.address +  "</h2><hr><p>" + feature.properties.href);
      }
    });
    category1.addLayer(geojson);
  });
  ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.