Is there a built-in way to change the style without reloading the whole map? - mapbox-gl-js

Whenever I use map.setStyle to change the style, the entire map reloads. This can be seen in the Mapbox GL JS example: https://docs.mapbox.com/mapbox-gl-js/example/setstyle/
I'm interested in changing the map more seamlessly. An example of this can be seen in Google maps when you switch between Map and Satellite views.
Does Mapbox GL JS have an easy way of style changing without reloading the whole map, or does this need to be implemented manually (I.e. with map.removeSource, map.addSource, map.removeLayer, map.addLayer)?

It depends a bit what you mean by "reloading the whole map". In this case, every single layer and source is being replaced wholesale, so it doesn't really have much choice.
If you have a style object, make some changes to it, and call setStyle() with the new style object, my understanding is that only the differences will be acted on. So usually, the effect won't be "reloading the whole map".

Related

Mapbox Loaded Event

I am using Mapbox to render a map with an layer from rainviewer. The code is working but I need to synchronize with the end of the layer rendering. I need to know when the last layer is rendered and the image is complete. I need to do this because I'm rendering the HTML in puppeteer. Using any of the networkidle options does not work. There does not seem to be any event on the Map object that signals this either.
I did scour the forums, etc. looking for a solution but did not find anything that would work specifically in this scenario.
This is a generally broken use case in Mapbox-GL-JS. One option that may work for you is:
map.once('idle', () => ...)
This fires once the map has come to rest, completely painted.

Is it possible to add a watermark in MapBox vector tiles?

A client would like to add their URL as a brand/watermark within a MapBox tiled vector layer in MapBox Studio, so that the watermark appears wherever the tiled vector layer is displayed. (One possible use-case is to discourage competitors from stealing that tiled layer in their own maps.)
Is it possible to add a watermark to a tiled layer in MapBox, and ensure that it's visible at least once in every view?
I tried adding a duplicate copy of a polyline dataset as a Symbol Layer, and labelling it with the client's URL using the Text Field option. This works but has the side effect of preventing the labels from appearing on the original copy of the line layer.
It is not possible to add a single occurrence of a watermark to a map style in Studio in the way that the Mapbox watermark is displayed on a map, but there are alternative approaches to achieve what you are looking to do.
If the underlying goal is to prevent competitors from using a particular map style (and hence an underlying tiled layer), the best approach is to set scopes and URL restrictions on the Mapbox access tokens being used to access the map style in a public environment. You can find more useful information about token management and access tokens in general in the Mapbox documentation. This approach could be used in conjunction with adding a branded "watermark" on the client side -- for example, placing a fixed div in the corner of a web map loaded with GL JS. Although this watermark obviously isn't included in the style itself, setting a URL restriction on the access token used to load the map would prevent others from accessing the same map with that token on other domains.
You could also experiment with adding a low-opacity background-pattern to relevant layers in the map style itself. This property could be used to mimic a traditional watermarked effect, where a particular logo is placed on an image at multiple regular intervals.

How to write text onto a mapbox vector tile

I want to label stations on my map, and I would like to clusterize the stops at different zoom levels to filter them down. So as you zoom out all you get is the start and end, and then finally a single label start->end.
How do I render a text label on a vector tile ?
I could fetch the stations as a geojson and reload on zoom change if there's no easy way to do this with tiles.
Is there a reason you need to encode your data differently per-zoom-level in the tiles or are you mainly concerned with displaying data differently per-zoom-level? If the latter, I would recommend looking for an approach that focuses more on styling the vector tiles you already have rather than trying to generate those tiles in a more complex fashion. You could try using a zoom function to style your data. If you're using Mapbox Studio, you can also set zoom-specific style rules in the Studio UI, which is the route you'll probably want to go if you're using Leaflet (I see the Leaflet tag in your post but it's not entirely clear what your implementation looks like).
If the former, you may need to use a tool like Tippecanoe. This route will likely be a bit more complex, but gives you fine-grained control over how your vector tiles are generated. Keep in mind that once you've created your tiles using Tippecanoe, you'll still need to style them somehow.

Custom drawing layer in Mapbox GL JS (and Leaflet)

I'm starting research to add a user feature to an existing map built in Mapbox GL JS (wrapped in an Angular 2+ application). What I need to do, is allow a user to be able to draw and rotate ellipses and text labels over the top of a map, and be able to save screen captures of the result.
I'm coming into this with no experience in Mapbox or Leaflet, so I have a lot to figure out. My first goal is to determine if I can do this in Mapbox directly (with a plugin?), of if I will need to render a canvas over the top of my map with some third-part drawing library (I have a lot of experience with those).
The obvious advantage to doing this in Mapbox directly would be that we might still be able zoom and pan.
The Mapbox-gl-draw library lets the user author features in a map, but probably not to the extent you need.
If the features the user creates don't need to live "in map space" (ie, the map is static, and the labels are statically positioned over the top, for printing), working directly on a canvas will give you much more flexibility. You'll also have access to a much wider variety of libraries.

Can leaflet notify me when a certain area is in the view?

I have several GeoJSON features on the map and wonder if leaflet could notify me when I am over a feature. I think that's geofencing?
Yes, and there is nothing very complicated to implement it.
What do you mean by "I am over a feature"?
If you mean your mouse pointer or a kind of marker / point that represents your current position, you would simply need a plugin like leaflet-pip to determine which features contain your position, if any (react on map"mousemove" event for the mouse).
If you mean the current map view intersects some of the features, that would be slightly more complex, but still easily solved through another library like turf. Look for turf.intersect method. You would need to iterate over all your features, checked against a rectangle built from the current map view (probably something like: L.rectangle(map.getBounds()).toGeoJSON()).