Cannot render vector tiles (.mbtiles) file with leaflet

狂风中的少年 提交于 2019-12-10 10:16:16

问题


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/leaflet@1.0.3/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/leaflet@1.3.1/dist/leaflet.js"></script>
    <script type="text/javascript"  src="https://unpkg.com/leaflet.vectorgrid@1.2.0"></script>

    <script src="https://unpkg.com/sql.js@0.3.2/js/sql.js"></script>

    <!--<script src="https://unpkg.com/leaflet.tilelayer.mbtiles@latest/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.


回答1:


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



来源:https://stackoverflow.com/questions/51850396/cannot-render-vector-tiles-mbtiles-file-with-leaflet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!