[GIS] How to add a CartoDB layer to a MapBox map

cartohtmlmapbox

I'm having some trouble adding a CartoDB layer to an L.mapbox.map, I thought it was a pretty simple thing to do in the HTML but it's just not working and I don't know why. My CartoDB layer has vector tiles whose info window opens to a clickable link. My map is a MapBox map that has imagery and streets layers from my MapBox account and the mapbox.places geocoder control.

The code is below and I am hoping someone out there can help me figure out my mistakes because all I am getting is a grey screen and it's a puzzle I'm having a nightmare trying to solve.

<html>
<head>
<meta charset=utf-8 />
<title>Tiles Map</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-   scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox.js/v2.2.1/mapbox.js'>      </script>
<link href='https://api.tiles.mapbox.com/mapbox.js/v2.2.1/mapbox.css' rel='stylesheet' />
<link rel="stylesheet" href="http://libs.cartocdn.com/cartodb.js/v3/themes/css/cartodb.css" />
<script src="http://libs.cartocdn.com/cartodb.js/v3/cartodb.js"></script>
</head>
<body>
<style>
body { margin: 0; padding: 0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<div id='map'></div>
<script>
L.mapbox.accessToken = 'MY_OWN_MAPBOX_TOKEN';
  var map = L.mapbox.map('map', null)
.addControl(L.mapbox.geocoderControl('mapbox.places', {keepOpen: true}))
.setView([51.505537,-0.115528], 12);

 var cdb_layer = cartodb.createLayer(map, 'MY_CARTODB_DATA/viz.json')
addTo(map); 
  var layers = {
  Streets: L.mapbox.tileLayer('MY_MAPBOX_STREETS_MAP'),
  Imagery: L.mapbox.tileLayer('MY_MAPBOX_IMAGERY_MAP')
  };

  layers.Streets.addTo(map);
  L.control.layers(layers).addTo(map);
</script>
</body>
</html>

Best Answer

Since both mapbox.js and cartodb.js include leaflet, you are attempting to load leaflet twice.

Mapbox has a "standalone" version of their library that doesn't load include leaflet, so loading this plus cartodb.js makes everything work.

I also added a .setZIndex() to the cartodb layer to make it show up on top.

The code below should work for you!

<!DOCTYPE html>
<head>
    <meta charset=utf-8 />
    <title>Tiles Map</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />

    <link href='https://api.tiles.mapbox.com/mapbox.js/v2.2.1/mapbox.css' rel='stylesheet' />
    <link rel="stylesheet" href="https://cartodb-libs.global.ssl.fastly.net/cartodb.js/v3/3.15/themes/css/cartodb.css" />
    <style>
        body {
            margin: 0;
            padding: 0;
        }
        #map {
            position:absolute;
            top:0;
            bottom:0;
            width:100%;
        }
    </style>
</head>

<body>

    </head>
    <div id='map'></div>

   <!--  Important:  Both mapbox.js and cartodb.js use Leaflet, so loading both libraries would load leaflet twice and cause problems.  Mapbox has a "standalone" version of their library that does not inlude leaflet, so in this scenario we are using leaflet provided by cartodb.js -->
    <script src="https://cartodb-libs.global.ssl.fastly.net/cartodb.js/v3/3.15/cartodb.uncompressed.js"></script>
    <script src='https://api.tiles.mapbox.com/mapbox.js/v2.2.1/mapbox.standalone.js'></script>
    <script>
        L.mapbox.accessToken = 'pk.eyJ1Ijoic3ZwdmVydGV4IiwiYSI6IkxuUklIQUEifQ.VlwL0B5MUZcEqU-XsV8TVQ';

        var map = L.map('map', {
            center: [51.505537, -0.115528],
            zoom: 12
        });

        map.addControl(L.mapbox.geocoderControl('mapbox.places', {
            keepOpen: true
        }));

        var layers = {
            Streets: L.mapbox.tileLayer('svpvertex.ml8nijl4'),
            Imagery: L.mapbox.tileLayer('svpvertex.m0ammo9e')
        };

        layers.Streets.addTo(map);

        //add cartoDB layer, set z-index so it shows up on top
        cartodb.createLayer(map, 'https://svpvertex.cartodb.com/api/v2/viz/2a795afa-208c-11e5-ada2-0e4fddd5de28/viz.json').addTo(map)
        .on('done', function(layer) {
            layer.setZIndex(5);
        });

        L.control.layers(layers).addTo(map);

    </script>
</body>

Related Question