Leaflet.VectorGrid icon indicating copy to clipboard operation
Leaflet.VectorGrid copied to clipboard

How can I use maxNativeZoom to continue to show the vector tiles beyond their maximum zoom level?

Open mcleantom opened this issue 2 years ago • 3 comments

I have a tile set that is defined for zoom levels 0-2, but I want it to continue to show beyond a zoom level of 2. I believe this is done using maxNativeZoom however this setting doesnt seem to work, as the tiles are hidden beyond a zoom level of 2.

The full code for this problem is:

<html>

<head>
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script src="https://unpkg.com/leaflet.vectorgrid@latest/dist/Leaflet.VectorGrid.bundled.js"></script>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
    <script src="https://d3js.org/d3-scale.v1.min.js"></script>
    <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
    <script src="https://d3js.org/d3-color.v1.min.js"></script>

    <style>
        body {
            margin: 0;
        }

        #map {
            background: #F9F7F7;
        }
    </style>
</head>

<body>
    <div id='map' style='width: 100vw; height: 100vh'></div>
    <script>
        var map = L.map('map');

        // add openstreetmap basemap
        L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
            attribution: '© OpenStreetMap contributors'
        }).addTo(map);

        const URL = 'https://gfswindtiles.s3.eu-west-2.amazonaws.com/tiles/{z}/{x}/{y}.pbf'
        const interpolator = d3.scaleLinear()
            .domain([0, 4, 12, 16, 20, 24, 28].map(x => x * 1.94384))
            .range(["hsl(0, 0%, 100%)", "hsl(202, 88%, 51%)", "hsl(157, 96%, 53%)", "hsl(60, 100%, 49%)", "hsl(26, 100%, 49%)", "hsl(0, 64%, 43%)", "hsl(274, 47%, 29%)"]);

        const opacityInterpolaotr = d3.scaleLinear()
            .domain([0, 4, 12, 28].map(x => x * 1.94384))
            .range([0, 0, 1, 1]);

        const vectorStyle = {
            wind: function (properties, zoom) {
                var speed = properties.wind_speed_max;
                const color = interpolator(speed);
                const opacity = opacityInterpolaotr(speed);
                return {
                    fill: true,
                    fillColor: color,
                    stroke: false,
                    fillOpacity: opacity
                };
            }
        };

        L.vectorGrid.protobuf(URL, {
            rendererFactory: L.canvas.tile,
            // token: TOKEN,
            vectorTileLayerStyles: vectorStyle,
            maxNativeZoom: 20,
            maxZoom: 2
        }).addTo(map);

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

    </script>
</body>

</html>

Any help would be appreciated!

mcleantom avatar Sep 06 '23 13:09 mcleantom

You've set:

            maxNativeZoom: 20,
            maxZoom: 2

Have you tried setting both to 20?

movahhedi avatar Mar 09 '25 07:03 movahhedi

IIRC the syntax to use for this scenario is:

            maxNativeZoom: 2,
            maxZoom: 20

maxNativeZoom → The highest zoom level available via the physical tiles maxZoom → The highest zoom level to display via the GUI

There may be additional configuration required for >2× overzoom (not sure). I recall having layers disappear when exceeding 1 level of overzoom (that was for raster tiles, not vector ones).

Alex-Kent avatar Mar 09 '25 14:03 Alex-Kent

Check https://leafletjs.com/reference.html#gridlayer-maxnativezoom

You need to set minZoom and maxZoom to the zoom levels, where the layer should start and end showing. minNativeZoom and maxNative Zoom needs to be set to the tile provider properties (which layers are provided).

pkolmann avatar Apr 03 '25 14:04 pkolmann