Cannot render vector tiles (.mbtiles) file with leaflet

I am trying to render some locally-stored and vector-based tiles download from OpenMapTile. The reason I am doing that is because my end application will only run on a computer that cannot be connected to the internet.

I have read many different things on whether or not leaflet can render vector-based tiles but it seems that it can from some examples.

It seems that it is not possible with Vector Grid that only does raster tiles but that it is possible with Leaflet.TileLayer.MBTiles

So I tried to do just that but always stumble upon an empty page when trying it out... I have the controllers for the map but it just doesn't display anything. Here is my MWE.

<!DOCTYPE html>
<html>
<head>

    <title>VectorGrid.Protobuf example</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />

</head>
<body style='margin:0'>

    <div id="map" style="width: 100vw; height: 100vh; background: white"></div>

    <script type="text/javascript"  src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script type="text/javascript"  src="https://unpkg.com/[email protected]"></script>

    <script src="https://unpkg.com/[email protected]/js/sql.js"></script>

    <!--<script src="https://unpkg.com/[email protected]/Leaflet.TileLayer.MBTiles.js"></script>-->
    <script src="Leaflet.TileLayer.MBTiles.js"></script>


    <!-- <script type="text/javascript" src="../dist/Leaflet.VectorGrid.bundled.js"></script> -->
    <script>

            var vectorTileStyling = {

            water: {
                fill: true,
                weight: 1,
                fillColor: '#06cccc',
                color: '#06cccc',
                fillOpacity: 0.2,
                opacity: 0.4,
            },
            admin: {
                weight: 1,
                fillColor: 'pink',
                color: 'pink',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            waterway: {
                weight: 1,
                fillColor: '#2375e0',
                color: '#2375e0',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            landcover: {
                fill: true,
                weight: 1,
                fillColor: '#53e033',
                color: '#53e033',
                fillOpacity: 0.2,
                opacity: 0.4,
            },
            landuse: {
                fill: true,
                weight: 1,
                fillColor: '#e5b404',
                color: '#e5b404',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            park: {
                fill: true,
                weight: 1,
                fillColor: '#84ea5b',
                color: '#84ea5b',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            boundary: {
                weight: 1,
                fillColor: '#c545d3',
                color: '#c545d3',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            aeroway: {
                weight: 1,
                fillColor: '#51aeb5',
                color: '#51aeb5',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            road: { // mapbox & nextzen only
                weight: 1,
                fillColor: '#f2b648',
                color: '#f2b648',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            tunnel: {   // mapbox only
                weight: 0.5,
                fillColor: '#f2b648',
                color: '#f2b648',
                fillOpacity: 0.2,
                opacity: 0.4,
//                  dashArray: [4, 4]
            },
            bridge: {   // mapbox only
                weight: 0.5,
                fillColor: '#f2b648',
                color: '#f2b648',
                fillOpacity: 0.2,
                opacity: 0.4,
//                  dashArray: [4, 4]
            },
            transportation: {   // openmaptiles only
                weight: 0.5,
                fillColor: '#f2b648',
                color: '#f2b648',
                fillOpacity: 0.2,
                opacity: 0.4,
//                  dashArray: [4, 4]
            },
            transit: {  // nextzen only
                weight: 0.5,
                fillColor: '#f2b648',
                color: '#f2b648',
                fillOpacity: 0.2,
                opacity: 0.4,
//                  dashArray: [4, 4]
            },
            building: {
                fill: true,
                weight: 1,
                fillColor: '#2b2b2b',
                color: '#2b2b2b',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            water_name: {
                weight: 1,
                fillColor: '#022c5b',
                color: '#022c5b',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            transportation_name: {
                weight: 1,
                fillColor: '#bc6b38',
                color: '#bc6b38',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            place: {
                weight: 1,
                fillColor: '#f20e93',
                color: '#f20e93',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            housenumber: {
                weight: 1,
                fillColor: '#ef4c8b',
                color: '#ef4c8b',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            poi: {
                weight: 1,
                fillColor: '#3bb50a',
                color: '#3bb50a',
                fillOpacity: 0.2,
                opacity: 0.4
            },
            earth: {    // nextzen only
                fill: true,
                weight: 1,
                fillColor: '#c0c0c0',
                color: '#c0c0c0',
                fillOpacity: 0.2,
                opacity: 0.4
            },


            // Do not symbolize some stuff for mapbox
            country_label: [],
            marine_label: [],
            state_label: [],
            place_label: [],
            waterway_label: [],
            poi_label: [],
            road_label: [],
            housenum_label: [],


            // Do not symbolize some stuff for openmaptiles
            country_name: [],
            marine_name: [],
            state_name: [],
            place_name: [],
            waterway_name: [],
            poi_name: [],
            road_name: [],
            housenum_name: [],
        };


        // Monkey-patch some properties for nextzen layer names, because
        // instead of "building" the data layer is called "buildings" and so on
        vectorTileStyling.buildings  = vectorTileStyling.building;
        vectorTileStyling.boundaries = vectorTileStyling.boundary;
        vectorTileStyling.places     = vectorTileStyling.place;
        vectorTileStyling.pois       = vectorTileStyling.poi;
        vectorTileStyling.roads      = vectorTileStyling.road;



        var map = L.map('map');


        //var openmaptilesUrl = "https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf.pict?key={key}";
        var openmaptilesUrl = "http://127.0.0.1:8080/2017-07-03_france_toulouse.mbtiles";



        var openmaptilesVectorTileOptions = {
            rendererFactory: L.canvas.tile,
            attribution: '<a href="https://openmaptiles.org/">&copy; OpenMapTiles</a>, <a href="http://www.openstreetmap.org/copyright">&copy; OpenStreetMap</a> contributors',
            vectorTileLayerStyles: vectorTileStyling,
            subdomains: '0123',
            key: 'UmmATPUongHdDmIicgs7',
            maxZoom: 14
        };

        var mb = L.tileLayer.mbTiles(openmaptilesUrl).addTo(map);
        /*var openmaptilesPbfLayer = L.vectorGrid.protobuf(openmaptilesUrl, openmaptilesVectorTileOptions).addTo(map);*/


        map.setView({ lat: 47.040182144806664, lng: 9.667968750000002 }, 0);


        /*L.control.layers({
            OpenMapTiles: openmaptilesPbfLayer,
        }, {}, {collapsed: false}).addTo(map);*/




    </script>
</body>
</html>

Since I had trouble finding Leaflet.TileLayer.MBTiles, https://gitlab.com/IvanSanchez/Leaflet.TileLayer.MBTiles/blob/master/Leaflet.TileLayer.MBTiles.js is a version that you can download

As for an example tile, you can use this one (directly downloaded from OpenMapTiles focusing on France's Toulouse as it was a rather smaller mbtile file).

I really don't understand what the problem is. It came to my mind that it could very well be that leaflet cannot read vector tiles, in which case I thought that I could try to convert them so that I end up with raster tiles, but I could not find a way to do so. I don't know what the best solution could be... It seems that some people have managed to make it work with vector AND raster tiles as explained on StackOverflow but I just can't seem to find a way to make it work on my own and this linked post is not very detailed.

Thank you in advance for the help.

Answers:

Answer

Try this change:

var openmaptilesUrl = "http://127.0.0.1:8080/2017-07-03_france_toulouse.mbtiles";

for this:

var openmaptilesUrl = "./2017-07-03_france_toulouse.mbtiles";

and store your mbtiles file to root of your web next to index.html

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.