Mapbox Changing Polygone Color based users area showed - mapbox

I'm currently building map using Mapbox GL. On this polygone there is polygone that are color based on 1 metric.
The metric range is between 1 to 25.
I have only 12 color panel.
ColorPannel
The goals would be to
Retrieve to top left, top right, bottom left and bottom right of the users map screen.
Get all the polygone that fit into the area. (SQL request)
From all those polygone, I retrieve the metric MIN and MAX.
Create 12 range of value based of MIN and MAX.
How could I reload the color for each polygone showed on the map based on the 12 range of value that I received from the back-end. This reload of color need to be executed when the users stop moving the area.
Here is my sample of the code :
map.addLayer({
'id': 'terrain1-data',
'type': 'fill',
'source': 'level_hight',
'source-layer': 'sold_level_high-36rykl', 'maxzoom': zoomThresholdZoneHtM, 'paint': {
'fill-color': [
'interpolate',
['linear'],
["to-number",['get', 'MYMETRIC']],
0,
'#FFFFFF',
5,
'#008855',
6,
'#13be00',
7,
'#75e100',
8,
'#aee500',
9,
'#dfff00',
10,
'#fff831',
11,
'#ffe82f',
12,
'#ffd500',
13,
'#ffa51f',
14,
'#ff7b16',
15,
'#ff0a02',
16,
'#c80000'
],
'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
0.8,
0.5
],
'fill-outline-color': '#000000',
}
});
Thanks in advance. Sorry I'm starting using Mapbox.

If my understanding is correct, you want to set the number dynamically in 'interpolate'. In the following case you want to change 0, 5, ... according to the data, light?
'fill-color': [
'interpolate',
['linear'],
["to-number",['get', 'MYMETRIC']],
0,
'#FFFFFF',
5,
Then, normally you will get the date from your server and there's a chance to calculate those numbers in JavaScript code. Then put the calculated number in 'interpolate' would work.
Here's a sample. The number is generated randomly,
map.on('load', function () {
map.addSource('maine', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[[0, 0], [0, 1], [1, 1], [1, 0]]
]
},
'properties': {
'height': 10
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[[1, 1], [1, 2], [2, 2], [2, 1]]
]
},
'properties': {
'height': 20
}
},
]
}
});
map.addLayer({
'id': 'maine',
'type': 'fill',
'source': 'maine',
'layout': {},
'paint': {
'fill-color': [
'interpolate',
['linear'],
['to-number', ['get', 'height']],
c(10),
'#000000',
c(10) + 10,
'#FFFFFF',
]
}
});
});
function c(n) {
return Math.round(Math.random() * n);
}

Related

Color of slope in Mapbox GL Js

Can I paint a gradient for the slope on a polyline (made from a track) in mapbox Js? I've seen the 'line-progress' property but that only takes into account the initial point and the last point.
this.map.addLayer({
'id': 'polilinea',
'type': 'line',
'source': 'route',
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': 'red',
'line-width': 14,
// I Want the equivalent of this, but for the slope or elevation
'line-gradient': [
'interpolate',
['linear'],
['line-progress'],
0,
'blue',
0.1,
'royalblue',
0.3,
'cyan',
0.5,
'lime',
0.7,
'yellow',
1,
'red'
]
},
});

Mapbox proportional symbol feature radius

I'm new to Mapbox GL JS and struggling with data-driven styling. I'd like to scale my circle features proportionally based on a value in my data source (a Google Sheet). Here's a code snippet:
map.addLayer({
id: 'csvData',
type: 'circle',
source: {
type: 'geojson',
data: data
},
paint: {
'circle-color': '#dd502c',
'circle-stroke-width': 1,
'circle-stroke-color': '#dd502c',
'circle-opacity': 0.5,
"circle-radius": {
property: 'value',
stops: [
[2, 5],
[1000, 10],
[8000, 20],
]
}
}
});
Many Thanks,
Looks like AverageNitrate (I assume this was the property you were trying to plot) was a string. Converting to int did the trick.
Also I referenced it in the styling expression instead of the generic 'value'
data.features.forEach((datum)=>{
datum.properties.AverageNitrate = parseInt(datum.properties.AverageNitrate)
})
//Add the the layer to the map
map.addLayer({
id: 'csvData',
type: 'circle',
source: {
type: 'geojson',
data: data
},
paint: {
'circle-color': '#dd502c',
'circle-stroke-width': 1,
'circle-stroke-color': '#dd502c',
'circle-opacity': 0.5,
"circle-radius": {
property: 'AverageNitrate',
stops: [
[2, 5],
[1000, 10],
[8000, 20],
]
}
}
});
Here is a link to the edited fiddle: https://jsfiddle.net/mojsc6pn/35/

Mapbox GL - Prevent Layer Label Fading Based on Zoom

Using Mapbox GL JS 1.12.0 with a GeoJSON source I'm adding circles that have a numeric label based on the "name" value in the GeoJSON.
map.addLayer({
'id': 'marker',
'type': 'circle',
'source': 'geojson',
'minzoom': 0,
'maxzoom': 24,
'paint': {
'circle-radius': 10,
'circle-color': '#FFFFFF',
'circle-stroke-color': '#000000',
'circle-stroke-width': 2,
'circle-opacity': 1,
},
'filter': ['==', '$type', 'Point']
});
map.addLayer({
'id': 'marker-label',
'type': 'symbol',
'source': 'geojson',
'minzoom': 0,
'maxzoom': 24,
'layout': {
'text-field': [ 'format', ['get', 'name'], { 'font-scale': 0.8, 'text-translate': [0,-20] } ],
},
'filter': ['==', '$type', 'Point']
});
When you're zoomed in they look correct:
As you zoom out the circles start to overlap, but still look correct:
But then the "2" fades out and the "1" shows through the circle for #2 (even though the circles have a white fill and an opacity of 1) and makes it unclear which is #1 and which is #2.
Is there a better way to do this? I wish you could just add a centered label to the circle itself.
Can I disable this automatic fading / transparency?
Can I somehow bind the label to that specific circle?
Can I disable this automatic fading / transparency?
You can use "text-allow-overlap": true to disable it. You may not like the result.
Can I somehow bind the label to that specific circle?
No.

How to draw multiple circles with different radius in MapBox GL JS?

I get some information from a AJAX and I create a GeoJson looking like
var waypointGeojson = {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'properties': {
'id': waypoint.poi_id,
'name': waypoint.name,
'iconSize': [100, 100]
},
'geometry': {
'type': 'Point',
'coordinates': [waypoint.longitude, waypoint.latitude],
}, {
'type': 'Feature',
'properties': {
'id': waypoint.poi_id,
'name': waypoint.name,
'iconSize': [25,25]
}, {
'geometry': {
'type': 'Point',
'coordinates': [waypoint.longitude, waypoint.latitude],
}, 'type': 'Feature',
'properties': {
'id': waypoint.poi_id,
'name': waypoint.name,
'iconSize': [35,35]
},
'geometry': {
'type': 'Point',
'coordinates': [waypoint.longitude, waypoint.latitude],
},
]
};
Then I add the source to the map like this :
map.addSource('waypoints', {
'type': 'geojson',
'data': waypointGeojson,
});
Then I loop around the Features to get the data and show the markers on my map.
waypointGeojson.features.forEach(function(marker) {
var radius = Number(marker.properties.iconSize[0]);
var latitude = Number(marker.geometry.coordinates[1]);
var el = document.createElement('div');
el.className = 'marker';
el.style.backgroundColor = 'rgba(230, 56, 18, 0.5)' ;
el.style.width = radius + 'px';
el.style.height = radius + 'px';
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);
}
At this step my map looks like :
Map at Zoom 15.32
However I want the Circle to be adjusted while I zoom in/zoom out.
For instance, if I zoom in :
Map at Zoom 17.32 The circle radius has not been adjusted (obviously!)
If you have any idea how I could do that with MapBox GL JS ?
I did try to use the formula (from here), with no success :
const metersToPixelsAtMaxZoom = (meters, latitude) =>
meters / 0.075 / Math.cos(latitude * Math.PI / 180)
If I use the method described here, then I put the
waypointGeojson.features.forEach(function(marker) {
var id = Number(marker.properties.id);
var radius = Number(marker.properties.iconSize[0]);
var latitude = Number(marker.geometry.coordinates[1])
map.addLayer({
"id": "circle"+id,
"type": "circle",
"source": "waypoints",
// "layout": {
// "visibility": "none"
// },
"paint": {
"circle-radius": {
stops: [
[0, 0],
[20, metersToPixelsAtMaxZoom(radius, latitude)]
],
base: 2
},
"circle-color": "red",
"circle-opacity": 0.4
}
});
});
I get 3 circles per point see here. This method is good because zoom in/out doesn't alter the size, but how to only have the corresponding circle on my point?

Showing Direction Arrow on Line in Mapboxgl

Trying to show a arrow as indication of direction in mapboxgl. The arrow is only visible at high zoom and is not visible at low zooms.
Adding a image Layer with 'symbol-placement': 'line'
Line Layer
map.addLayer({
'id': 'route',
'type': 'line',
'source': 'mapSource',
'filter': ['==', '$type', 'LineString'],
'layout': {
'line-join': 'round',
'line-cap': 'round'
},
'paint': {
'line-color': '#3cb2d0',
'line-width': {
'base': 1.5,
'stops': [[1, 0.5], [8, 3], [15, 6], [22, 8]]
}
}
});
Arrow Layer
const url = 'img/arrow.png'
map.loadImage(url, (err, image) => {
if (err) { return; }
map.addImage('arrow', image);
map.addLayer({
'id': 'arrowId',
'type': 'symbol',
'source': 'mapSource',
'layout': {
'symbol-placement': 'line',
'symbol-spacing': 1,
'icon-allow-overlap': true,
// 'icon-ignore-placement': true,
'icon-image': 'arrow',
'icon-size': 0.045,
'visibility': 'visible'
}
});
});
No Arrow at low zoom
Arrow showing at high zoom
I have tried experimenting with symbol-spacing, but it didn't work.
Is there way to force mapbox to show arrow on low zoom?
jsfiddle.net/4jjmh2nb