tileserver-gl/src/pmtiles_adapter.js
dependabot[bot] 300925d432
fix(deps): Bump pmtiles from 2.11.0 to 3.0.0 (#1161)
* fix(deps): Bump pmtiles from 2.11.0 to 3.0.0

Bumps [pmtiles](https://github.com/protomaps/pmtiles) from 2.11.0 to 3.0.0.
- [Commits](https://github.com/protomaps/pmtiles/commits)

---
updated-dependencies:
- dependency-name: pmtiles
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix: update for named imports

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Andrew Calcutt <acalcutt@techidiots.net>
2024-02-02 22:12:26 -05:00

151 lines
3.2 KiB
JavaScript

import fs from 'node:fs';
import { PMTiles, FetchSource } from 'pmtiles';
import { isValidHttpUrl } from './utils.js';
class PMTilesFileSource {
constructor(fd) {
this.fd = fd;
}
getKey() {
return this.fd;
}
async getBytes(offset, length) {
const buffer = Buffer.alloc(length);
await readFileBytes(this.fd, buffer, offset);
const ab = buffer.buffer.slice(
buffer.byteOffset,
buffer.byteOffset + buffer.byteLength,
);
return { data: ab };
}
}
/**
*
* @param fd
* @param buffer
* @param offset
*/
async function readFileBytes(fd, buffer, offset) {
return new Promise((resolve, reject) => {
fs.read(fd, buffer, 0, buffer.length, offset, (err) => {
if (err) {
return reject(err);
}
resolve();
});
});
}
/**
*
* @param FilePath
*/
export function openPMtiles(FilePath) {
let pmtiles = undefined;
if (isValidHttpUrl(FilePath)) {
const source = new FetchSource(FilePath);
pmtiles = new PMTiles(source);
} else {
const fd = fs.openSync(FilePath, 'r');
const source = new PMTilesFileSource(fd);
pmtiles = new PMTiles(source);
}
return pmtiles;
}
/**
*
* @param pmtiles
*/
export async function getPMtilesInfo(pmtiles) {
const header = await pmtiles.getHeader();
const metadata = await pmtiles.getMetadata();
//Add missing metadata from header
metadata['format'] = getPmtilesTileType(header.tileType).type;
metadata['minzoom'] = header.minZoom;
metadata['maxzoom'] = header.maxZoom;
if (header.minLon && header.minLat && header.maxLon && header.maxLat) {
metadata['bounds'] = [
header.minLon,
header.minLat,
header.maxLon,
header.maxLat,
];
} else {
metadata['bounds'] = [-180, -85.05112877980659, 180, 85.0511287798066];
}
if (header.centerZoom) {
metadata['center'] = [
header.centerLon,
header.centerLat,
header.centerZoom,
];
} else {
metadata['center'] = [
header.centerLon,
header.centerLat,
parseInt(metadata['maxzoom']) / 2,
];
}
return metadata;
}
/**
*
* @param pmtiles
* @param z
* @param x
* @param y
*/
export async function getPMtilesTile(pmtiles, z, x, y) {
const header = await pmtiles.getHeader();
const tileType = getPmtilesTileType(header.tileType);
let zxyTile = await pmtiles.getZxy(z, x, y);
if (zxyTile && zxyTile.data) {
zxyTile = Buffer.from(zxyTile.data);
} else {
zxyTile = undefined;
}
return { data: zxyTile, header: tileType.header };
}
/**
*
* @param typenum
*/
function getPmtilesTileType(typenum) {
let head = {};
let tileType;
switch (typenum) {
case 0:
tileType = 'Unknown';
break;
case 1:
tileType = 'pbf';
head['Content-Type'] = 'application/x-protobuf';
break;
case 2:
tileType = 'png';
head['Content-Type'] = 'image/png';
break;
case 3:
tileType = 'jpeg';
head['Content-Type'] = 'image/jpeg';
break;
case 4:
tileType = 'webp';
head['Content-Type'] = 'image/webp';
break;
case 5:
tileType = 'avif';
head['Content-Type'] = 'image/avif';
break;
}
return { type: tileType, header: head };
}