Maximkaaa / galileo

General purpose cross-platform GIS-rendering library written in Rust
Apache License 2.0
377 stars 27 forks source link

Add support for PMTiles (ProtoMaps) #18

Open prabirshrestha opened 10 months ago

prabirshrestha commented 10 months ago

It would be great if PMTiles is supported. More info at https://docs.protomaps.com. Since it doesn't require any server processing, one can easily serve PMTiles via s3, webdav or any http server as long as it has http range support.

You can see the sample at https://protomaps.github.io/PMTiles/ and can use the dev tools to see the http range requests it is making to view the tiles.

I'm currently using PMTiles for to render offline maps as I'm building a nextcloud alternative in rust and typescript. I have a proof of concept PMTiles working on react/typescript with webdav server in rust doing http range requests. My plan is to use this to show photo exif information similar to how google photos or other popular apps does it without any external internet connection.

image

While I could just use the typescript project for rendering the pmtiles, my interest with Galileo project is due to the fact it supports native iOS where I plan to port my project to a native iOS app.

If you want to download the full earth for pmtiles you can do so via https://maps.protomaps.com/builds/. It is around 110gb.

There is also a cli that allows to extract part of tiles. https://github.com/protomaps/go-pmtiles. This could be useful to have to ship the pmtiles as part of the iOS builds or even the web server where I can ship the country borders. Currently this is not a top of my list yet.

Would love to have Galileo working with PMTiles.

shujaatak commented 10 months ago

@prabirshrestha I have found & tested a rust project supporting PMTiles: https://github.com/DelusionalLogic/maps This project can be helpful for galileo for adding support for PMTiles.

Maximkaaa commented 10 months ago

Thanks @prabirshrestha for such a detailed feature request. To support these fully we would need to implement two things:

Requesting tiles with given indices from a web-server

This should be pretty straightforward to do. All we need is to implement a new TileProvider<RasterTile> that would use range request for all tiles and then separate them into parts. The only caveat is that at the moment layer requests download of tiles one by one, and we want it to request all at once and let the provider decide the strategy for their loading. This will also be useful when we decide to support caching tiles in ways different from files (like DB or local tile servers).

Caching tiles

We don't really need to add a new way to cache the tiles. They can be cached as separate files. The only difference from how current TileProvider works is that caching is done on the network layer to mimic how caching would work on web. But in case of range requests we want caching to be done by the TileProvider after it separates tiles from each other.

Also, adding an option for tile provider to only use cache would allow the tile layer to work offline, only with the tiles that were loaded before. And that can be done by directly calling TileProvider::load_tiles method on any set of tiles needed by the application.


Implementing these doesn't require any in-depth knowledge of Galileo internals, so I would suggest anyone interested and/or familiar with PMTiles format to give it a try. If not, I'll get to it as a part of v0.2 release (which will be in a while...)

prabirshrestha commented 1 month ago

There is another one https://versatiles.org which is created in rust so has official libraries.

https://docs.rs/versatiles/latest/versatiles/