Display mountain names at lower zoom level - mapbox

How can I display layers that by default seem hidden to show at lower zoom levels? For example, I am trying to display mountain names ("poi-parks-scalerank1") at zoom level lower than 10. Is that possible?

It is not possible to show vector tile data at zoom levels lower than the tiles in which it is physically present. For instance, if the mountain names only exist at zoom 10 and above (that is, any vector tiles at /9/x/y.pbf don't have them), there's nothing you can do to force Mapbox-GL-JS to render them.
(The reverse is not true: you can "overzoom" vector tiles by setting maxzoom on the layer.)
It's possible (but very unlikely - Mapbox's tiles are pretty optimised) that the data exists in a lower level than the style actually calls for, so you might as well have a go, as leelum1 suggests.
Otherwise, you will have to obtain the mountain name information somehow and create your own layer, then style it.

Related

How do you get all features within a bounding box regardless of zoom?

Given a bound box like the below picture, how do you get all the features contained within, regardless of if they are visible or not.
I have tried to get all roads using
let features = map.querySourceFeatures('composite', {sourceLayer: 'road'})
But it only gives me roads that are visible if I am zoomed in.
I have also tried
let features = map.queryRenderedFeatures([tile_info.swPt, tile_info.nePt])
But again, it only gets features visible on the map based on zoom level.
I need all the features within the bounding box regardless of what you can see or zoom level
It is in the nature of vector tiles that you can not do what you want to do here. You can only query data which has been loaded into the browser, and the point of the vector tile architecture is to prevent that happening at lower zooms.
You could consider a server based approach like Tilequery.

how to avoid polygon being clipped with tileset?

I am generating a layer UK scale, it is composed for several polygons, the idea for the layer is to display it fully and then the user can zoom to most specific area. The main problem is because the number of polygons when I create the .mbtile it split some of the polygon at determined zooms.
I have tried with different options of tippecanoe like --not duplication extend zooms if still dropping ... but I couldn't nail whit the correct commands to make it work.
tippecanoe -zg --read-parallel -l $LAYER -o "$OUT_MBTILES" "$OUT_JSON" --coalesce-densest-as-needed --extend-zooms-if-still-dropping --no-duplication
I suspect this is somehow related to --no-duplication. Per the documentation:
--no-duplication: As with --no-clipping, each feature is included intact instead of cut to tile boundaries. In addition, it is included only in a single tile per zoom level rather than potentially in multiple copies. Clients of the tileset must check adjacent tiles (possibly some distance away) to ensure they have all features.
I'm not sure why you're using that option, but disable it if possible.
It's hard to be more specific without seeing your data and having a lot more information about what you're trying to achieve, zoom levels, attributes, data size etc.

Displayed zoom level vs tile zoom level: pixel density?

Tiles come with a zoom level, and depending on the area that is viewed, leaflet fills the display with tiles of a certain zoom level.
Currently, the number of pixels in the display and the number of pixels in a tile, are tightly bound together, if I understand correctly. Or actually, it is probably the html/css pixels, which are no longer device pixels.
I believe that these are actually two fundamentally different zoom parameters, especially when (mobile) devices have varying pixel densities (window.devicePixelRatio).
My question is: is it possible to control which zoom level of the tiles is shown, as a function of the zoom level that is displayed (geospatial distance vs screen distance)?
The reason I ask is that the level of detail is often different for different zoom levels. On some devices displaying tiles of higher detail might actually look good. Some map sources, like topographic maps from http://geoportail.gouv.fr even change the map style drastically between different levels. I want to play with the possibility of showing, say, zoom level 15 over a large physical area on a hdpi display, where leaflet would normally show zoom level 14 or 13.
I found that by modifying the option "tileSize", passed to the TileLayer constructor, choosing a value lower than the default 256, I get almost what I want. However: the positioning is way off. Is there a simple solution for this?
After some digging in the source code, I noticed, as IvanSanchez pointed out, that the functionality is present indeed.
detectRetina applies a zoom of 'one up', that is bumping the zoom by one and dividing the length of the sides of the tiles by two, if the device has a devicePixelRatio >= 2.
I want to apply an arbitrary offset at will. This can be done at once for a layer by initializing with the options
let zoomOffset = 2;
let options = {
"detectRetina" : false,
"zoomOffset" : zoomOffset,
"tileSize" : 256 / Math.pow(2, zoomOffset)
}
However, it's even neater to have the possibility to do this realtime while viewing, so I wrote this L.Control-plugin: Leaflet.Control.DetailLevel
I want to play with the possibility of showing, say, zoom level 15 over a large physical area on a hdpi display, where leaflet would normally show zoom level 14 or 13.
It seems that what you want is already implemented by the detectRetina option of L.TileLayers. Quoting the docs::
If true and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.

Mapbox not able to change the style of vector tiles at run time

I am using tippecanoe command line utility to create my application vector tileset. This is creating a directory structure as per the z/x/y coordinates which is perfectly fine. I have a certain group of features(allocated with a layer) which do not need z to be up to 21 zoom level so it's creating the tiles up to zoom-level 14. It is critical in my case to not to waste the memory space by increasing the max-zoom to 21 for certain layer of features.
As per my understanding, mapbox gl-js queries for the vector tiles as per its coordinate space.
So during my zoom-in from 6 to 21, although zoom-level > 14 tile queries are responding with 404, gl-js is adopting the same tile which is available at 14.
The problem is,
For example, If I click on any feature, I need that feature to be highlighted. I am doing it by filtering out the layers as :
//hiding the current layer
mapBox.setFilter(currentLayer, ["==",'gid', "_none_"]);
//showing only the clicked feature by filtering it out with a unique id it has
mapBox.setFilter(highlightedLayer, ["==",'gid', feature_gid]);
This works as expected for zoom-level < 14 but if zoom-level exceeds 14 (the max-zoom while tile creation) then it is not able to render the tile with applied layer style as it tries to fetch a tile which is not there on my server. So my question is if a source tile at particular zoom level is giving 404 then why not apply the layer style to whichever tile is available at zoom level 14 ?
Any help to solve this problem?
This functionality is not supported by mapbox-gl. You need to go back to Tippecanoe and generate the tiles for this zoom level.
Note that you those new tiles can be similar in terms of data as the other zoom levels.
Remember that tiles are like images generated at a precise zoom level. If you zoom in, one tile will be divided in many tiles.

Specifying Lat & Long for Leaflet TileLayer

Seems like a simple question, but I have been tearing my hair out for hours now.
I have a series of files ie.
kml_image_L1_0_0.jpg
kml_image_L2_0_0.jpg
kml_image_L2_0_1.jpg
kml_image_L2_1_0.jpg
kml_image_L2_1_1.jpg
etc. However just plotting them on the leaflet map surface understandibly puts the images at 0,0 on the earths surface, and the 0 zoom level inferred by the files should really be about 15 or so.
So I want to specify the latitude and longitude where the images should originate , and what zoom level they should start at. I have tried bounds (which doesn't display anything) and I have tried playing with offsetting the zoom level.
I need this because a user needs to click on an offline map to specify where they are and I need the GPS coordinates.
I also have a KML file but it seems to be of more help for plotting vector data on the map.
Any help is much appreciated, cheers.
If I understand correctly, the "kml_image_Lz_x_y.jpg" images that you have are actually tiles, with zoom, horizontal and vertical indices in their file name?
And your issue is that they use (z,x,y) numbers as if they started from the top-most level (zoom 0, single tile for entire world), but in fact they are just a small portion of the pyramid of tiles?
And you cannot use them as is because you still want to get actual geographic coordinates (latitude, longitude), which would be totally wrong if you used the tiles as if they were showing the entire world?
In that case, you have several options as workarounds:
The most simple and reliable would probably be to simply write a small script to rename all your tiles to their true (z,x,y) numbers.
Another option would be to modify the (z,x,y) numbers before they are written in the tile src attribute, and apply the appropriate offset (constant for z, scaled by z for x and y). That should probably happen in L.TileLayer.getTileUrl() method.
Good luck! :-)