How can I tell if a Leaflet layer is currently visible? - leaflet

I'm building a Leaflet plugin that adds/removes layers to/from a Leaflet map. My plugin needs to know if a given layer is visible on-screen. So far, I've come up with the following criteria that a layer must meet in order to be considered "visible":
It must be added to the map. (This is trivial to check in my case.)
It must be within a valid zoom range. (This is also pretty easy to handle.)
It must be visible within the current extent/bounds.
The third criteria is the one I am having difficulty checking. My layers are a variety of different Esri-Leaflet layers. I understand that I can check whether a given point or rectangle is contained within the visible bounds of the map with map.getBounds().contains(...), but my problem is I am not sure how to represent my Esri-Leaflet layer as a rectangle. Not even all Leaflet layers have a getLatLng() method, so this question isn't even Esri-Leaflet specific (e.g. how would you perform the same check on a TileLayer)?
How can I get the bounds of a Leaflet layer, or otherwise check if the layer is visible on the map?
Not a duplicate of:
Get a list of markers/layers within current map bounds in Leaflet
Get the bounding box of the visible leaflet map?

Related

Two cursors on maps at same time in Mapbox GL-JS

I am developing a weather radar viewer using Mapbox. In a certain mode, there are 2 Mapbox maps on the screen at the same time showing different modes of the radar. The maps are locked to each other. When one map moves, rotates, or pans - the other one does as well. I did this by simply passing the properties of one map to the other. In the below screenshot, you will see how they are showing identical locations.
What I want to do is - when the user is hovering the mouse over "map1", I would like an identical (ghost or false) cursor on "map2". Here is what I am looking to do:
(edit: What you are looking at is an actual screenshot. Each map is enclosed in a DIV with 50% width of the screen, if this helps to explain)
I don't know if this is even possible in Mapbox. Hopefully someone can give some guidance as I can't find any other questions related to this and I really have no code to show without knowing where to start.
If you attempt to do this inside Mapbox-GL-JS (for instance, by constantly updating the location of a GeoJSON feature layer), I think the performance will be pretty poor.
But since the two views are exactly locked (and presumably the exact same dimensions), you can just do this at an HTML/CSS level. Detect mouse movement on the first map, and update the location of an absolutely-positioned element hovering over the second map to match.
Another approach would be using a canvas element overlaid over the second map, similarly updated.

Marker versus point feature?

When should one use a marker instead of a feature layer of points in Mapbox?
Points layers can be updated and styled dynamically using all the styling tools of Mapbox GL JS. Features in points layers can also be clicked, presenting a popup just like with a marker.
Given this, when would one want to use a marker?
As Andrew mentioned there are two sides two this:
Accessibility
Markers are implemented as DOM elements and thus can be included in the tab order and can be given accessibility attributes
Animation
As markers are DOM elements animating them is quite easy with a bit of CSS & JS. You can animate points on a circle layer too, but its much more of a hassle.
Small point count
The number of markers/points you can display at once is somewhat limited by what the DOM can manage. My suggestion is that, if you have more than 500 points to display, you should opt for a circle layer instead of markers (this is a very rough estimates and depends on other parameters as well, animation, point size etc.). Using a circle layer you will hit - depending on the hardware - a limit in the 10s of thounds of points.

Mapbox GL JS: Show all labels completely inside non-interactive map

Labels across the visble map's edges are only shown partially. This is of course expected behaviour and not a problem when panning is possible.
But for non-interactive maps, like in this Mapbox example, panning is disabled. There's no way for users to ever see those labels completely. That leaves most of them as useless clutter.
For this case, when panning is disabled, I'd prefer to either render those labels completely inside the visible map or not at all. Any ideas?
The symbol-avoid-edges property provides the behaviour for which you're asking. Applying this property to all symbol layers in your base layer will require some light scripting or elbow grease.
There is no existing way to prevent labels from intersecting with the viewport edges.

Mapbox gl repeat marker

I try to repeat a marker at the same coordinates when I am moving the map to infinity, in the same way that layers.
example : https://www.mapbox.com/mapbox-gl-js/example/geojson-polygon/
Has anyone found how to do that please?
If it's not possible, conversely is it possible to not repeat layers when you moving the map ?
Thank you
The Link example you provided is not using Markers to render the shaded area. It is using a feature, in this case a polygon, included in a layer (a layer can have many features).
In MapBox the rendered map is made up of any number of layers (including the tile data) which is rendered whenever you scroll or drag to a particular area of the map. For example as you keep dragging to the right in the map it will just keep rendering in the relevant layers and tiles.
The Marker functionality has a different purpose which is as a one off selected point which is useful for a user click or hover interaction.

Mapbox GL JS: Set Map Center or Bounds to show visible part of a layer

I have a layer with 7000+ polygons and am displaying a portion of the polygons in a web app using "setFilter" on map load. (The filter is choosing the polygons to display dynamically based on data from the url of the current page.)
However, I can't figure out how to make the map center on the particular polygons currently showing (the visible part of that layer), which means the user has to hunt around to find it. There can be multiple polygons visible at one time, and they are a range of different sizes. Any ideas?
If you have the feature collection of polygons that are visible on your map, you can use the turf-extent module to get the geographical extent of the visible polygons, and then call map.fitBounds(extent) to make all visible polygons within the viewport.