0

I am developing an application in Apache Cordova that uses vector layers in mbtiles, created with tippecanoe, and I need it to be fully accessible offline. To achieve this, I am using maplibre-gl-js, using addProtocol("custom"), as indicated here

I am using the "tms" scheme since the data in the mbtiles file is in that scheme. When I take the z, x, and y from the url parameters to query the database with SQLite, the {y} parameter is a little offset.

It's not a XYZ / TMS schema problem. Everything is under TMS schema (data, and maplibre source), but the value in maplibre "{y}" parameter, has a little offset, for example, {y} = 10005 in maplibre, versus tile_row 10050 in mbtiles, or {y} = 20011 in maplibre, vs tile_row 20100 in mbtiles.

Mbtiles tile_row has the correct value.

The code i'm using is:

first, add the new protocol.

maplibregl.addProtocol("custom", (params, callback) => {
    getTileBufferFromDatabase(params).then(tileBuffer => {
        if (tileBuffer) {
            callback(null, tileBuffer, null, null);
        } else {
            callback(new Error(message));
        }
    });
    return { cancel: () => { } };
});

Add the function to query the database, used in the protocol

async function getTileBufferFromDatabase(params) {
    const url = new URL(params['url']);
    const pathComponents = url.pathname.split('/');
    const z = parseInt(pathComponents[6]);
    const x = parseInt(pathComponents[7]);
    var y = parseInt(pathComponents[8].split('.')[0]);

    return new Promise((resolve, reject) => {
        db2.executeSql('SELECT BASE64(tile_data) AS base64_tile_data FROM tiles WHERE zoom_level = ?    AND tile_column = ? AND tile_row = ?', [z, x, y], (resultSet) => {
            if (resultSet.rows.length > 0) {
                const base64Data = resultSet.rows.item(0).base64_tile_data;
                const rawData = pako.inflate(base64js.toByteArray(base64Data));
                resolve(rawData)
            } else {
                resolve(null);
            }
        }, (error) => {
            reject(error);
        });
    });
}

Creating the map.

const map = new maplibregl.Map({
    container: 'map',
    center: [
        -4.93911,
        37,777985
    ],
    zoom: 14,
    tileSize: 512
});

Adding the source with the new protocol "custom".

map.addSource('mbtiles-source', {
      type: 'vector',
      tiles: ["custom://data/user/com.project.ndvi/databases/{z}/{x}/{y}.pbf"],
      tileSize: 512,
      minzoom: 14,
      maxzoom: 15
 });

var ndvi_layer = map.addLayer({
   "id": 'ndvi-layer',
   "type": 'fill',
   "source": 'mbtiles-source',
   "source-layer": 'ndvi',
   "layout": {},
   "paint": {
     'fill-color': 'blue',
     'fill-opacity': 0.5
   }
 });

When I query the databse, the {y} parameter is offset.

Any idea why this is happening? Thank you!

0 Answers0