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

Enable viewing of locally saved pmtiles #73

Open
Robinlovelace opened this issue Nov 24, 2023 · 8 comments
Open

Enable viewing of locally saved pmtiles #73

Robinlovelace opened this issue Nov 24, 2023 · 8 comments

Comments

@Robinlovelace
Copy link
Contributor

I've just tried the following to no avail:

library(leafem)
library(leaflet)
url_rivers = "https://vector-tiles-data.s3.eu-central-1.amazonaws.com/rivers_africa.pmtiles"
leaflet() %>%
  addTiles() %>%
  addPMPolylines(
    url = url_rivers
    , layerId = "rivers"
    , group = "rivers"
    , style = paintRules(
      layer = "rivers_africa"
      , color = "blue"
    )
  ) %>%
  setView(24, 2.5, 4)
f_rivers = basename(url_rivers)
if (!file.exists(f_rivers)) {
  download.file(url_rivers, f_rivers)
}
leaflet() %>%
  addTiles() %>%
  addPMPolylines(
    # url = paste0("pmtiles://", f_rivers)
    url = f_rivers
    , layerId = "rivers"
    , group = "rivers"
    , style = paintRules(
      layer = "rivers_africa"
      , color = "blue"
    )
  ) %>%
  setView(24, 2.5, 4)

I know that hosting pmtiles locally can work: protomaps/PMTiles#234

Thoughts @tim-salabim or anyone? Would be super useful if possible and imagine it would work as a simple solution when shipping a .pmtiles file alongside a map for a quick solution.

@tim-salabim
Copy link
Member

I've investigated that last year. IIRC, we would need to serve the tiles via a local server. I tried with servr but that doesn't work as it apparently does not support http range requests. At least that was what @bdon told me. I guess if we find a server solution that supports http range requests locally that we can invoke from R, then supporting PMTiles should be straight forward.

@Robinlovelace
Copy link
Contributor Author

Ah yes, a parallel server is needed, that makes sense. In my tests I use VS Live Server extension FYI: https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer

I imagine something like {servr} would be ideal, worth opening an issue in the issue tracker? Various alternatives out there, wish I had more time to test them out!

@tim-salabim
Copy link
Member

I've already provided a thumbs up here
rstudio/httpuv#259

Have you tried serving locally and then using addPM* functions?

@Robinlovelace
Copy link
Contributor Author

Nope, can do! Also, out of interest, I tried uploading the .pmtiles file to GitHub pages, am I missing something obvious here?

u_routes = "https://itsleeds.github.io/netvis/rnet_limerick.pmtiles"
leaflet() %>%
  addTiles() %>%
  addPMPolylines(
    # url = paste0("pmtiles://", f_rivers)
    url = u_routes
    , layerId = "rnet_limerick"
    # , group = "rivers"
    , style = paintRules(
      layer = "rnet_limerick"
      , color = "blue"
    )
  ) %>%
  setView(24, 2.5, 4)

No luck yet, should show lines in Limerick 🤞

@tim-salabim
Copy link
Member

Did you enable cors? What does the browser console say?

@Robinlovelace
Copy link
Contributor Author

Didn't enable cors but should be fine when both on GH pages. Here's a test: https://itsleeds.github.io/netvis/pmtiles.html

Doesn't seem to be asking for the tiles so probably something up with my code. Here are the tiles: https://itsleeds.github.io/netvis/rnet_limerick.pmtiles

And here's an example of it working with GH pages: https://altilunium.github.io/vmap/

Food for thought...

@Robinlovelace
Copy link
Contributor Author

Update: pmtiles working! I guess the challenge now is just to get R to output the html, right?

https://itsleeds.github.io/netvis/pmtiles-test.html

Relevant bit of html:

        <script type="text/javascript">
            // add the PMTiles plugin to the maplibregl global.
            let protocol = new pmtiles.Protocol();
            maplibregl.addProtocol("pmtiles",protocol.tile);

            let PMTILES_URL = "rnet_limerick.pmtiles"
            const p = new pmtiles.PMTiles(PMTILES_URL);

            // this is so we share one instance across the JS code and the map renderer
            protocol.add(p);

            // we first fetch the header so we can get the center lon, lat of the map.
            p.getHeader().then(h => {
                const map = new maplibregl.Map({
                    container: 'map',
                    zoom: 14,
                    center: [-8.63, 52.66],
                    style: {
                        version:8,
                        sources: {
                            "example_source": {
                                type: "vector",
                                url: "pmtiles://" + PMTILES_URL,
                                attribution: '© <a href="https://openstreetmap.org">OpenStreetMap</a>'
                            }
                        },
                        layers: [
                            {
                                "id":"rnet_limerick",
                                "source": "example_source",
                                "source-layer":"rnet_limerick",
                                "type": "line",
                                "paint": {
                                    "line-color": "red"
                                }
                            }
                        ]
                    }
                });
                map.showTileBoundaries = true;
            })
        </script>

Source: https://github.com/ITSLeeds/netvis/blob/main/pmtiles-test.html

@tim-salabim
Copy link
Member

That's probably because the PMTiles dependency hasn't been updated for quite some time...

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

No branches or pull requests

2 participants