Skip to content

Instantly share code, notes, and snippets.

@jsanz
Last active December 1, 2017 19:27
Show Gist options
  • Save jsanz/8b89d374fda49a5baa02 to your computer and use it in GitHub Desktop.
Save jsanz/8b89d374fda49a5baa02 to your computer and use it in GitHub Desktop.
JavaScript CartoDB.js: Remove layer from GMaps

On this example we add and remove a layer from a Google Maps Instance.

The thing is you need to explicitely disable the interaction and then execute the off() method in order to completely detach the layer from the map object, otherwise events will still be triggered and you'll have more than one infowindows and several log lines on the console.

<!DOCTYPE html>
<html>
<head>
<title>GMs and IW | CartoDB.js</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="http://cartodb.com/assets/favicon.ico" />
<style>
html, body, #map {
height: 100%;
padding: 0;
margin: 0;
}
.controls{
position: absolute;
top:20px;
right: 20px;
background: white;
z-index: 100;
padding: 20px;
width: 70px;
text-align: center;
}
.controls span{
color: blue;
cursor: pointer;
}
</style>
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/3.15/themes/css/cartodb.css" />
</head>
<body>
<div class="controls">
<span class="toggle">Add</span>
</div>
<div id="map">
</div>
<!-- include google maps library + visualization-->
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=visualization"></script>
<!-- include cartodb.js library -->
<script src="http://libs.cartocdn.com.s3.amazonaws.com/cartodb.js/v3/3.15/cartodb.uncompressed.js"></script>
<script>
var map, sublayer, isRemoveLayer=false;
function main() {
// Map center
var myOptions = {
zoom: 3,
center: new google.maps.LatLng(40, 0),
disableDefaultUI: true,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
// Render basemap
map = new google.maps.Map(document.getElementById("map"), myOptions);
var urlLayer = "https://team.cartodb.com/u/ramirocartodb/api/v2/viz/d3b411a0-e521-11e5-bf3f-0e31c9be1b51/viz.json";
/* Add a layer to the map */
var addLayer = function(){
console.log("Add Layer");
cartodb.createLayer(map, urlLayer)
.addTo(map)
.done(function(layer){
sublayer = layer.getSubLayer(0);
// Attach a simple log
layer.getSubLayer(0).on('featureClick',function(){
console.log("Click at " + Math.random());
});
$('.toggle').html("Remove");
});
};
/* Remove a layer from the map */
var removeLayer = function(){
console.log("Remove Layer");
map.overlayMapTypes.clear();
/*
If you don't add these two lines you get multiple
instances of the layer receiving events
*/
sublayer.setInteraction(false);
sublayer.off();
sublayer = null; // this is optional
$('.toggle').html("Add");
}
$('.toggle').click(function(){
if (isRemoveLayer){
removeLayer();
} else {
addLayer();
}
isRemoveLayer = ! isRemoveLayer;
});
}
window.onload = main;
</script>
</body>
</html>
@nerik
Copy link

nerik commented Feb 17, 2017

Thanks, that was useful.
Note that map.overlayMapTypes.clear(); will kill all overlays on the Google Map, including non CARTO ones.
Maybe a more subtle approach:

  removeCartoLayer(layer) {
    let cartoLayer;
    let overlayMapTypeIndex;
    this.map.overlayMapTypes.forEach((overlayMapType, index) => {
      if (overlayMapType && overlayMapType.id && overlayMapType.id === layer.id) {
        cartoLayer = overlayMapType;
        overlayMapTypeIndex = index;
      }
    });
    if (overlayMapTypeIndex !== undefined) {
      for (let subLayerIndex = 0, subLayersCount = cartoLayer.getSubLayerCount(); subLayerIndex < subLayersCount; subLayerIndex++) {
        const subLayer = cartoLayer.getSubLayer(subLayerIndex);
        subLayer.setInteraction(false);
        subLayer.off();
      }
      this.map.overlayMapTypes.removeAt(overlayMapTypeIndex);
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment