Add icon halo as border around image uploaded as a Mapbox icon - mapbox

I have a mapbox map with custom coffee mug icons (not maki icons). I want to give the icons a halo conditionally based on a data field of each point. This works, but since the icon is uploaded as a png, it gets treated as a rectangle, even though the image is of a coffee mug which is mostly round. So when you add a halo, it gets added around the perimeter of the bounding rectangle of the icon. Here's a picture of two of these icons, one that has a halo because it meets the "CONDITION" and one that doesn't.
How can I make this halo wrap around the border of the coffee mug icons, like it does for maki icons? Here is the relevant part of my style definition:
layout: {
'icon-image': 'cafe-icon'
},
paint: {
"icon-color": "#1a7a08",
"icon-halo-color": "#e4be8b",
"icon-halo-width": ['case', ['==', ['get', 'CONDITION'], true], 4, 0]
}
Also, here are the mapbox dependencies in my package.json file:
"#mapbox/mapbox-sdk": "^0.12.1",
"mapbox-gl": "^2.1.1",
"#mapbox/mapbox-gl-geocoder": "^4.7.0"
And here is the coffee mug icon I'm using for now:

According to Mapbox-gl-js documentation couple of style properties can only be applied to SDF Enabled Images and one of them is "icon-halo-width" also.
READ HERE
Which says:
Four style specification properties can only be used with SDF-enabled images: icon-color, icon-halo-color, icon-halo-width, and icon-halo-blur.
I downloaded a demo png of "shop-15.png" from this link and applied the icon-halo-width to 10 and style get applied.
Code:
//downloaded
var accessible = "http://localhost:3000/shop-15.png";
map.loadImage(accessible, function (error, image) {
if (error) throw error;
map.addImage('accessible', image, { sdf: true });
map.addLayer({
"id": "iconLayer",
"type": "symbol",
"source": 'maine',
"layout": {
'icon-allow-overlap': true,
"icon-image": "accessible",
"icon-size": 3,
},
"paint": {
"icon-color": "white",
"icon-halo-color": "red",
"icon-halo-width": 10
}
});
});
Screenshot:
How To Create SDF Images?
HERE is the link where I combined few of my research.
Thanks!

Related

Mapbox Studio: How can I use hoover effect on layer added in Mapbox Studio style?

I want to make hoover effect on my map created in Mapbox Studio. I've added a SHP feature as a fill with initial opacity set in "style editor" to 0.5. How can I make hoover effect that will change that opacity to 1 when mouseon?
I've been using this example (https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/) but data in this example is coming from external GEOJOSN. I want to use my layer already styled in Mapbox Studio. Is it possible? Thank you
Yes, this is possible to achieve by referencing the name of the source which you have already added in Mapbox Studio, rather that using Map#addSource and Map#addLayer as shown in the example. That is, you can replace 'states' in the example with the name of your source added to your map style with Mapbox Studio.
Thank you for reply. Where do I add in that case command line defining "true" and "false" values for "fill-opacity" when hover event appears?
If I don't use Map#addSource and Map#addLayer, there is no line to put new opacity values. I am really new at this so pleas understand me.
map.addLayer({
'id': 'state-fills',
'type': 'fill',
'source': 'states',
'layout': {},
'paint': {
'fill-color': '#627BC1',
**'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
0.5**
]
}
});
and then, that case is recalled in map.on mousemove event:
map.on('mousemove', 'state-fills', function(e) {
if (e.features.length > 0) {
if (hoveredStateId) {
map.setFeatureState(
{ source: 'states', id: hoveredStateId },
**{ hover: false }**
);
If I just replace layer "states" for my layer, lets call it "PollyGon", I can't see there to define opacity values? Thank you!

querySourceFeature returns empty array

I am using mapbox to try and query all features of the mapbox tileset and return them as geojson. From what I understand, to query features that are no visible on the screen, you must use querysourcefeatures. My tileset only shows up at zoom 14 so I am having trouble querying all the features in the dataset at once and then applying a filter. Is this possible? It stills like querySourceFeatures returns an empty array.
function addLayers() {
map.addSource('plutonew-c03oxi', {
'type': 'vector',
'url': 'mapbox://samtpr.4ehwzn0r'
});
map.addLayer({
"id": "parcels_fill",
"type": "fill",
"source": "plutonew-c03oxi",
"source-layer": "plutonew-c03oxi",
'layout': {
'visibility': 'visible'
},
paint: {
'fill-color': 'blue',
'fill-outline-color': 'gray',
"fill-opacity": ["case",
["boolean", ["feature-state", "hover"], false],
0.5,
0
]
}
});
var features = map.querySourceFeatures('plutonew-c03oxi', {filter: ["==", ['get','ZIPCODE'], zipcode_val]});
From what I understand, to query features that are no visible on the screen, you must use querysourcefeatures
You may have misunderstood. querySourceFeatures allows you to query features that are present within the vector tiles currently loaded and displayable within the current viewport and zoom level. Unlike queryRenderedFeatures they don't have to actually be rendered through a visible layer, however.
In this case it sounds like you're hoping to gain access to features that are not available at the current zoom level, which is not possible.

GeoJson styling Asymmetrik/ngx-leaflet

Hi I have a problem with Asymmetrik/ngx-leaflet geojson interpretation.
My geojson is automatically generated with color and opacity corresponding to the map information. Each geojson is a FeatureCollection with multiple Polygons differently styled.
I've tried different options, I've found to set style of the Polygons, but non of them seems to work.
Example geoJson:
{
"type":"FeatureCollection",
"features":[
{
"geometry":{
"type":"Polygon",
"coordinates":[
[...]
]
},
"type":"Feature",
"properties":{
"style":{
"color":"#ff0000",
"weight":0,
"opacity":0.2
}
}
}, ... ]}
I've been trying multiple options that seems to work for people. Also there is nothing on styling inside geojson in the ngx-leaflet docs.
How should I set the styling above to make ngx-leaflet display proper color, stroke and opacity?
ngx-leaflet doesn't do anything to manipulate the layers you add to the map. So, it's up to you to provide the style options when you create the features.
E.g.,
let geoJson = {...};
let options = { "color": "#ff7800", "weight": 5, "opacity": 0.65 };
L.geoJSON(geoJson, options).addTo(map);
This example was taken from here: http://leafletjs.com/examples/geojson/

How to change a marker base in mapbox gl?

When I add a marker to my mapbox gl script, it's positionned in a way that its center indicates the location, not the base. As a consquence, the marker seems to indicate an incorrect location.
Please see the screenshot
Is there a way to change the part of the image that is used as the base for the coordinates?
Thanks in advance!
Oktawia
Use the icon-offset layout property to offset the icon from your coordinates
map.addLayer({
"id": "pointclick",
type: 'symbol',
source: 'pointclick',
"layout": {
"icon-image": "{marker-symbol}",
"icon-size":1,
"icon-offset": [0, -13]
},
"paint": {}
});

Adding custom markers to the mapbox gl

I would like to add a custom marker to my map. I am using a mapbox gl script.
The only documentation that I found related to this topic is this one https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/.
I tried to customize given example and I managed to add a marker and modify it a little changing the size, but since I don't understand all the parameters, I don't know how to add my own marker. Is there any documentation that is more detailed?
Here is my code:
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiYWl3YXRrbyIsImEiOiJjaXBncnI5ejgwMDE0dmJucTA5aDRrb2wzIn0.B2zm8WB9M_qiS1tNESWslg';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/aiwatko/cipo0wkip002ddfm1tp395va4', //stylesheet location
center: [7.449932,46.948856], // starting position
zoom: 14.3, // starting zoom
interactive: true
});
map.on('load', function () {
map.addSource("markers", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [7.4368330, 46.9516040]
},
"properties": {
"title": "Duotones",
"marker-symbol": "marker",
}
}]
}
});
map.addLayer({
"id": "markers",
"type": "symbol",
"source": "markers",
"layout": {
"icon-image": "{marker-symbol}-15",
"icon-size": 3
}
});
});
</script>
Thanks in advance!
Oktawia
There are two ways to customize markers in Mapbox.
Raster Markers in Mapbox
See this link on Mapbox.com for Custom marker icons. That example shows how to use a .png as a marker.
SVG Markers in Mapbox
You are pretty close to modifying the icons, but take some time to familiarize yourself with the parameters.
The icon-image may be the harder one to understand. It takes the property "marker-symbol": "marker" from the GeoJson, and "icon-image": "{marker-symbol}-15", to create the final result of marker-15.
This brings up a further question: where/how are the markers defined?!?
The markers also come from Mapbox and are called Maki Icons. You can change the "marker-symbol" to aquarium or cafe to see the results.
From the Mapbox GL Style Reference
icon-size — Scale factor for icon. 1 is original size, 3 triples the size.
icon-image — A string with {tokens} replaced, referencing the data property to pull from.