Skip to content

Add refreshTiles() to map public API #5806

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

Merged
merged 11 commits into from
Apr 26, 2025

Conversation

NathanMOlson
Copy link
Contributor

@NathanMOlson NathanMOlson commented Apr 25, 2025

This PR adds refreshTiles() to the map public API.

This allows tiles to be force-reloaded from outside MapLibre. The use case I've got in mind is that when tiles on the server change, a WebSocket message is sent to the client (using a to-be-developed plugin) notifying it of changed tiles. The plugin can then call map.refreshTiles() with the modified tile IDs, causing the map to reload the tiles and display the new data.

You can check out a demo here. Clicking on a tile will call map.refreshTiles() on the tile. I'm using addProtocol() to draw a timestamp (from performance.now()) on each tile, representing the time it was loaded. Zoom all the way out to see that it behaves correctly for wrapped tiles (all tiles sharing an x/y/z are updated when a tile is clicked). Zoom past z3 to see that it behaves correctly for overscaled tiles.

Marginally related to #5799, which is also intended to help with the use case where server-side data is changing rapidly.

  • Confirm your changes do not include backports from Mapbox projects (unless with compliant license) - if you are not sure about this, please ask!
  • Briefly describe the changes in this PR.
  • Link to related issues.
  • Write tests for all new functionality.
  • Document any changes to public APIs.
  • Add an entry to CHANGELOG.md under the ## main section.

@NathanMOlson NathanMOlson marked this pull request as draft April 25, 2025 00:01
@NathanMOlson NathanMOlson marked this pull request as ready for review April 25, 2025 00:15
@HarelM
Copy link
Collaborator

HarelM commented Apr 25, 2025

This PR solves the following feature request, doesn't it?

@NathanMOlson
Copy link
Contributor Author

This PR solves the following feature request, doesn't it?

I believe so, now that I've added a source-global refresh option.

@HarelM
Copy link
Collaborator

HarelM commented Apr 25, 2025

There is a report about flashing tiles here: #415, does this PR solves the requested feature?

@NathanMOlson NathanMOlson changed the title Add refreshTile() to map public API Add refreshTiles() to map public API Apr 25, 2025
@NathanMOlson
Copy link
Contributor Author

There is a report about flashing tiles here: #415, does this PR solves the requested feature?

I'm not sure. I've only tested with raster tiles. With raster tiles, I don't see any flashing and the refresh happens immediately.

In my implementation, map.refreshTiles(sourceId) is equivalent to map.style.sourceCaches[sourceId].reload() when sourceId is a valid source ID.

* Reload any currently renderable tiles that are match one of the incoming `tileId` x/y/z
*/
refreshTiles(tileIds: Array<ICanonicalTileID>) {
for (const id in this._tiles) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to do some .filter(...) to the array to remove some indentation in this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed some indentation without using filter.

@HarelM
Copy link
Collaborator

HarelM commented Apr 26, 2025

Added a minor nit-picking.
How confident are you with adding this functionality with all the reload flow happening in maplibre?
Or maybe the question is why wasn't this API introduced earlier if the implementation is so simple?

@NathanMOlson
Copy link
Contributor Author

How confident are you with adding this functionality with all the reload flow happening in maplibre?

I'm confident that this works in my use-case, which is raster tiles. I'm not confident that it works for vector tiles or geojson sources.

@HarelM
Copy link
Collaborator

HarelM commented Apr 26, 2025

In geojson you can simply update the data and it will reload I believe, for vector I hope it will work as expected.
In any case, the public API is ok even if we decide the underlying implantation.

@HarelM HarelM merged commit a733662 into maplibre:main Apr 26, 2025
17 checks passed
@russss
Copy link

russss commented Apr 26, 2025

Nice! I might give it a test with vector tiles...

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

Successfully merging this pull request may close these issues.

Map Source Refresh A reliable way to reload tiles from a vector tile source
3 participants