Mapbox raster Image quality changes with zoom level - mapbox

I have a floorplan image added on top of Mapbox as a Raster, everything works as expected except as I zoom out the image gets blurrier and its features are unrecognizable. please see below what I mean.
Zoom = 20
Zoom = 19
Zoom = 18
Is this something I can change, or is it how Mapbox handles the raster display?
Here is my code
map.on('load', () => {
map.addSource('radar', {
'type': 'image',
'url': 'URL_TO_IMAGE',
'coordinates': [...]
});
map.addLayer({
id: 'radar-layer',
'type': 'raster',
'source': 'radar',
'paint': {
'raster-fade-duration': 0
}
});
});

Because of the way this is rendered as an overlay image, there is no way to really fix this.
My answer is to actually just convert the image to a GeoTIF and use the utility gdal2tiles to convert the image to a tileset. For each zoom level, the tiles are rendered differently and the image will always be as intended. It is not trivial if you have never worked with GeoTIFs or gdal before, but with effort you can get it to look perfectly as desired.

Related

How I can I get geojson boundary array from existing layer using mapbox gl?

I am using one of the custom tileset of tilling service in mapbox. I loaded that custom tile layer in map using below code.
map.addSource('california', {
type: 'vector',
url: 'mapbox://xyz.california'
});
map.addLayer({
'id': 'terrain-data',
'type': 'fill',
'source': 'california',
'source-layer': 'california',
'layout': {},
'paint': {
'fill-color': 'black',
'fill-opacity': 0.5
}
});
Above code is filling out the inner area with black color. But I want to fill out the outer area of that polygon. Only one way I know to do that is getting difference of whole map with that polygon by using turf.js. After that I will be able to fill the outside area.
Now the question is how can I get the geojson ploygon array of above added layer? So I can calculate the difference.
You can't easily get the complete geometry of a polygon from a vector tile set, because it has already been cut up into tiles. You would have to either find a way to merge them together, or get your geometry into the front end as a complete geojson first.

Mapbox gl - Custom filter and render of PBF tiles

map.addSource('testLayer', {
'type': 'vector',
'source-layer': 'testLayer',
'tiles': [
'http://localhost:3004/{z}/{x}/{y}.pbf'
],
'minzoom': 0,
'maxzoom': 24,
});
map.addLayer({
'id': 'urban-areas-fill',
'source': 'testLayer',
// Custom styling based on filtering. Help needed here
});
Above pbf tile contains point data, along with height attribute. I want to collect height attribute of all the points within each tile, take an average of it per tile, use it for each individual point's height value (respective to that tile) to perform certain filtering (if else) and assign colours accordingly to display. Also, I want to convert the final rendering of each point as pixel (ie rectangle), and not as a circle. Thanks :)

Check if a GeoJSON source is present in mapbox viewport

I have a map with several layers of GeoJSON each with their own unique layer name:
var map = new mapboxgl.Map({
container: 'map',
center: [-97.5651505, 37.89549,],
zoom: 4
});
var sources = {
'ord': 'chicago',
'pit': 'pittsburgh',
'atl': 'atlanta'
};
map.on('load', function () {
for (var s in sources) {
map.addSource(s, { type: 'geojson', data: `/geojson/${s}.json` });
map.addLayer({
'id': sources[s],
'type': 'fill',
'source': s,
'layout': {
'visibility': 'visible'
},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.5
}
});
}
});
I would like to check if a user has zoomed in past zoom level 13 evaluate if any of these three layers is in the viewport. If it is I'll take action to add a button to the overlay. However, I'm having issues finding any documentation other than leaflet on how to check if a layer is inside the viewport. I've found some mention of markers that that doesn't seem to apply.
You can achieve this with queryRenderedFeatures which returns an array of features rendered within a given bounding box. However, if you omit the bounding box argument, queryRenderedFeatures will query within the entire viewport. You can also use the options.layers argument to limit your query to specific layers to avoid getting a bunch of features that are in the underlying style (for example, streets and lakes). You can do this query in a zoomend event listener to achieve your desired outcome. Putting it all together would look something like this:
map.on('zoomend', () => {
if (map.getZoom() > 13) {
const visibleFeatures = map.queryRenderedFeatures(null, {layers: ['ord', 'pit', 'atl']});
// if none of the layers are visible, visibleFeatures will be an empty array
if (visibleFeatures.length) {
// figure out which layers are showing and add your button
}
}
});

Mapbox-gl fill layer distorts rendering on higher zoom

I'm using mapbox-gl version 0.46.0-beta.1 (With ReactJS).
I've drawn simple fill layers using GeoJSON source.
The coordinates used to draw the fill are
Coordinates Data:
At a specific zoom level, the polygon renders as expected.
Expected Layer:
But on zooming in, the polygon distorts.
Distorted Fill Layer:
The code I'm using is:
`let paint = {
'fill-color': 'Some Color',
'fill-opacity': 0.4,
'fill-outline-color': 'Some Color'
}
let uniqueID = 'someuniqueID';
map.addLayer({
'id': uniqueID,
'type': 'fill',
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [polyCoords]
}
}
},
'paint': paint
})`
We were able to solve the same problem by making sure the first point in the polygon is also the last. For this polygon, you should add the point:
[28.6045067810482..., 77.3860210554725...]
I also had this issue. For a bounding box of coordinates for mapbox, having just the 4 coordinate pairs to create the polygon does create rendering artifacts, directly like above. When making your coordinate bounding box as a polygon, be sure to enter a 5th record, which would be the same as your coordinate at coor[0], where coor is your array of coordinate pairs. You will only notice the weird rendering and re-drawing when zooming, this in fact made it go away for me.
For example:
var coors = [[+sw_lng, +sw_lat], [+sw_lng, +ne_lat], [+ne_lng, +ne_lat], [+ne_lng, +sw_lat]]; //makes a 4 pointed polygon
coors.push(coors[0]); //then continue

Mapbox GL JS: Display map labels above layer?

I'm using Mapbox GL JS, with a Mapbox Streets base layer. I have added a polygon layer with white borders and a transparent fill, but I'm finding it hard to read the basemap labels underneath the polygon layer. See how the labels are covered by the white borders:
Is there any way I can make sure the labels are on top of the polygon layer, or at least not obscured by it?
My code looks like this:
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-2.839, 54.579],
zoom: 4
});
map.on('load', function () {
map.addSource('constituencies', {
'type': 'vector',
'url': 'mapbox://pcsu.xxx'
});
var constituencyLayer = map.addLayer({
'id': 'constituencies',
'source': 'constituencies',
'source-layer': 'constituencies',
'type': 'fill',
'paint': {
'fill-color': 'rgba(162,181,205,0.6)',
'fill-outline-color': 'white'
},
'layout': {
'visibility': 'visible'
}
});
Have a look at this Mapbox example and use the second argument of map.addLayer(layer, [before]). If this layer before exists, the new layer will be placed before/below it. I think the argument naming is a bit confusing here.
The name of the lowest label layer depends on the style. Most of the time you're looking for housenum-label. There's also a discussion in the Mapbox github issues how to ease this process, e.g by introducing placeholder layers.