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

A new fill paint property to mask areas outside region of interest or polygon #6267

Open
planemad opened this issue Mar 2, 2018 · 19 comments
Labels
cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.) feature 🍏

Comments

@planemad
Copy link

planemad commented Mar 2, 2018

This is a feature request. The implementation details are unknown.

Motivation

As a map designer, a common cartographic technique for me to focus the user attention to an area of interest is to mask/hide details of the areas outside the region of interest.

To accomplish such an effect with the existing GL style-spec, one needs to create a polygon covering the whole world with a hole of the desired region. This is a cumbersome and tedious data creation process for a map designer.

Design Alternatives

Design

Adding a new fill-region paint property is simple and communicates clearly to the user where the paint is applied in relation with the polygon.

Feel that maybe a new inverted-fill layer type might be the simplest with respect to keeping the style-spec clean

Mock-Up

What will this design look like to developers?

map.addLayer({
	'id': 'area of interest',
	'source': 'aoi',
        'type': 'fill',
	'layout': {},
	'paint': {
                'fill-region': 'outside',
                ...any supported fill properties
	}
});

What will this design look like to end users?

Image source: inverted fill in qgis

Concepts

fill-region is the new concept that would be introduced. This feature is called "inverted polygon" in qgis.

@planemad planemad added the cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.) label Mar 2, 2018
@planemad planemad changed the title A new layer type to mask areas outside region of interest A new fill layer type to mask areas outside region of interest Mar 2, 2018
@anandthakker
Copy link
Contributor

Another alternative would be to add a fill-region: 'inside' | 'outside' property to the existing fill layer.

@andrewharvey
Copy link
Collaborator

This feature would make it easier for the map designer, avoiding the need to use turf.mask. See prior discussion for this feature at #993 and #6257.

@ryanbaumann
Copy link
Contributor

While masks work great for maps without symbol layers, one challenge are labels near the borders of the mask. This proposal is likely out-of-scope for this particular bug, but it's important to consider when creating masks.

@markusjohnsson
Copy link
Contributor

We need this feature in our application and I am willing to work on it to make it happen.

What we need is to invert the 'water' layer - we need a 'land' layer to place above a custom layer where we render wave height and ocean currents. And because it is such a large dataset for the water layer, we would really like to not have to download, invert offline and upload it again.

(Or, we would need a way to mask our custom layer with the water layer, but I think an inverted fill is more usable.)

I have implemented a proof-of-concept (/hack) of @mourner 's suggestion from #993 (comment) to invert geojson on-the-fly inside mapbox, but did not manage to do the same with vector tiles.. Would that be feasible?

I would like some guidance so that I don't develop something that cannot be merged.

@markusjohnsson
Copy link
Contributor

I've worked on this a bit more, taking another approach than the one mentioned above. Instead I'm using the stencil buffer to mask the polygon and then fill the tile.

image

Still lots of work to be done, but at least this looks like it will work.

@waissbluth
Copy link

Is this feature planned?

@markusjohnsson
Copy link
Contributor

@waissbluth I've received no indication that this would be accepted if I opened a pull request. I still need this for a customer project, but it is on low priority right now.

@unitof
Copy link

unitof commented Mar 13, 2019

@markusjohnsson Do you have a public fork you'd be willing to share? Looks like a wondrous start—is the "inverse" fill styled the same way I would style a fill-type layer?

@1ec5
Copy link
Contributor

1ec5 commented Apr 26, 2019

This is orthogonal to the request for masking, but in case anyone is coming here looking for a way to effectively dim the background layer outside an area of interest without blotting it out entirely, I shared a simple approach towards the end of this workshop at State of the Map U.S. 2018.

detroit

@planemad planemad changed the title A new fill layer type to mask areas outside region of interest A new fill paint property to mask areas outside region of interest or polygon Nov 4, 2019
@pavelko3lov
Copy link

Is there any feature like this (mask areas outside polygon) in Mapbox iOS SDK ?
Appreciate for the answer!

@andrewharvey
Copy link
Collaborator

The new within expression https://blog.mapbox.com/introducing-gl-js-v1-9-0-and-the-within-expression-6268f6c32be3 may help with some of the use cases here. It will let you apply a different style to points and lines outside a polygon.

@pavelko3lov
Copy link

The new within expression https://blog.mapbox.com/introducing-gl-js-v1-9-0-and-the-within-expression-6268f6c32be3 may help with some of the use cases here. It will let you apply a different style to points and lines outside a polygon.

Sorry, but I mean in Mapbox iOS SDK, not in mapbox-gl-sj.

@andrewharvey
Copy link
Collaborator

Sorry, but I mean in Mapbox iOS SDK, not in mapbox-gl-sj.

I was commenting in general about this thread, not in response to your question.

@1ec5
Copy link
Contributor

1ec5 commented Apr 30, 2020

@fvonk, as of mapbox/mapbox-gl-native-ios#184 and v5.8.0, you can use a SELF IN %@ expression, which is equivalent to the within expression seen here. However, it only works on whole features in shape or vector tile sources; it won’t cut up a single feature that happens to be partially inside your region of interest.

@Stophface
Copy link

You can use turf's mask function for that
https://www.npmjs.com/package/@turf/mask
Simply create a "cover polygon" with the extend of your (Map)View (or the whole world) and use your Polygon. Turf even creates the "cover polygon" for you, if you do not provide one.
https://github.com/Turfjs/turf/blob/master/packages/turf-mask/index.js#L58

@s11richard
Copy link

Has there been any update to the status of this feature request?

We are currently using the solution that leverages turf-mask to invert the geometries. But in our case, it is too cumbersome to render on the client, so we are processing them as tilesets.

In order to avoid the high cost of processing 10m resolution tiles that span the entire planet, we are forced to use a maxzoom value of 5. This results in a 300m resolution, which is not ideal.

This feature seems like the only solution to our problem.

@boredland
Copy link

It's a shame that within can only be applied to point and line geometries, not everything else.

@chriszrc
Copy link

chriszrc commented Sep 7, 2023

@boredland yeah, and that lines won't get clipped to the bounds either, they're either all in or out :(

@david-morris
Copy link

This issue is making the use of vector tiles much more difficult. I'll have to make two sets for now, and needing to do so programattically rules out Mapbox's web UI for doing so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cross-platform 📺 Requires coordination with Mapbox GL Native (style specification, rendering tests, etc.) feature 🍏
Projects
None yet
Development

No branches or pull requests