maplibregl-mapbox-request-transformer icon indicating copy to clipboard operation
maplibregl-mapbox-request-transformer copied to clipboard

Mapbox maps with a geo-referenced transparent-background image shows with black background

Open igal1c0de4n opened this issue 2 years ago • 0 comments

This issue describes a maplibre/mapbox interoperability issue which may be associated with missing functionality in this plugin.

Geo-referencing a GeoTiff image into a mapbox map results in black background in the image transparent areas, instead of showing the map layer under

Note: The tests in this issue use the mapbox style mapbox://styles/mapme1/clbmiaqhu000a14s6w4wqmoij It is a custom style produced by loading a GeoTiff image in mapbox studio. The image has transparent background. The flow: load image, create tileset, add as a layer on top of a standard mapbox map.

I created https://jsfiddle.net/tivoni/k60nr18x which loads the style with mapblibregl-js v2.4.0. Note the black tiles background:

Screenshot 2022-12-16 at 10 55 58 PM

The same style loaded with the older mapblibregl-js v1.15.2 takes into account the image transparent background and shows the map tiles under the image layer:

https://jsfiddle.net/tivoni/k60nr18x/6/ Screenshot 2022-12-16 at 11 04 07 PM

The difference between the jsFiddles is the maplibregl versions and the usage of this plugin (only with maplibre v2.4.0)

Investigation

The requested mapbox style points to this .json resource which includes:

"tiles": [
  "https://a.tiles.mapbox.com/v4/mapme1.9x3arx2f/{z}/{x}/{y}.jpg?access_token=..."

Note the .jpg extension in the url pattern. Since JPEG does not support transparency, the request for such tiles seems incorrect.

To verify this assumption I inspected devtools network panel:

maplibre v1.15.2 requests WEBP images - the tile preview shows transparent background: Screenshot 2022-12-16 at 11 14 27 PM

In comparison, maplibre v2.4.0 requests JPEG images - the tile preview shows black background! Screenshot 2022-12-16 at 11 16 10 PM

Possible solutions:

  1. The mapbox json tile url pattern needs to be updated to something like: https://a.tiles.mapbox.com/v4/mapme1.9x3arx2f/{z}/{x}/{y}@2x.webp?access_token=...
  • Is this a configurable setting in mapbox studio? (or: is this a question to mapbox support staff?)
  1. Use transformRequest to catch and modify all .jpg tiles requests to *.tiles.mapbox.com:
import {isMapboxURL, transformMapboxUrl} from 'maplibregl-mapbox-request-transformer'

const map = new mapLibreGL.Map({
        ...
        transformRequest: (url, resourceType) => {
            if (isMapboxURL(url)) {
                return transformMapboxUrl(url, resourceType, accessToken)
            } else {
                const regEx =
                    /^https:\/\/[0-9a-zA-Z]+\.tiles\.mapbox\.com\/v[0-9]\/[0-9a-zA-Z]+\.[0-9a-zA-Z]+\/\d+\/\d+\/\d+\.jpg\?/
                if (regEx.test(url)) {
                    url = url.replace('.jpg', '@2x.webp')
                }
                return {url}
            }
        }

Note: the above code is confirmed to: (A) fetch the webp tiles and (B) display the layer under transparent part of the image correctly. Meaning, no black background appears and the map tiles renders under the transparent areas as expected.

  1. Integrate (2) into the maplibregl-mapbox-request-transformer plugin

@rowanwins your insights/advice is appreciated 🙏🏼

igal1c0de4n avatar Dec 16 '22 21:12 igal1c0de4n