block by andrewxhill 9885c36421fa7790abe6

Use Leaflet Draw to filter and style a CartoDB layer

Full Screen

index.html

<!DOCTYPE html>
<html>
<head>
	<title>Leaflet.draw drawing and editing tools</title>
    <link 
        rel="stylesheet" 
        href="//cdn.leafletjs.com/leaflet-0.7/leaflet.css"
    />
    <link rel="stylesheet" href="//libs.cartocdn.com/cartodb.js/v3/themes/css/cartodb.css" />
    <link 
        rel="stylesheet" 
        href="//leaflet.github.io/Leaflet.draw/leaflet.draw.css"
    />

    <script src="//libs.cartocdn.com/cartodb.js/v3/cartodb.js"></script>
    <script
        src="//leaflet.github.io/Leaflet.draw/leaflet.draw.js">
    </script>
    <!-- include cartodb.js library -->


</head>
<body>
	<div id="map" style="width: 800px; height: 600px; border: 1px solid #ccc"></div>
	<button id="changeColor">Rectangle -> Blue</button>
	<script>

        var map = new L.Map('map', {
          zoomControl: false,
          center: [43, 0],
          zoom: 3
        });

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

			L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';

			var drawControl = new L.Control.Draw({
				position: 'topright',
				draw: {
					polyline: false,
					polygon: {
						allowIntersection: false,
						showArea: true,
						drawError: {
							color: '#b00b00',
							timeout: 1000
						},
						shapeOptions: {
							color: '#bada55'
						}
					},
					circle: false,
					marker: false
				}
			});
			map.addControl(drawControl);



		function updateLayer(query, layer){
			// Run a query to get new Max / Min of layer
		    var sql = cartodb.SQL({ user: 'andrew' });
		        sql.execute("select min(pop_max) min, max(pop_max) max from ("+query+") a").done(function(data) {
		        // Generate a new CartoCSS to apply
		        var limit = (data.rows[0].min+(data.rows[0].max-data.rows[0].min)/10); // something
		    	var cartocss = "#ne_10m_populated_places_simple_3{ marker-fill: #000; marker-fill-opacity: 0.9; marker-line-color: #fff; marker-line-width: 0.5; marker-line-opacity: 1; marker-placement: point; marker-type: ellipse; marker-width: 8; marker-allow-overlap: true; [pop_max < "+limit+"]{ marker-fill: red;}}";
		    	// Set our query to filter the layer
      			layer.setSQL(query);
      			// Set our new Style
		    	layer.setCartoCSS(cartocss)

		     });
		}



        cartodb.createLayer(map, '//andrew.cartodb.com/api/v2/viz/32e5207e-fb95-11e3-9e94-0edbca4b5057/viz.json')
        .addTo(map)
        .on('done', function(layer) {

        	// Keep track of all draw objects
			var drawnItems = new L.FeatureGroup();
			map.addLayer(drawnItems);

			// // Set the title to show on the polygon button

			map.on('draw:created', function (e) {
				var type = e.layerType,
					draw_layer = e.layer;

				// Show the polygon on the map
				drawnItems.addLayer(draw_layer);

				// Get the coordinates of the polygon we just drew
				var poly = draw_layer.getLatLngs();
				var sql_poly = [];
				for (i in poly){

					sql_poly.push("CDB_LatLng("+poly[i].lat+","+poly[i].lng+")")
				}
				//SQL polygon must be a CLOSED loop
				sql_poly.push("CDB_LatLng("+poly[0].lat+","+poly[0].lng+")")


				// Join our coordinates and a SQL query
				var query = "SELECT * FROM ne_10m_populated_places_simple_3 WHERE ST_Intersects(the_geom, ST_MakePolygon(ST_MakeLine(Array["+sql_poly.join()+"])))";
				// Run our function to update SQL and Style
      			updateLayer(query, layer.getSubLayer(0))
			});
        })
        .on('error', function(err) {
          alert("some error occurred: " + err);
        });

	</script>
</body>
</html>