Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

It's possible to style drawn polygons and polylines? #833

Closed
CarbonHeartDev opened this issue Nov 8, 2018 · 15 comments
Closed

It's possible to style drawn polygons and polylines? #833

CarbonHeartDev opened this issue Nov 8, 2018 · 15 comments
Labels
question rendering Rendering issues and errors

Comments

@CarbonHeartDev
Copy link

I'm developing an application where I need to draw polygons/polylines on a Mapbox map and then style them programmatically changing their color/line width. I can easily draw using this library but I have no clue on how to style drawn objects (I need to give to each object its individual style, not to give the same style to every object generated by the Mapbox GL Draw instance), what's the best way to do it?

@mcwhittemore
Copy link
Contributor

@EmiSan1998

Draw provides some default styles that are defined here. This JSON is the layer section of the Mapbox Style Spec without the source attributes as Draw moves features between two sources for performance reasons. The names of those sources are mapbox-gl-draw-hot and mapbox-gl-draw-cold.

To create a custom style for Draw you can either set the styles option when setting up Draw and follow these directions for styling. As you want custom per feature styles you'll want to set userProperties to true and make sure your styles prefix your feature property fields with user_ as covered in the styling directions.

Another option is to use mapbox-gl-js's addLayer function.

The Draw option will be a bit harder if you don't know the number of unique layers you will need and the mapbox-gl-js addLayer option will be a bit harder as you MUST add each layer twice. Once for mapbox-gl-draw-hot and once for mapbox-gl-draw-cold.

@vivienred
Copy link

I also need the same effect

@mcwhittemore
Copy link
Contributor

If this is something more people want, I could see a "styleFeature" function being added to Draw that would allow a user to set a features style. Internally this would add a style layer to the mapbox-gl-js that references that id of the feature.

draw.styleFeature('id', { style json })

The style json would be a paired down version of what is in the default styles, noting that filter, id and source would all need to be left off so that Draw could set them.

draw.styleFeature('id', null)

Would remove the style from the map as would draw.deleteFeature('id').

Thoughts?

@CarbonHeartDev
Copy link
Author

Sorry for the late answer but I was very busy with more urgent features of my application. I'd love a styleFeature method and I hope to see it in future Mapbox versions. Keep me updated!

@rob137
Copy link

rob137 commented Feb 12, 2019

I would also love to see this.

@CarbonHeartDev
Copy link
Author

There is any hope to have this feature?

@sameerabit
Copy link

sameerabit commented Apr 17, 2019

Hope this will be helpful.
https://bl.ocks.org/dnseminara/0790e53cef9867e848e716937727ab18

@rob137
Copy link

rob137 commented Apr 17, 2019

@sameerabit Yep I found it the other day - it was really helpful, thanks!

@CarbonHeartDev
Copy link
Author

Hope this will be helpful.
https://bl.ocks.org/dnseminara/0790e53cef9867e848e716937727ab18

Thank you, with proper modification for my particular application it did the trick for me!

@kkaefer kkaefer added feature rendering Rendering issues and errors labels Jan 7, 2020
@Khyzar
Copy link

Khyzar commented Mar 2, 2020

If this is something more people want, I could see a "styleFeature" function being added to Draw that would allow a user to set a features style. Internally this would add a style layer to the mapbox-gl-js that references that id of the feature.

draw.styleFeature('id', { style json })

The style json would be a paired down version of what is in the default styles, noting that filter, id and source would all need to be left off so that Draw could set them.

draw.styleFeature('id', null)

Would remove the style from the map as would draw.deleteFeature('id').

Thoughts?

Hi,
Is this feature implemented yet?

@skydiablo
Copy link

hi, i also hit this problem. i just want to add an custom style but do not want to replace the default styles. this is my current work-around:

let drawDummy = new MapboxDraw();
let draw = new MapboxDraw({
    displayControlsDefault: false,
    controls: {
        polygon: true,
        trash: true
    },
    userProperties: true,
    styles: drawDummy.options.styles.concat({
        'id': 'gl-draw-polygon-color-picker',
        'type': 'fill',
        'filter': ['all',
            ['==', '$type', 'Polygon'],
            ['has', 'user_portColor'],
        ],
        'paint': {
            'fill-color': ['get', 'user_portColor'],
            'fill-outline-color': ['get', 'user_portColor'],
            'fill-opacity': 0.5
        }
    })
});

but it floods the console for every default style with messages like this:

Error: Layer with id "gl-draw-point-static.hot" already exists on this map

how can we handle this feature request?

regards, volker.

@Khyzar
Copy link

Khyzar commented Sep 1, 2021

@skydiablo you can set the default styles like this while initializing mapboxDraw
this.geofenceDrawer = new MapboxDraw({
userProperties: true,
styles: styles('#000'),
displayControlsDefault: false,
controls: {
trash: false
},
modes: {
...MapboxDraw.modes,
draw_circle: CircleMode,
drag_circle: DragCircleMode,
direct_select: CustomDirectMode,
simple_select: SimpleSelectMode,
static: StaticMode,
DrageMode: customDragMode
}
});

export const styles = (portColor) => {
return [
{
id: 'gl-draw-polygon-fill-inactive',
type: 'fill',
filter: ['all', ['==', 'active', 'false'],
['==', '$type', 'Polygon'],
['!=', 'mode', 'static']
],
paint: {
'fill-color': '#3bb2d0',
'fill-outline-color': '#3bb2d0',
'fill-opacity': 0.1
}
},
{
id: 'gl-draw-polygon-fill-active',
type: 'fill',
filter: ['all', ['==', 'active', 'true'],
['==', '$type', 'Polygon']
],
paint: {
'fill-color': portColor,
'fill-outline-color': portColor,
'fill-opacity': 0
}
},
{
id: 'gl-draw-polygon-stroke-inactive',
type: 'line',
filter: ['all', ['==', 'active', 'false'],
['==', '$type', 'Polygon'],
['!=', 'mode', 'static']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#3bb2d0',
'line-width': 2
}
},
{
id: 'gl-draw-polygon-stroke-active',
type: 'line',
filter: ['all', ['==', 'active', 'true'],
['==', '$type', 'Polygon']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': portColor,
'line-dasharray': [0.2, 2],
'line-width': 2
}
},
{
id: 'gl-draw-line-inactive',
type: 'line',
filter: ['all', ['==', 'active', 'false'],
['==', '$type', 'LineString'],
['!=', 'mode', 'static']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#3bb2d0',
'line-width': 2
}
},
{
id: 'gl-draw-line-active',
type: 'line',
filter: ['all', ['==', '$type', 'LineString'],
['==', 'active', 'true']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': portColor,
'line-dasharray': [0.2, 2],
'line-width': 2
}
},
{
id: 'gl-draw-point-point-stroke-inactive',
type: 'circle',
filter: ['all', ['==', 'active', 'false'],
['==', '$type', 'Point'],
['==', 'meta', 'feature'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 15,
'circle-opacity': 1,
'circle-color': '#fff'
}
},
{
id: 'gl-draw-point-inactive',
type: 'circle',
filter: ['all', ['==', 'active', 'false'],
['==', '$type', 'Point'],
['==', 'meta', 'feature'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 3,
'circle-color': '#3bb2d0'
}
},
{
id: 'gl-draw-point-stroke-active',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'],
['==', 'active', 'true'],
['!=', 'meta', 'midpoint']
],
paint: {
'circle-radius': 7,
'circle-color': '#fff'
}
},
{
id: 'gl-draw-point-active',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'],
['!=', 'meta', 'midpoint'],
['==', 'active', 'true']
],
paint: {
'circle-radius': 5,
'circle-color': portColor
}
},
{
id: 'gl-draw-polygon-fill-static',
type: 'fill',
filter: ['all', ['==', 'mode', 'static'],
['==', '$type', 'Polygon']
],
paint: {
'fill-color': '#404040',
'fill-outline-color': '#404040',
'fill-opacity': 0.1
}
},
{
id: 'gl-draw-polygon-stroke-static',
type: 'line',
filter: ['all', ['==', 'mode', 'static'],
['==', '$type', 'Polygon']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#404040',
'line-width': 2
}
},
{
id: 'gl-draw-line-static',
type: 'line',
filter: ['all', ['==', 'mode', 'static'],
['==', '$type', 'LineString']
],
layout: {
'line-cap': 'round',
'line-join': 'round'
},
paint: {
'line-color': '#404040',
'line-width': 2
}
},
{
id: 'gl-draw-point-static',
type: 'circle',
filter: ['all', ['==', 'mode', 'static'],
['==', '$type', 'Point']
],
paint: {
'circle-radius': 5,
'circle-color': '#404040'
}
},
{
id: 'gl-draw-polygon-color-picker',
type: 'fill',
filter: ['all', ['==', '$type', 'Polygon'],
['has', 'user_portColor']
],
paint: {
'fill-color': ['get', 'user_portColor'],
'fill-outline-color': ['get', 'user_portColor'],
'fill-opacity': 0.5
}
},
{
id: 'gl-draw-line-color-picker',
type: 'line',
filter: ['all', ['==', '$type', 'LineString'],
['has', 'user_portColor']
],
paint: {
'line-color': ['get', 'user_portColor'],
'line-width': 2
}
},
{
id: 'gl-draw-point-color-picker',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'],
['has', 'user_portColor']
],
paint: {
'circle-radius': 3,
'circle-color': ['get', 'user_portColor']
}
},
{
id: 'gl-draw-polygon-midpoint-stroke',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'],
['==', 'meta', 'midpoint']
],
paint: {
'circle-radius': 6,
'circle-color': '#e3641f'
}
},
{
id: 'gl-draw-polygon-midpoint',
type: 'circle',
filter: ['all', ['==', '$type', 'Point'],
['==', 'meta', 'midpoint']
],
paint: {
'circle-radius': 4,
'circle-color': '#44484a'
}
},
{
id: 'gl-draw-polygon-and-line-vertex-stroke-inactive',
type: 'circle',
filter: ['all', ['==', 'meta', 'vertex'],
['==', '$type', 'Point'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 8, // outer circle
'circle-color': '#e3641f'
}
},
{
id: 'gl-draw-polygon-and-line-vertex-inactive',
type: 'circle',
filter: ['all', ['==', 'meta', 'vertex'],
['==', '$type', 'Point'],
['!=', 'mode', 'static']
],
paint: {
'circle-radius': 6, // inner circle
'circle-color': '#44484a'
}
},
]
}

and when u want to add custom styles/colors in geofence you get do it like this:
this.geofenceDrawer.add(geofence); // this is to add the geofence in the mapboxdrawer object
this.geofenceDrawer.setFeatureProperty(geofence.id, 'portColor', "colorCode"); // any color code that you want to add
this.geofenceDrawer.add(this.geofenceDrawer.get(geofence.id)) // in the end you have to update this geofence in the mapboxdrawer object.

I hope this helps

@puka-tchou
Copy link

Hello, I just stumbled on this very problem, and while I managed to find a workaround, seeing this feature implemented would be a welcome addition. Any updates?

@SnailBones
Copy link

This issue has become rather verbose, so let's move discussion of implementing this feature to #1109.

@3zzy
Copy link

3zzy commented Mar 16, 2024

Another option is to use mapbox-gl-js's addLayer function.

@mcwhittemore addLayer in the onSetup lifecycle method when writing a custom mode you mean?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question rendering Rendering issues and errors
Projects
None yet
Development

No branches or pull requests