Merge branch 'master' into master

This commit is contained in:
Andrew Calcutt 2024-08-31 22:41:40 -04:00 committed by GitHub
commit ecd7456d02
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 201 additions and 194 deletions

74
package-lock.json generated
View file

@ -1,24 +1,24 @@
{ {
"name": "tileserver-gl", "name": "tileserver-gl",
"version": "4.12.0", "version": "4.13.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "tileserver-gl", "name": "tileserver-gl",
"version": "4.12.0", "version": "4.13.1",
"license": "BSD-2-Clause", "license": "BSD-2-Clause",
"dependencies": { "dependencies": {
"@jsse/pbfont": "^0.2.1", "@jsse/pbfont": "^0.2.2",
"@mapbox/mbtiles": "0.12.1", "@mapbox/mbtiles": "0.12.1",
"@mapbox/polyline": "^1.2.1", "@mapbox/polyline": "^1.2.1",
"@mapbox/sphericalmercator": "1.2.0", "@mapbox/sphericalmercator": "1.2.0",
"@mapbox/vector-tile": "2.0.3", "@mapbox/vector-tile": "2.0.3",
"@maplibre/maplibre-gl-native": "5.4.0", "@maplibre/maplibre-gl-native": "5.4.1",
"@maplibre/maplibre-gl-style-spec": "20.3.1", "@maplibre/maplibre-gl-style-spec": "20.3.1",
"@sindresorhus/fnv1a": "3.1.0", "@sindresorhus/fnv1a": "3.1.0",
"advanced-pool": "0.3.3", "advanced-pool": "0.3.3",
"axios": "^1.7.5", "axios": "^1.7.6",
"canvas": "2.11.2", "canvas": "2.11.2",
"chokidar": "3.6.0", "chokidar": "3.6.0",
"clone": "2.1.2", "clone": "2.1.2",
@ -40,8 +40,8 @@
"tileserver-gl": "src/main.js" "tileserver-gl": "src/main.js"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.4.0", "@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.2.2", "@commitlint/config-conventional": "^19.4.1",
"@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/parser": "^7.18.0",
"chai": "5.1.1", "chai": "5.1.1",
@ -73,9 +73,9 @@
} }
}, },
"node_modules/@acalcutt/node-pre-gyp": { "node_modules/@acalcutt/node-pre-gyp": {
"version": "1.0.14", "version": "1.0.15",
"resolved": "https://registry.npmjs.org/@acalcutt/node-pre-gyp/-/node-pre-gyp-1.0.14.tgz", "resolved": "https://registry.npmjs.org/@acalcutt/node-pre-gyp/-/node-pre-gyp-1.0.15.tgz",
"integrity": "sha512-P+xIiJefMa2ylrqPDwCw1S4Xr6ULKvF5TqmbZKifPSzId9jiSgLoplKfTmoP/y3Mq2kWts/rZDX1N9wMaSl6ZA==", "integrity": "sha512-+9vgfGWqByWMO/XbbCSpKe/ug7n16YbjKixY6D/Wx6goqx43qdmcXhFrGlnqNbyrpzKwbbQASX7AS/YbZNc/rg==",
"dependencies": { "dependencies": {
"detect-libc": "^2.0.0", "detect-libc": "^2.0.0",
"https-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.0",
@ -213,13 +213,13 @@
"integrity": "sha512-sw2JhwJyvyL0zlhG61aDzOVryEfJg2PDZFSV7i7IdC7nAE41WuXCru3QWLGiP87At0BMzKOoKO/FqEGoKygGZQ==" "integrity": "sha512-sw2JhwJyvyL0zlhG61aDzOVryEfJg2PDZFSV7i7IdC7nAE41WuXCru3QWLGiP87At0BMzKOoKO/FqEGoKygGZQ=="
}, },
"node_modules/@commitlint/cli": { "node_modules/@commitlint/cli": {
"version": "19.4.0", "version": "19.4.1",
"resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.4.0.tgz", "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.4.1.tgz",
"integrity": "sha512-sJX4J9UioVwZHq7JWM9tjT5bgWYaIN3rC4FP7YwfEwBYiIO+wMyRttRvQLNkow0vCdM0D67r9NEWU0Ui03I4Eg==", "integrity": "sha512-EerFVII3ZcnhXsDT9VePyIdCJoh3jEzygN1L37MjQXgPfGS6fJTWL/KHClVMod1d8w94lFC3l4Vh/y5ysVAz2A==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@commitlint/format": "^19.3.0", "@commitlint/format": "^19.3.0",
"@commitlint/lint": "^19.2.2", "@commitlint/lint": "^19.4.1",
"@commitlint/load": "^19.4.0", "@commitlint/load": "^19.4.0",
"@commitlint/read": "^19.4.0", "@commitlint/read": "^19.4.0",
"@commitlint/types": "^19.0.3", "@commitlint/types": "^19.0.3",
@ -234,9 +234,9 @@
} }
}, },
"node_modules/@commitlint/config-conventional": { "node_modules/@commitlint/config-conventional": {
"version": "19.2.2", "version": "19.4.1",
"resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.2.2.tgz", "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.4.1.tgz",
"integrity": "sha512-mLXjsxUVLYEGgzbxbxicGPggDuyWNkf25Ht23owXIH+zV2pv1eJuzLK3t1gDY5Gp6pxdE60jZnWUY5cvgL3ufw==", "integrity": "sha512-D5S5T7ilI5roybWGc8X35OBlRXLAwuTseH1ro0XgqkOWrhZU8yOwBOslrNmSDlTXhXLq8cnfhQyC42qaUCzlXA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@commitlint/types": "^19.0.3", "@commitlint/types": "^19.0.3",
@ -324,14 +324,14 @@
} }
}, },
"node_modules/@commitlint/lint": { "node_modules/@commitlint/lint": {
"version": "19.2.2", "version": "19.4.1",
"resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.2.2.tgz", "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.4.1.tgz",
"integrity": "sha512-xrzMmz4JqwGyKQKTpFzlN0dx0TAiT7Ran1fqEBgEmEj+PU98crOFtysJgY+QdeSagx6EDRigQIXJVnfrI0ratA==", "integrity": "sha512-Ws4YVAZ0jACTv6VThumITC1I5AG0UyXMGua3qcf55JmXIXm/ejfaVKykrqx7RyZOACKVAs8uDRIsEsi87JZ3+Q==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@commitlint/is-ignored": "^19.2.2", "@commitlint/is-ignored": "^19.2.2",
"@commitlint/parse": "^19.0.3", "@commitlint/parse": "^19.0.3",
"@commitlint/rules": "^19.0.3", "@commitlint/rules": "^19.4.1",
"@commitlint/types": "^19.0.3" "@commitlint/types": "^19.0.3"
}, },
"engines": { "engines": {
@ -428,9 +428,9 @@
} }
}, },
"node_modules/@commitlint/rules": { "node_modules/@commitlint/rules": {
"version": "19.0.3", "version": "19.4.1",
"resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.0.3.tgz", "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.4.1.tgz",
"integrity": "sha512-TspKb9VB6svklxNCKKwxhELn7qhtY1rFF8ls58DcFd0F97XoG07xugPjjbVnLqmMkRjZDbDIwBKt9bddOfLaPw==", "integrity": "sha512-AgctfzAONoVxmxOXRyxXIq7xEPrd7lK/60h2egp9bgGUMZK9v0+YqLOA+TH+KqCa63ZoCr8owP2YxoSSu7IgnQ==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"@commitlint/ensure": "^19.0.3", "@commitlint/ensure": "^19.0.3",
@ -1099,9 +1099,9 @@
} }
}, },
"node_modules/@jsse/pbfont": { "node_modules/@jsse/pbfont": {
"version": "0.2.1", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/@jsse/pbfont/-/pbfont-0.2.1.tgz", "resolved": "https://registry.npmjs.org/@jsse/pbfont/-/pbfont-0.2.2.tgz",
"integrity": "sha512-Dn01v8D2Bv4BjrJHgPyN+O4+fsytlpRtE2SA0gh7I5folZ7uyqJKS11yG+xOkYPcLo0RvMNg9zWJEMfdaMBMzg==", "integrity": "sha512-pggXQp645b+bNwJ826odtLuGUJZvvKexg79XLreqInvancdgQlkUQf7yWtoqF94lNcZOwZhZXh7nDMR5NCACJg==",
"dependencies": { "dependencies": {
"@bufbuild/protobuf": "^2.0.0" "@bufbuild/protobuf": "^2.0.0"
}, },
@ -1212,12 +1212,12 @@
} }
}, },
"node_modules/@maplibre/maplibre-gl-native": { "node_modules/@maplibre/maplibre-gl-native": {
"version": "5.4.0", "version": "5.4.1",
"resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-native/-/maplibre-gl-native-5.4.0.tgz", "resolved": "https://registry.npmjs.org/@maplibre/maplibre-gl-native/-/maplibre-gl-native-5.4.1.tgz",
"integrity": "sha512-onNGCs7BYDR3R1lO6vjnP5WoEiaU2ISUziLX/LkiWsBjU8JkDmgMr+gxHiIKsLgQlL9bqSolZnHpbp0XOkMlyA==", "integrity": "sha512-Vkn/3W2suB1DDKjb5fzS2CDT046MqmZV2+EvQ+lU5t+khxJucbKRGfa+kHTksW//F6sTPb+Bez7CEKICOb5L7w==",
"hasInstallScript": true, "hasInstallScript": true,
"dependencies": { "dependencies": {
"@acalcutt/node-pre-gyp": "^1.0.14", "@acalcutt/node-pre-gyp": "^1.0.15",
"@acalcutt/node-pre-gyp-github": "1.4.8", "@acalcutt/node-pre-gyp-github": "1.4.8",
"minimatch": "^9.0.4", "minimatch": "^9.0.4",
"npm-run-all": "^4.1.5" "npm-run-all": "^4.1.5"
@ -1999,9 +1999,9 @@
} }
}, },
"node_modules/axios": { "node_modules/axios": {
"version": "1.7.5", "version": "1.7.6",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.5.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.6.tgz",
"integrity": "sha512-fZu86yCo+svH3uqJ/yTdQ0QHpQu5oL+/QE+QPSv6BZSkDAoky9vytxp7u5qk83OJFS3kEBcesWni9WTZAv3tSw==", "integrity": "sha512-Ekur6XDwhnJ5RgOCaxFnXyqlPALI3rVeukZMwOdfghW7/wGz784BYKiQq+QD8NPcr91KRo30KfHOchyijwWw7g==",
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.6", "follow-redirects": "^1.15.6",
"form-data": "^4.0.0", "form-data": "^4.0.0",
@ -5432,9 +5432,9 @@
"integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA==" "integrity": "sha512-awNbTOqCxK1DBGjalK3xqWIstBZgN6fxsMSiXLs9/spqWkF2pAhb2rrYCFSsr1/tT7PhcDGjZndG8SWYn0byYA=="
}, },
"node_modules/micromatch": { "node_modules/micromatch": {
"version": "4.0.7", "version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true, "dev": true,
"dependencies": { "dependencies": {
"braces": "^3.0.3", "braces": "^3.0.3",

View file

@ -1,6 +1,6 @@
{ {
"name": "tileserver-gl", "name": "tileserver-gl",
"version": "4.12.0", "version": "4.13.1",
"description": "Map tile server for JSON GL styles - vector and server side generated raster tiles", "description": "Map tile server for JSON GL styles - vector and server side generated raster tiles",
"main": "src/main.js", "main": "src/main.js",
"bin": "src/main.js", "bin": "src/main.js",
@ -18,16 +18,16 @@
"prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){ process.exit(1) } \" || husky" "prepare": "node -e \"if (process.env.NODE_ENV !== 'production'){ process.exit(1) } \" || husky"
}, },
"dependencies": { "dependencies": {
"@jsse/pbfont": "^0.2.1", "@jsse/pbfont": "^0.2.2",
"@mapbox/mbtiles": "0.12.1", "@mapbox/mbtiles": "0.12.1",
"@mapbox/polyline": "^1.2.1", "@mapbox/polyline": "^1.2.1",
"@mapbox/sphericalmercator": "1.2.0", "@mapbox/sphericalmercator": "1.2.0",
"@mapbox/vector-tile": "2.0.3", "@mapbox/vector-tile": "2.0.3",
"@maplibre/maplibre-gl-native": "5.4.0", "@maplibre/maplibre-gl-native": "5.4.1",
"@maplibre/maplibre-gl-style-spec": "20.3.1", "@maplibre/maplibre-gl-style-spec": "20.3.1",
"@sindresorhus/fnv1a": "3.1.0", "@sindresorhus/fnv1a": "3.1.0",
"advanced-pool": "0.3.3", "advanced-pool": "0.3.3",
"axios": "^1.7.5", "axios": "^1.7.6",
"canvas": "2.11.2", "canvas": "2.11.2",
"chokidar": "3.6.0", "chokidar": "3.6.0",
"clone": "2.1.2", "clone": "2.1.2",
@ -46,8 +46,8 @@
"tileserver-gl-styles": "2.0.0" "tileserver-gl-styles": "2.0.0"
}, },
"devDependencies": { "devDependencies": {
"@commitlint/cli": "^19.4.0", "@commitlint/cli": "^19.4.1",
"@commitlint/config-conventional": "^19.2.2", "@commitlint/config-conventional": "^19.4.1",
"@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/eslint-plugin": "^7.18.0",
"@typescript-eslint/parser": "^7.18.0", "@typescript-eslint/parser": "^7.18.0",
"chai": "5.1.1", "chai": "5.1.1",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -8,9 +8,11 @@ import path from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import axios from 'axios'; import axios from 'axios';
import { server } from './server.js'; import { server } from './server.js';
import MBTiles from '@mapbox/mbtiles';
import { isValidHttpUrl } from './utils.js'; import { isValidHttpUrl } from './utils.js';
import { openPMtiles, getPMtilesInfo } from './pmtiles_adapter.js'; import { openPMtiles, getPMtilesInfo } from './pmtiles_adapter.js';
import { program } from 'commander';
import { existsP } from './promises.js';
import { openMbTilesWrapper } from './mbtiles_wrapper.js';
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename); const __dirname = path.dirname(__filename);
@ -23,8 +25,6 @@ if (args.length >= 3 && args[2][0] !== '-') {
args.splice(2, 0, '--mbtiles'); args.splice(2, 0, '--mbtiles');
} }
import { program } from 'commander';
import { existsP } from './promises.js';
program program
.description('tileserver-gl startup options') .description('tileserver-gl startup options')
.usage('tileserver-gl [mbtiles] [options]') .usage('tileserver-gl [mbtiles] [options]')
@ -187,62 +187,55 @@ const startWithInputFile = async (inputFile) => {
); );
process.exit(1); process.exit(1);
} }
const instance = new MBTiles(inputFile + '?mode=ro', (err) => { let info;
if (err) { try {
console.log('ERROR: Unable to open MBTiles.'); const mbw = await openMbTilesWrapper(inputFile);
console.log(`Make sure ${path.basename(inputFile)} is valid MBTiles.`); info = await mbw.getInfo();
process.exit(1); if (!info) throw new Error('Metadata missing in the MBTiles.');
} catch (err) {
console.log('ERROR: Unable to open MBTiles or read metadata:', err);
console.log(`Make sure ${path.basename(inputFile)} is valid MBTiles.`);
process.exit(1);
}
const bounds = info.bounds;
if (
info.format === 'pbf' &&
info.name.toLowerCase().indexOf('openmaptiles') > -1
) {
config['data'][`v3`] = {
mbtiles: path.basename(inputFile),
};
const styles = await fsp.readdir(path.resolve(styleDir, 'styles'));
for (const styleName of styles) {
const styleFileRel = styleName + '/style.json';
const styleFile = path.resolve(styleDir, 'styles', styleFileRel);
if (await existsP(styleFile)) {
config['styles'][styleName] = {
style: styleFileRel,
tilejson: {
bounds,
},
};
}
} }
} else {
console.log(
`WARN: MBTiles not in "openmaptiles" format. Serving raw data only...`,
);
config['data'][(info.id || 'mbtiles').replace(/[?/:]/g, '_')] = {
mbtiles: path.basename(inputFile),
};
}
instance.getInfo(async (err, info) => { if (opts.verbose) {
if (err || !info) { console.log(JSON.stringify(config, undefined, 2));
console.log('ERROR: Metadata missing in the MBTiles.'); } else {
console.log( console.log('Run with --verbose to see the config file here.');
`Make sure ${path.basename(inputFile)} is valid MBTiles.`, }
);
process.exit(1);
}
const bounds = info.bounds;
if ( return startServer(null, config);
info.format === 'pbf' &&
info.name.toLowerCase().indexOf('openmaptiles') > -1
) {
config['data'][`v3`] = {
mbtiles: path.basename(inputFile),
};
const styles = await fsp.readdir(path.resolve(styleDir, 'styles'));
for (const styleName of styles) {
const styleFileRel = styleName + '/style.json';
const styleFile = path.resolve(styleDir, 'styles', styleFileRel);
if (await existsP(styleFile)) {
config['styles'][styleName] = {
style: styleFileRel,
tilejson: {
bounds,
},
};
}
}
} else {
console.log(
`WARN: MBTiles not in "openmaptiles" format. Serving raw data only...`,
);
config['data'][(info.id || 'mbtiles').replace(/[?/:]/g, '_')] = {
mbtiles: path.basename(inputFile),
};
}
if (opts.verbose) {
console.log(JSON.stringify(config, undefined, 2));
} else {
console.log('Run with --verbose to see the config file here.');
}
return startServer(null, config);
});
});
} }
}; };

46
src/mbtiles_wrapper.js Normal file
View file

@ -0,0 +1,46 @@
import MBTiles from '@mapbox/mbtiles';
import util from 'node:util';
/**
* Promise-ful wrapper around the MBTiles class.
*/
class MBTilesWrapper {
constructor(mbtiles) {
this._mbtiles = mbtiles;
this._getInfoP = util.promisify(mbtiles.getInfo.bind(mbtiles));
}
/**
* Get the underlying MBTiles object.
* @returns {MBTiles}
*/
getMbTiles() {
return this._mbtiles;
}
/**
* Get the MBTiles metadata object.
* @returns {Promise<object>}
*/
getInfo() {
return this._getInfoP();
}
}
/**
* Open the given MBTiles file and return a promise that resolves with a
* MBTilesWrapper instance.
* @param inputFile Input file
* @returns {Promise<MBTilesWrapper>}
*/
export function openMbTilesWrapper(inputFile) {
return new Promise((resolve, reject) => {
const mbtiles = new MBTiles(inputFile + '?mode=ro', (err) => {
if (err) {
reject(err);
return;
}
resolve(new MBTilesWrapper(mbtiles));
});
});
}

View file

@ -5,7 +5,6 @@ import path from 'path';
import clone from 'clone'; import clone from 'clone';
import express from 'express'; import express from 'express';
import MBTiles from '@mapbox/mbtiles';
import Pbf from 'pbf'; import Pbf from 'pbf';
import { VectorTile } from '@mapbox/vector-tile'; import { VectorTile } from '@mapbox/vector-tile';
@ -16,6 +15,7 @@ import {
openPMtiles, openPMtiles,
} from './pmtiles_adapter.js'; } from './pmtiles_adapter.js';
import { gunzipP, gzipP } from './promises.js'; import { gunzipP, gzipP } from './promises.js';
import { openMbTilesWrapper } from './mbtiles_wrapper.js';
export const serve_data = { export const serve_data = {
init: (options, repo) => { init: (options, repo) => {
@ -242,39 +242,25 @@ export const serve_data = {
} }
} else if (inputType === 'mbtiles') { } else if (inputType === 'mbtiles') {
sourceType = 'mbtiles'; sourceType = 'mbtiles';
const sourceInfoPromise = new Promise((resolve, reject) => { const mbw = await openMbTilesWrapper(inputFile);
source = new MBTiles(inputFile + '?mode=ro', (err) => { const info = await mbw.getInfo();
if (err) { source = mbw.getMbTiles();
reject(err); tileJSON['name'] = id;
return; tileJSON['format'] = 'pbf';
}
source.getInfo((err, info) => {
if (err) {
reject(err);
return;
}
tileJSON['name'] = id;
tileJSON['format'] = 'pbf';
Object.assign(tileJSON, info); Object.assign(tileJSON, info);
tileJSON['tilejson'] = '2.0.0'; tileJSON['tilejson'] = '2.0.0';
delete tileJSON['filesize']; delete tileJSON['filesize'];
delete tileJSON['mtime']; delete tileJSON['mtime'];
delete tileJSON['scheme']; delete tileJSON['scheme'];
Object.assign(tileJSON, params.tilejson || {}); Object.assign(tileJSON, params.tilejson || {});
fixTileJSONCenter(tileJSON); fixTileJSONCenter(tileJSON);
if (options.dataDecoratorFunc) { if (options.dataDecoratorFunc) {
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON); tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
} }
resolve();
});
});
});
await sourceInfoPromise;
} }
repo[id] = { repo[id] = {

View file

@ -24,7 +24,6 @@ import express from 'express';
import sanitize from 'sanitize-filename'; import sanitize from 'sanitize-filename';
import SphericalMercator from '@mapbox/sphericalmercator'; import SphericalMercator from '@mapbox/sphericalmercator';
import mlgl from '@maplibre/maplibre-gl-native'; import mlgl from '@maplibre/maplibre-gl-native';
import MBTiles from '@mapbox/mbtiles';
import polyline from '@mapbox/polyline'; import polyline from '@mapbox/polyline';
import proj4 from 'proj4'; import proj4 from 'proj4';
import axios from 'axios'; import axios from 'axios';
@ -43,6 +42,7 @@ import {
import { renderOverlay, renderWatermark, renderAttribution } from './render.js'; import { renderOverlay, renderWatermark, renderAttribution } from './render.js';
import fsp from 'node:fs/promises'; import fsp from 'node:fs/promises';
import { existsP, gunzipP } from './promises.js'; import { existsP, gunzipP } from './promises.js';
import { openMbTilesWrapper } from './mbtiles_wrapper.js';
const FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+.?\\d+)'; const FLOAT_PATTERN = '[+-]?(?:\\d+|\\d+.?\\d+)';
const PATH_PATTERN = const PATH_PATTERN =
@ -1152,7 +1152,6 @@ export const serve_rendered = {
}; };
repo[id] = repoobj; repo[id] = repoobj;
const queue = [];
for (const name of Object.keys(styleJSON.sources)) { for (const name of Object.keys(styleJSON.sources)) {
let sourceType; let sourceType;
let source = styleJSON.sources[name]; let source = styleJSON.sources[name];
@ -1226,69 +1225,52 @@ export const serve_rendered = {
} }
} }
} else { } else {
queue.push( const inputFileStats = await fsp.stat(inputFile);
new Promise(async (resolve, reject) => { if (!inputFileStats.isFile() || inputFileStats.size === 0) {
inputFile = path.resolve(options.paths.mbtiles, inputFile); throw Error(`Not valid MBTiles file: "${inputFile}"`);
const inputFileStats = await fsp.stat(inputFile); }
if (!inputFileStats.isFile() || inputFileStats.size === 0) { const mbw = await openMbTilesWrapper(inputFile);
throw Error(`Not valid MBTiles file: "${inputFile}"`); const info = await mbw.getInfo();
map.sources[name] = mbw.getMbTiles();
map.sourceTypes[name] = 'mbtiles';
if (!repoobj.dataProjWGStoInternalWGS && info.proj4) {
// how to do this for multiple sources with different proj4 defs?
const to3857 = proj4('EPSG:3857');
const toDataProj = proj4(info.proj4);
repoobj.dataProjWGStoInternalWGS = (xy) =>
to3857.inverse(toDataProj.forward(xy));
}
const type = source.type;
Object.assign(source, info);
source.type = type;
source.tiles = [
// meta url which will be detected when requested
`mbtiles://${name}/{z}/{x}/{y}.${info.format || 'pbf'}`,
];
delete source.scheme;
if (options.dataDecoratorFunc) {
source = options.dataDecoratorFunc(name, 'tilejson', source);
}
if (
!attributionOverride &&
source.attribution &&
source.attribution.length > 0
) {
if (!tileJSON.attribution.includes(source.attribution)) {
if (tileJSON.attribution.length > 0) {
tileJSON.attribution += ' | ';
} }
map.sources[name] = new MBTiles(inputFile + '?mode=ro', (err) => { tileJSON.attribution += source.attribution;
map.sources[name].getInfo((err, info) => { }
if (err) { }
console.error(err);
return;
}
map.sourceTypes[name] = 'mbtiles';
if (!repoobj.dataProjWGStoInternalWGS && info.proj4) {
// how to do this for multiple sources with different proj4 defs?
const to3857 = proj4('EPSG:3857');
const toDataProj = proj4(info.proj4);
repoobj.dataProjWGStoInternalWGS = (xy) =>
to3857.inverse(toDataProj.forward(xy));
}
const type = source.type;
Object.assign(source, info);
source.type = type;
source.tiles = [
// meta url which will be detected when requested
`mbtiles://${name}/{z}/{x}/{y}.${info.format || 'pbf'}`,
];
delete source.scheme;
if (options.dataDecoratorFunc) {
source = options.dataDecoratorFunc(
name,
'tilejson',
source,
);
}
if (
!attributionOverride &&
source.attribution &&
source.attribution.length > 0
) {
if (!tileJSON.attribution.includes(source.attribution)) {
if (tileJSON.attribution.length > 0) {
tileJSON.attribution += ' | ';
}
tileJSON.attribution += source.attribution;
}
}
resolve();
});
});
}),
);
} }
} }
} }
await Promise.all(queue);
// standard and @2x tiles are much more usual -> default to larger pools // standard and @2x tiles are much more usual -> default to larger pools
const minPoolSizes = options.minRendererPoolSizes || [8, 4, 2]; const minPoolSizes = options.minRendererPoolSizes || [8, 4, 2];
const maxPoolSizes = options.maxRendererPoolSizes || [16, 8, 4]; const maxPoolSizes = options.maxRendererPoolSizes || [16, 8, 4];