Last active
October 19, 2019 07:37
-
-
Save ramiroaznar/8dd773586170c8c983e8439e14c697a5 to your computer and use it in GitHub Desktop.
leaflet.draw + CARTO
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>leaflet.draw + CARTO</title> | |
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> | |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> | |
<link rel="shortcut icon" href="https://cartodb.com/assets/favicon.ico" /> | |
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/3.15/themes/css/cartodb.css" /> | |
<script src="http://libs.cartocdn.com/cartodb.js/v3/3.15/cartodb.js"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.3/leaflet.draw.css" /> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.3/leaflet.draw.js"></script> | |
<style> | |
html, body, #map { | |
height: 100%; | |
padding: 0; | |
margin: 0; | |
} | |
#infobox{ | |
width: 200px; | |
height: 200px; | |
position: absolute; | |
top: 20px; | |
left: 20px; | |
background-color: white; | |
opacity: 0.6; | |
text-align: center; | |
font-family: "Open Sans"; | |
} | |
</style> | |
</head> | |
<body> | |
<!-- map div --> | |
<div id="map"></div> | |
<!-- infobox div --> | |
<div id="infobox"> | |
<h4>Draw a geometry</h4> | |
<p id="count">Count</p> | |
<p id="total">Total</p> | |
<p id="avg">Average</p | |
</div> | |
<script type="text/cartocss" id="style"> | |
#layer { | |
marker-width: 7; | |
marker-fill: #EE4D5A; | |
marker-fill-opacity: 0.9; | |
marker-line-color: #FFFFFF; | |
marker-line-width: 1; | |
marker-line-opacity: 1; | |
marker-type: ellipse; | |
marker-allow-overlap: true; | |
} | |
</script> | |
<script type="text/sql" id="query"> | |
SELECT | |
a.* | |
FROM | |
populated_places a | |
</script> | |
<script> | |
function main() { | |
// get styles & query | |
const style = $("#style").text(), | |
query = $("#query").text(), | |
// declare map variable | |
map = L.map('map', { | |
zoomControl: false, | |
center: [41, -15], | |
zoom: 3 | |
}); | |
// add basemap | |
L.tileLayer('http://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png', {attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="http://cartodb.com/attributions">CARTO</a>'}).addTo(map); | |
//prep the draw FeatureGroup and add Leaflet.draw controls to map | |
const editableLayers = new L.FeatureGroup(); | |
map.addLayer(editableLayers); | |
const drawPluginOptions = { | |
position: 'topright', | |
draw: { | |
polygon: { | |
allowIntersection: false, | |
drawError: { | |
color: '#46945C', | |
message: '<strong>Oh snap!<strong> you can\'t draw that!' | |
}, | |
shapeOptions: { | |
color: '#826DBA' | |
} | |
}, | |
polyline: false, | |
circle: false, | |
rectangle: false, | |
marker: false, | |
}, | |
edit: { | |
featureGroup: editableLayers, | |
remove: false | |
} | |
}; | |
const drawControl = new L.Control.Draw(drawPluginOptions); | |
map.addControl(drawControl); | |
// add CARTO layer | |
cartodb.createLayer(map, { | |
user_name: 'ramirocartodb', | |
type: 'cartodb', | |
sublayers: [{ | |
sql: query, | |
cartocss: style | |
}] | |
}).addTo(map) | |
.done(function(layer){ | |
// declare sublayer variable | |
const cityLayer = layer.getSubLayer(0); | |
// draw layer, intersect with CARTO layer & get count, total & avg data | |
map.on('draw:created', function(e) { | |
// draw layer | |
const drawLayer = e.layer; | |
editableLayers.addLayer(drawLayer); | |
// get geojson from the draw layer | |
const geojson = drawLayer.toGeoJSON(), | |
geom = JSON.stringify(geojson["geometry"]), | |
// set new query & style for intersected geometries | |
new_query = query + ` WHERE ST_Intersects(ST_SetSRID(ST_GeomFromGeoJSON('${geom}'), 4326), a.the_geom)`; | |
cityLayer.setSQL(new_query); | |
cityLayer.setCartoCSS('#layer {marker-width: 7; marker-fill: #FFFFFF; marker-fill-opacity: 0.9; marker-line-color: #EE4D5A; marker-line-width: 1; marker-line-opacity: 1; marker-type: ellipse; marker-allow-overlap: true;}'); | |
// get count, total and avg from intersected geometries | |
const sql = new cartodb.SQL({ user: 'ramirocartodb' }), | |
widget_query = `SELECT count(a.*) as count, sum(a.pop_max) as total, avg(a.pop_max) as avg FROM populated_places a WHERE ST_Intersects(ST_SetSRID(ST_GeomFromGeoJSON('${geom}'), 4326), a.the_geom)`; | |
sql.execute(widget_query) | |
.done(function(data) { | |
const count = JSON.stringify(data.rows[0].count), | |
total = JSON.stringify(data.rows[0].total), | |
avg = JSON.stringify(data.rows[0].avg); | |
// return count, total and avg in the infobox | |
$('#count').text(count); | |
$('#total').text(total); | |
$('#avg').text(avg); | |
}) | |
.error(function(errors) { | |
// errors contains a list of errors | |
console.log("errors:" + errors); | |
}) | |
// remove editable layer and clear parameters from the infobox when clicking on the draw layer | |
drawLayer.on('click', function(e){ | |
editableLayers.clearLayers(e.layer); | |
cityLayer.setSQL(query); | |
cityLayer.setCartoCSS(style); | |
// clear parameters from the infobox | |
$('#count').text('Count'); | |
$('#total').text('Total'); | |
$('#avg').text('Average'); | |
}); | |
}); | |
}); | |
} | |
window.onload = main; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment