Why is zoom level interpreted different in mapbox-gl-js? - mapbox-gl-js

Comparing maps from openlayers, leaflet and mapbox-gl-js, I can see that mapbox-gl-js has a different map image for the same center and zoom combination, and the same div size. It seems to zoom in one level extra compared to the openlayers and leaflet maps. Why is this?

yep that's correct. this one level difference is because the vector tiles used by mapbox-gl-js are 512px and in openlayers/leaflet/mapbox.js the raster tiles used are 256px. in other words, the appearance of a 512 tile at zoom level 0 is the same as the appearance of a 256 tile at zoom level 1. hope this helps!
512px tile 0/0/0
256px tile 1/0/0

You can set the zoomFactor of OpenLayerMap like this to make same as mapbox-gl
const view = new View({
center: [lng, lat],
zoom: zoom,
zoomFactor: 2.38
})
Also you should set the tileSize to 512 in openlayer map setting

Related

Leaflet: caculate zoom levels for resolutions for map with CRS = EPSG:25832

my map has crs EPSG:25832. I have a layergroup containing two layers. One layer shall be visible between map resolution 0.149 and 19.093 m/px, the second layer shall be visible between resolution 19.093 and 156412 m/px. So while zooming the layers will switch their visibility.
In leaflet I can only set minzoom and maxzoom for a layer not a resolution. So I need to find a way to calculate the zoom levels based on the given resolutions.
For EPSG:3857 this works pretty good with the equations from here:
https://wiki.openstreetmap.org/wiki/Zoom_levels.
But I have no idea how to properly calculate the zoom levels for EPSG:25832.
Does anybody have any suggestions?
Thanks a lot!

GeoServer Vector Tiles show tile boundary issue in Mapbox GL JS

I use GeoServer to provide Vector Tiles (based on the GeoServer Vector Tile Extension) of my biking trails as .pbf.
The data are added as vector source and visualized using Mapbox GL JS.
Additionally, I use the GeoServer perpendicularOffset to offset the lines (as I always have two directions of the biking trail).
A problem occurs when visualizing the data within Mapbox. The lines are cut at the tile edges, although they are visualized correctly using the layer preview on GeoServer.
The further I zoom in the map, the less the clipping of the lines happens and at a very detailed zoom, the lines are drawn correctly.
I already tried to use a large enough buffer and modify the tile size, as these were suggestions when researching the problem. Unfortunately, these settings had no effect.
I have another vector source layer for the base map, there I have no problems.
It seems to me, that offsetting the lines might be a problem.
Any idea what I can try?
the tile size of Geoserver's tile grid is 256x256 , but mapbox need 512x512, add a custom tile grid, set the tile size to 512x512, generate your vector tile with the custom tile grid should be ok.

Prevent tiles outside of polygon from loading

Is there a way to prevent tiles from loading that are outside of a polygon? The closest example of this I found is here
http://jsfiddle.net/LsvDk/23/
var polygon = L.multiPolygon(
[
[
[
[51.509, -0.08],
[51.503, -0.08],
[51.503, -0.047],
[51.51, -0.047],
],
[
[84.774798, -176.835937],
[-85.221998, -175.078125],
[-85.103422, 176.484375],
[84.3916, 178.242188]
]
]
], {
color: '#DBDBDB',
weight: 1,
opacity: 1,
fillOpacity: 1
}).addTo(map);
It does what I want except it looks crappy when panning or zooming out because it loads tiles outside of the polygon.
If my understanding is correct, you do not like the example you mention because it uses a vector shape (polygon) to hide the tiles, but Leaflet has to re-render the shape when panning / zooming, which makes the background tiles temporarily appear?
EDIT:
Please have a try with TileLayer.BoundaryCanvas plugin. Instead of using a vector shape as mask, it combines tiles and its mask into a canvas. Hence the mask becomes a raster image, which avoids Leaflet behaviour of vector shape re-rendering at each pan / zoom, but instead keeps previous tiles (combined with mask in this case) until new ones are received.
Allows you to draw tile layers with arbitrary polygonal boundary. HTML5 Canvas is used for rendering.
The mask is specified as a GeoJSON shape, so it should be as easy to set up as in your example.
Remaining of original answer:
You would probably be interested in the bounds option of Tile Layer, to prevent any displaying of tiles outside a specified area.
When this option is set, the TileLayer only loads tiles that are in the given geographical bounds.
However, if your visible area does not perfectly fit with tiles boundaries, you would still have to use a mask to cover some areas, and you might still get the same issue with vector shapes being re-rendered.

mapbox - loading different geojson choropleth overlays at different zoom levels

so i have a mapbox base map and want to load a dynamic choropleth area map over the top of it. it will cover all continents. i've looked into doing this before using geojson but the resulting file was over 9mb. is there a way to have different geojson vectors loaded at different zoom levels as to reduce the file size ?
the reason the file was so big was because it was a very detailed vector overlay. basically i'd like to replicate the vectors of 'am map' but with the performance of mapbox, with much better vector resolution at bigger zoom levels. (http://www.amcharts.com/javascript-maps/)
the only other way to do this is by using geojson markers that are loaded on top of the base map, but this doesn't give the same visual impact of the fully coloured continent vectors..
any help would be greatly appreciated!
x
Well, you could watch zoomend on the map to add/remove overlays as needed.
map.on('zoomend', function() {
var currentZoom = map.getZoom();
overlayGroup.clearLayers() //remove existing
overlayGroup.addLayer(myZoomLevelMapping[currentZoom]) //add layer for this zoom level.
})

Mapbox.js - Fallback tile image from lower zoom level, when missing in requested zoom level

I serve map png files from disk and I have tile pngs for whole city in zoom level 15. I have also tiles in zoom levels 16-18 but only for certain areas.
I would like to set up the tile Layer, so that when the user is in zoom level 18 the map will display scaled tiles from level 15 as a fallback.
I tried setting option maxNativeZoom, but didn't work for me.
Here is my code:
offlineLayer = L.mapbox.tileLayer(tileJSON, {
minZoom: 8,
maxZoom: 18,
maxNativeZoom: 15
});
map.addLayer(offlineLayer, 'Offline', 1);
Can I make it work, that way using some options or do I need to hack it some way? Or is there some example code for that?
Just to let people know that I wrote Leaflet.TileLayer.Fallback plugin some time ago to address this exact use case:
Replaces missing Tiles (404 error) by scaled lower zoom Tiles.
Demo page
In OP's situation, you would just specify the maxZoom Tile Layer option as usual, and whenever a tile is found missing at the current zoom level, the plugin will try to replace it by the "parent" tile at the previous zoom level (scaled and clipped appropriately so that it fits the missing tile), and so on until a tile is found or minZoom is reached.
L.tileLayer.fallback(urlTemplate, {
minZoom: 8,
maxZoom: 18
});
Disclaimer: I am the author of that plugin.
When you say that it didn't work for you, I'm guessing that what you're seeing with the code above is level 15 tiles for everywhere even when at zoom levels 16-18 in the areas where you have tiles at those levels? That's the expected behavior of maxNativeZoom. TileLayer creates all of the tiles for a given zoom level and map bounds and sets the "src" to a URL containing the current zoom level. If the current zoom level is greater than "maxNativeZoom" then the zoom level in the URL is set to "maxNativeZoom". For example, src="http://a.tile.openstreetmap.org/15/16368/10896.png" would be used for zoom levels 16-18 if "maxNativeZoom" is set to 15.
There is no logic in the code that checks to see if an image actually exists for that tile at that zoom level.
If your tiles are in a single data set then you could modify the code in TileLayer to check for a HTTP 404 return code for the generated URL and if one is received then create a new URL using "maxNativeZoom". If your tiles are in multiple data sets (i.e. one for zoom level 15 and less, and another for zoom levels 16-18) then I think you'd have to write a TileLayer that supports multiple data sets.