4

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>
2

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>

  • Cheers Chris W! This is a big help, I'm only just starting with this map and to get over the first hurdle is brilliant! I think me loading all those resources was my way of trying to make sure I had every library to work with, no idea it was going to cause me even more issues! Thanks again...now to figure out the infowindow problem! – SVP Jul 10 '15 at 7:24
  • "mapbox.standalone.js" that's the badger! Cheers. – Amn Sep 2 '16 at 13:59
0

How many layers do you have in your viz.json? Are you getting any errors in the console?

I believe using the cartodb.createLayer() method you might have to use a callback function to bring the Mapbox tile layer behind your data layer from CartoDB. Instead of adding the CartoDB layer to the map right away, add the layer in the callback function and then bring the Mapbox layer to the back using Leaflet's L.tileLayer.bringToBack() method

Here is an example of how I accomplished this.

  • Hi Chris, thanks for the answer. If you can tell from my code, I'm a total novice at this, so whilst I get the gist of what you are saying, I think my HTML knowledge is failing me when trying to implement it. I have tried the bringToBack method, but I imagine I am doing it wrong, because now instead of a grey screen with the search box and zoom contorls, I just grey. In answer to your question though, I only have one layer in the viz.json, its about 150 1km polygon tiles. As for errors in the console, there seems to be nothing, it's almost as if it works, but just doesn't let me see it! – SVP Jul 9 '15 at 13:19
  • can you post your map / code live somewhere like in a js fiddle? – clhenrick Jul 9 '15 at 13:31
  • I think this is it jsfiddle.net/g6vf6sbv – SVP Jul 9 '15 at 13:53
  • 1
    Ah looks like Chris Wong is correct about the mapbox.standalone.js library. From there you can either do: layers.Streets.bringToBack() or layer.setZIndex(5) in the .on('done') callback to get your data layer on top of the MapBox basemap. jsfiddle.net/hpm1rwoy/6 – clhenrick Jul 9 '15 at 15:13
  • Thanks Chris H, I spent a long evening working out what both you and Chris W have explained. I think I get it now, not not only was my layer loading up behind everything else, I was trying to load too many Leaflet libraries! I'm learning, I'll get there soon I imagine. Now I have to figure out how to get the links working in the infowindows, another problem, another day! – SVP Jul 10 '15 at 7:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.