The issue is that there are more layers than you probably hide with vectorTileLayerStyle
. Some of them are only shown on certain zoom levels.
The most up-to-date code of Leaflet.VectorGrid
has an option filter
that takes a function to filter out unwanted layers (see line 96). Unfortunately, the most recent version on npm and unpkg.com are older than the code on GitHub.
Anyways, as a workaround, you could consider to watch the internal object _dataLayerNames
of the L.VectorGrid
instance and update the vectorTileLayerStyles
whenever a new layer is added.
In order to accomplish this in the following example, I am using a Proxy
object for the internal object and replace the internal object with the proxy object:
const map = L.map('map')
.setView([46.801111, 8.226667], 7);
const basemap = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
// add a link to OpenStreetMap (omitted here for shorter line width)
attribution: '© OpenStreetMap contributors'
});
basemap.addTo(map);
// URL in this example shortened for better readability on StackOverflow
const url = 'https://basemaps.arcgis.com/.../VectorTileServer/tile/{z}/{y}/{x}.pbf';
const tileOptions = {
rendererFactory: L.canvas.tile,
vectorTileLayerStyles: {
Road: {
weight: 2,
color: '#ff0000',
fill: false,
}
},
// see https://www.arcgis.com/home/item.html?id=30d6b8271e1849cd9c3042060001f425
attribution: `Esri, TomTom, Garmin, FAO,
NOAA, USGS, and the GIS User Community`,
};
const layer = L.vectorGrid.protobuf(url, tileOptions);
function isLayerHidden(layerName) {
return layerName != 'Road';
}
// workaround, we watch the internal _dataLayerNames object for changes
// and if there are changes, we set any layer style that is unwanted
// to an empty array
layer._dataLayerNames = new Proxy(layer._dataLayerNames, {
set: (target, key, value) => {
if (isLayerHidden(key)) {
layer.options.vectorTileLayerStyles[key] = [];
}
target[key] = value;
return true;
},
});
map.addLayer(layer);
Caveat: This works because the _dataLayerNames
object is updated before the styling is handled. That said, using internal (private) objects is usually not best practise. If the maintainers decide to change the internal structure and go ahead and releasing new versions, the code with the workaround may not work anymore.
Also, I did not do any performance testing with this workaround using a proxy object. However, I have not observed issues when testing the code in a jsfiddle.net sandbox.
Alternatively, if you are okay with hosting your own copy of Leaflet.VectorGrid
, the easiest way is probably to clone the GitHub repository, use the option filter
and create your own distribution files.
Another approach to get all layers could be parsing the Style file to retrieve all layers, then building the vectorTileLayerStyle
option and finally using L.vectorGrid.protobuf
. (I haven't had a chance to test it myself yet.)