Mapbox-gl-js: How to implement markers that can be scaled and recoloured?

Created on 6 Oct 2015  路  8Comments  路  Source: mapbox/mapbox-gl-js

I need to implement dynamic markers that can be scaled and re-coloured.

From this issue, I can see that SDF icons is a neat way to go about. But I am not sure how I can generate an SDF image? Do you use any tool for this? And I see that there is no SDF usage in V8 and it has been replaced with SVG.

SVG would be a better solution, but again from this issue that I raised earlier, it looks like SVG's are converted to png + JSON sprites, and therefore I cannot scale or re-colour it.

And I also think that there should be an example for this.

Most helpful comment

icon-color is also not working, this code taken from https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/ wont change the marker color to red

    map.addLayer({
        "id": "markers",
        "type": "symbol",
        "source": "markers",
        "layout": {
            "icon-image": "{marker-symbol}-15",
            "text-field": "{title}",
            "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
            "text-offset": [0, 0.6],
            "text-anchor": "top"
        },
        "paint": {
            "text-size": 12,
            "icon-color" : "#ff0000"
        }
    });

All 8 comments

@mourner Any thoughts on my above query?

I am also interested in doing this. I find it strange that Mapbox GL JS is all about vector graphics but doesn't seem to have an easy way of customizing vector icons. It would be great to be able to use Mapbox GL JS instead of d3.js for mapping dynamic data.

icon-color is also not working, this code taken from https://www.mapbox.com/mapbox-gl-js/example/geojson-markers/ wont change the marker color to red

    map.addLayer({
        "id": "markers",
        "type": "symbol",
        "source": "markers",
        "layout": {
            "icon-image": "{marker-symbol}-15",
            "text-field": "{title}",
            "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
            "text-offset": [0, 0.6],
            "text-anchor": "top"
        },
        "paint": {
            "text-size": 12,
            "icon-color" : "#ff0000"
        }
    });

@jordi-adame The documentation for icon-color states that it can only be used for sdf icons.

Unfortunately we don't have a turnkey solution for generating sdf icons but you can see an example of how its done in the maki project https://github.com/mapbox/maki/blob/mb-pages/sdf-render.js

A poor man's attempt:

I tried to use the cli tools of imagemagick to create SDF images - and it works _kind of_ (it is far from perfect, but at least it is simple):

As my test input I downloaded this maki icon: bicycle-15.svg

  • Step1: create a bigger raster version with some padding:
    convert.exe -size 150x150 -gravity center -extent 150% bicycle-15.svg -fill black temp.png
  • Step2: create a SDF (or something similar ?):
    convert.exe temp.png ( +clone -negate -morphology Distance Euclidean -level 60%,-50% ) -morphology Distance Euclidean -compose Plus -composite -auto-level -level 0%,30% -alpha copy -channel A -negate +channel -filter Jinc -resize 20% sprite.png

_I麓m on Windows; on Linux you need no .exe but you have to escape the brackets:
convert tmp.png ... \( +clone ... \) ... sprite.png
_

together with a sprite.json:

{"icon": {"width": 38, "height": 38,"x": 0,"y": 0,"pixelRatio": 1, "sdf": true }}

this makes a single icon.

As said, this is just a quick-and-dirty solution with a lot of manual work ( e.g. the values in the IM commands could be tweaked) and I麓m not sure somebody is interested.
(This is based on: https://habrahabr.ru/post/215905/ so thanks to 袩邪胁械谢 and Google Translator ;-)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Scarysize picture Scarysize  路  3Comments

aaronlidman picture aaronlidman  路  3Comments

iamdenny picture iamdenny  路  3Comments

yoursweater picture yoursweater  路  3Comments

BernhardRode picture BernhardRode  路  3Comments