[GIS] fitBounds on points after feature selection

cartoleaflet

I am trying to follow some of the examples I have found here and in Google Groups about fitBounds for points. Most of the examples are for polygons and don't seem to work for points. I think I've tried just about every combo of syntax that generally looks like the following:

 var sql = cartodb.SQL({ user: 'username' });

 //feature selection buttons:
 $('.button').click(function(e, latlon, lat, lng, pxPos, data, layer) {

   $('.button').removeClass('selected');
   $(this).addClass('selected');

   //I think I need to include an sql statement with lat and lon to get bounds, but I could be wrong:
   //sql.execute("SELECT cartodb_id, name, ST_X(the_geom) lon, ST_Y(the_geom) lat FROM table_name WHERE name = " + $(this).attr('selected'), function(ret) {

   var swLat = map.getBounds().getSouthWest().lat,
       swLon = map.getBounds().getSouthWest().lng,
       neLat = map.getBounds().getNorthEast().lat,
       neLon = map.getBounds().getNorthEast().lng,

       //fitBounds works with manual inputs (below)
       southWest = L.latLng(40.56, -112.05),
       northEast = L.latLng(40.77, -111.8),

       //...**but not with this part**
       //southWest = L.latLng(swLat, swLon),
       //northEast = L.latLng(neLat, neLon),

       bounds =  L.latLngBounds(southWest, northEast),

   map.fitBounds(bounds);

   LayerActions[$(this).attr('id')] ();

 });

I would be grateful for any feedback on this, or examples of fitBounds for points and not polygons. Here is the jsbin, annotated to the best of my ability: http://jsbin.com/hunovumu/38/edit

Best Answer

This is less of a Leaflet issue than a CartoDB one. In your code you are adding a CartoDB layer to your Leaflet map, then interacting with CartoDB to filter the features the layer shows.

The short answer is: you need to ask CartoDB for the bounds. Leaflet doesn't know much about the CartoDB layer, especially when it comes to the features CartoDB is showing.

The longer answer is:

  1. Get the bounds from CartoDB. There are a few ways to do this, but the easiest is likely to use sql.getBounds(). This will looks something like:

    var sql = new cartodb.SQL({ user: 'tbushman' });
    sql.getBounds(YOUR_QUERY).done(function(bounds) {
        // TODO Set Leaflet's bounds here
    });
    

    Where YOUR_QUERY is whatever SQL query you used to filter your layer. For example, looking in your code, one of them is:

    SELECT * FROM full_uu_tb WHERE type = 'Health and Ability'
    
  2. Now set your Leaflet map's bounds (on the TODO line above). This should be as simple as what you already have in the code above:

    map.fitBounds(bounds);
    
  3. Get rid of most of the bounds-handling code you have above, everything between (but not including) $(this).addClass('selected'); and LayerActions[$(this).attr('id')] ();

Finally, the LayerActions object in your full code is a nice way of separating the various SQL queries from the rest of the code. The only problem is that it is a bit redundant and you're going to need to get the actual SQL query in order to get the bounds. I would recommend storing only the SQL queries this way and moving the rest into $('.button').click(...).