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'
]
},
});
Related
when i tried to add 2 layer like below, for ex:
data[banana,chicken,banana,chicken,chicken]
for(let indexin data){
if(data[index]=="banana"){
map.addLayer({
'id': 'router' + index,
'type': 'line',
'source': 'LineString' + index,
'layout': {
'line-join': 'round',
'line-cap': 'round',
},
'paint': {
'line-color': '#00FF00',
'line-width': 4,
'line-dasharray': [2, 4]
}
});
} else{
map.addLayer({
'id': 'router' + index,
'type': 'line',
'source': 'LineString' + index,
'layout': {
'line-join': 'round',
'line-cap': 'round',
},
'paint': {
'line-color': '#00FF00',
'line-width': 4
}
});
}
}
this approach only show the last conditional result. so if the last loop is chicken , the map will only shown the else layer. Is there a way to fix this? Bcs i want to differentiate it by type from array data
Thank you
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/
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);
}
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.
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