Leaflet map with subclass of TileLayer

I am using Leaflet to access an authenticated tile server. The tile server needs an Authorization header added to each tile request. Apparently this is not possible in plain leaflet because it is using <img> tags to request tiles:

I would like to extend TileLayer to add the Authorization header but I'm stuck on a few points.

I found some JavaScript examples that point in the right direction, see links below. I can probably figure out the JavaScript to make the request, but I'm clueless about how to incorporate a subclassed TileLayer into the R wrapper around leaflet.js. Any example of using a custom TileLayer subclass from R would be very helpful!

My client is a Shiny app, not sure if that matters.
Thanks, Kent

References:
It is possible to extend L.TileLayer to use a different method to fetch tiles. Docs here:
https://leafletjs.com/examples/extending/extending-2-layers.html

Here is an example of extending the WMS layer to use XMLHttpRequest with custom headers to fetch WMS tiles. I would like to do this with XYZ tiles:

1 Like

OK, I figured this out, it is possible using htmlwidgets::onRender.

I'm using a variation of this TileLayer subclass. The function to create my custom tile layer is L.TileLayer.xhr. The renderLeaflet code looks roughly like this:

output$map = renderLeaflet({
    map = leaflet() # Don't addTiles here!
    url_template = 'http://...' # XYZ tile URL
    auth_header = '...' # Authorization token to add to headers
    js_code = stringr::str_glue("
    function(el, x, data) {{
        var xhrLayer = L.TileLayer.xhr(
            '{url_template}', data.options, data.headers)
        .addTo(this);
    }}")
    map = htmlwidgets::onRender(map, js_code, data=list(
        headers=list(list(header='Authorization', value=auth_header))))
    map
})
3 Likes

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.