This content applies to a previous version of CARTO
In October 2021 we released a new version of our platform. You can find the latest documentation at docs.carto.com
Draw geometries on a CARTO.js map
Overview
This guide demonstrates how to implement drawing tools on a CARTO.js map to filter data interactively. The example uses either the Leaflet.draw plugin or Google Maps drawing library to create geometries – specifically circles – that intersect with and filter a CARTO dataset called ne_10m_populated_places_simple.
The implementation follows these steps:
- Create a CARTO.js map with one layer
- Instantiate the drawing tool with circle options
- Create a
circleCountPointsIntersect(radius, lat, lng)function to update the layer source - Set an event listener to capture the circle’s radius and center coordinates
- Call the filter function to display only intersecting data
Differences between Leaflet and Google Maps approach
Leaflet
Load the Leaflet Draw plugin:
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.13/leaflet.draw.css" />
Configure the Draw controller:
let drawControl = new L.Control.Draw({
draw: {
polygon: false,
polyline: false,
line: false,
marker: false,
rectangle: false,
circle: {
shapeOptions: {
color: 'green',
weight: 0.1,
opacity: 0.5
}
},
circlemarker: false,
},
edit: false
});
map.addControl(drawControl);
Listen for drawn circles:
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
map.addLayer(layer);
let radius = layer.getRadius();
let centerLat = layer.getLatLng().lat;
let centerLng = layer.getLatLng().lng;
circleCountPointsIntersect(radius, centerLat, centerLng)
});
Google Maps
Load the Google Maps drawing library:
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=drawing&v=3.32"></script>
Configure the drawing manager:
var drawingManager = new google.maps.drawing.DrawingManager({
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: ['circle']
},
circleOptions: {
fillColor: 'green',
fillOpacity: 0.5,
strokeWeight: 0.1,
clickable: false,
editable: false,
zIndex: 1
}
});
drawingManager.setMap(map);
Listen for drawn circles:
google.maps.event.addListener(drawingManager, 'circlecomplete', function (circle) {
let radius = circle.getRadius();
let centerLat = circle.getCenter().lat();
let centerLng = circle.getCenter().lng();
circleCountPointsIntersect(radius, centerLat, centerLng)
});
Bonus: save drawn data into CARTO dataset
You can persist drawn geometries to a CARTO dataset by:
- Creating a CARTO dataset with empty
cartodb_idandthe_geomfields - Generating an API Key with SQL INSERT permissions
- Using the CARTO SQL API to execute INSERT operations
Example using Leaflet Draw:
map.on(L.Draw.Event.CREATED, function (e) {
let layer = e.layer;
map.addLayer(layer);
let radius = layer.getRadius();
let centerLat = layer.getLatLng().lat;
let centerLng = layer.getLatLng().lng;
circleCountPointsIntersect(radius, centerLat, centerLng)
let layerAdded = JSON.stringify(layer.toGeoJSON().geometry)
fetch(`https://cartojs-test.carto.com/api/v2/sql?q=
INSERT INTO insert_polygons(the_geom)
VALUES(
St_SetSRID(
St_GeomFromGeoJSON('${layerAdded}'), 4326
)
)&api_key=XXXXX`,
{
headers: new Headers({
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*'
}),
method: 'get',
mode: 'no-cors'
}
).then(function(response){
console.log(response)
}).catch(function(err){
console.log(err)
})
});
