Showing Direction Arrow on Line in Mapboxgl - leaflet

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

Related

Is there a way that I can connect a polygon format (JS) to a map (HTML)

I'm trying to put a polygon format from Mapbox into the Mapbox map itself (via a Github copy for a project), and I haven't yielded any results.
I did the formatting, using different files, combining them into 1 via a combiner, etc.
Polygon (JS):
map.on('load', () => {
// Add a data source containing GeoJSON data.
map.addSource('maine', {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
// These coordinates outline Maine.
'coordinates': [
[
[-125.15625000000001, 48.04870994288686],
[-124.71679687499999, 43.32517767999296],
[-125.15625000000001, 39.639537564366684],
[-121.11328124999999, 34.59704151614417],
[-121.11328124999999, 34.59704151614417],
[-117.158203125, 32.47269502206151],
[-105.732421875, 31.27855085894653],
[-97.20703125, 25.64152637306577],
[-84.287109375, 29.84064389983441],
[-80.947265625, 24.84656534821976],
[-74.970703125, 35.38904996691167],
[-66.62109375, 45.02695045318546],
[-68.73046875, 47.39834920035926],
[-71.455078125, 44.84029065139799],
[-82.880859375, 41.96765920367816],
[-88.154296875, 48.22467264956519],
[-109.072265625, 49.03786794532644],
[-123.134765625, 49.15296965617042],
[-125.15625000000001, 48.04870994288686],
]
]
}
}
});
// Add a new layer to visualize the polygon.
map.addLayer({
'id': ' ',
'type': 'fill',
'source': 'maine', // reference the data source
'layout': {},
'paint': {
'fill-color': '#0080ff', // blue color fill
'fill-opacity': 0.2
}
});
// Add a black outline around the polygon.
map.addLayer({
'id': 'outline',
'type': 'line',
'source': 'maine',
'layout': {},
'paint': {
'line-color': '#000',
'line-width': 0
}
});
});
Said remaining copies of code are located in https://github.com/AliCodes-Beep/Google-Map-Clone

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'
]
},
});

Error mapbox layer only show the last conditional result

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

Mapbox Changing Polygone Color based users area showed

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);
}

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.