问题
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/">© OpenMapTiles</a>, <a href="http://www.openstreetmap.org/copyright">© 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