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

Layer.isVisible() #11897

Open
joffreyBerrier opened this issue May 15, 2022 · 5 comments
Open

Layer.isVisible() #11897

joffreyBerrier opened this issue May 15, 2022 · 5 comments

Comments

@joffreyBerrier
Copy link

mapbox-gl-js version: 2.8.2

Question

I would like to know if my layer is visible
The layer is hidden according to the zoom in the map, is there a method to know the layers visible on the map ? I have tried to parse the array but is quiet complicated :/

The function map.getLayoutProperty(layerId, 'visibility') doesn't work because my layer is hidden with the zoom and not with an attribute

I would like to have a function like that :
map.getLayer(id).isVisible() => boolean

Thx

Links to related documentation

@SnailBones
Copy link
Contributor

As far I know there's no built-in function to do what you're asking.

In most cases you should be able to check the visibility as follows:

if (map.getZoom() > layer.minzoom && map.getZoom() < layer.maxzoom){
   console.log("Layer is visible!")
}

One caveat is that layer visibility is determined at the tile level and can be inconsistent between tiles with globe, terrain or high pitch.

@joffreyBerrier
Copy link
Author

Hi @SnailBones yes this is a simple case with min_zoom / max_zoom but when in mapbox studio we define line-width or line-opacity with a interpolation this is quit more difficult

Exemple :
mapbox

When I have that 🔝 mapbox send me an array like that :

this.map.getStyle.layers.find(l => l.id === road-simple).paint['line-width']
['interpolate', ..., ..., 5, 0.7, 13, 2.5, 18, 26]

So with that I have a solution but is not clean :

const values = layer?.paint['line-width']?.slice(
  3,
  layer.paint['line-width'].length
)

const b = values[1] => // return 5 equal to zoom 5
const c = values[2] => // return 0.7 equal to2. width 0.7

if (zoom <= c && b === 0) {
  return false
}

But if my zoom is not 5 but 8 the line property is linear or exponential so my line-width is not 0.7 but a size between 0.7 and 2.5, and I wouldlike a simple method like map.getLayer(id).isVisible() or map.getLayer(id).getRealWidth()

Thx

@joffreyBerrier
Copy link
Author

@SnailBones does it seem complicated to you?
Do you think I can try to do it ? 😇

@SnailBones
Copy link
Contributor

this.map.getStyle.layers.find(l => l.id === road-simple).paint['line-width']
['interpolate', ..., ..., 5, 0.7, 13, 2.5, 18, 26]

@joffreyBerrier I think you can rewrite this line as:

this.map.getPaintProperty('road-simple', 'line-width');

This approach seems like a good solution to your specific use case, but if we were to add this feature to GL JS I'd like it to be able to evaluate any expression. I think the proposal to add a public hook to expression evaluation in #7670 would be the right approach. One approach would be to add alternatives to getPaintProperty() and getLayoutProperty like:

 evaluatePaintProperty(layerId, propertyName, feature?)

Then your use case could be achieved with:

if (map.evaluatePaintProperty("road-simple", "line-width") > 0){
   console.log("Layer is visible!")
}

@joffreyBerrier
Copy link
Author

Hi @SnailBones thx

this.map.getStyle.layers.find(l => l.id === road-simple).paint['line-width']
=== this.map.getPaintProperty('road-simple', 'line-width')

I need to know for line-width but I also need it for line-opacity etc

So your solution is finished ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants