mirror of
https://github.com/maptiler/tileserver-gl.git
synced 2024-08-15 23:10:36 +03:00
Merge pull request #1074 from liberty-rider/refactor4
Code cleaning: more idiomatic, a bit shorter
This commit is contained in:
commit
40ade063f9
@ -79,7 +79,7 @@
|
||||
<div class="details">
|
||||
<h3>{{tileJSON.name}}</h3>
|
||||
<div class="identifier">identifier: {{@key}}{{#if formatted_filesize}} | size: {{formatted_filesize}}{{/if}}</div>
|
||||
<div class="identifier">type: {{#is_vector}}vector{{/is_vector}}{{^is_vector}}raster{{/is_vector}} data {{#if source_type}} | ext: {{source_type}}{{/if}}</div>
|
||||
<div class="identifier">type: {{#is_vector}}vector{{/is_vector}}{{^is_vector}}raster{{/is_vector}} data {{#if sourceType}} | ext: {{sourceType}}{{/if}}</div>
|
||||
<p class="services">
|
||||
services: <a href="{{public_url}}data/{{@key}}.json{{&../key_query}}">TileJSON</a>
|
||||
{{#if xyz_link}}
|
||||
|
59
src/main.js
59
src/main.js
@ -9,7 +9,7 @@ import axios from 'axios';
|
||||
import { server } from './server.js';
|
||||
import MBTiles from '@mapbox/mbtiles';
|
||||
import { isValidHttpUrl } from './utils.js';
|
||||
import { PMtilesOpen, GetPMtilesInfo } from './pmtiles_adapter.js';
|
||||
import { openPMtiles, getPMtilesInfo } from './pmtiles_adapter.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@ -62,14 +62,14 @@ const opts = program.opts();
|
||||
|
||||
console.log(`Starting ${packageJson.name} v${packageJson.version}`);
|
||||
|
||||
const StartServer = (configPath, config) => {
|
||||
const startServer = (configPath, config) => {
|
||||
let publicUrl = opts.public_url;
|
||||
if (publicUrl && publicUrl.lastIndexOf('/') !== publicUrl.length - 1) {
|
||||
publicUrl += '/';
|
||||
}
|
||||
return server({
|
||||
configPath: configPath,
|
||||
config: config,
|
||||
configPath,
|
||||
config,
|
||||
bind: opts.bind,
|
||||
port: opts.port,
|
||||
cors: opts.cors,
|
||||
@ -77,11 +77,11 @@ const StartServer = (configPath, config) => {
|
||||
silent: opts.silent,
|
||||
logFile: opts.log_file,
|
||||
logFormat: opts.log_format,
|
||||
publicUrl: publicUrl,
|
||||
publicUrl,
|
||||
});
|
||||
};
|
||||
|
||||
const StartWithInputFile = async (inputFile) => {
|
||||
const startWithInputFile = async (inputFile) => {
|
||||
console.log(`[INFO] Automatically creating config file for ${inputFile}`);
|
||||
console.log(`[INFO] Only a basic preview style will be used.`);
|
||||
console.log(
|
||||
@ -123,8 +123,8 @@ const StartWithInputFile = async (inputFile) => {
|
||||
|
||||
const extension = inputFile.split('.').pop().toLowerCase();
|
||||
if (extension === 'pmtiles') {
|
||||
let FileOpenInfo = PMtilesOpen(inputFile);
|
||||
const metadata = await GetPMtilesInfo(FileOpenInfo);
|
||||
const fileOpenInfo = openPMtiles(inputFile);
|
||||
const metadata = await getPMtilesInfo(fileOpenInfo);
|
||||
|
||||
if (
|
||||
metadata.format === 'pbf' &&
|
||||
@ -174,7 +174,7 @@ const StartWithInputFile = async (inputFile) => {
|
||||
console.log('Run with --verbose to see the config file here.');
|
||||
}
|
||||
|
||||
return StartServer(null, config);
|
||||
return startServer(null, config);
|
||||
} else {
|
||||
if (isValidHttpUrl(inputFile)) {
|
||||
console.log(
|
||||
@ -215,7 +215,7 @@ const StartWithInputFile = async (inputFile) => {
|
||||
config['styles'][styleName] = {
|
||||
style: styleFileRel,
|
||||
tilejson: {
|
||||
bounds: bounds,
|
||||
bounds,
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -235,13 +235,13 @@ const StartWithInputFile = async (inputFile) => {
|
||||
console.log('Run with --verbose to see the config file here.');
|
||||
}
|
||||
|
||||
return StartServer(null, config);
|
||||
return startServer(null, config);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
fs.stat(path.resolve(opts.config), (err, stats) => {
|
||||
fs.stat(path.resolve(opts.config), async (err, stats) => {
|
||||
if (err || !stats.isFile() || stats.size === 0) {
|
||||
let inputFile;
|
||||
if (opts.file) {
|
||||
@ -251,7 +251,7 @@ fs.stat(path.resolve(opts.config), (err, stats) => {
|
||||
}
|
||||
|
||||
if (inputFile) {
|
||||
return StartWithInputFile(inputFile);
|
||||
return startWithInputFile(inputFile);
|
||||
} else {
|
||||
// try to find in the cwd
|
||||
const files = fs.readdirSync(process.cwd());
|
||||
@ -266,7 +266,7 @@ fs.stat(path.resolve(opts.config), (err, stats) => {
|
||||
}
|
||||
if (inputFile) {
|
||||
console.log(`No input file specified, using ${inputFile}`);
|
||||
return StartWithInputFile(inputFile);
|
||||
return startWithInputFile(inputFile);
|
||||
} else {
|
||||
const url =
|
||||
'https://github.com/maptiler/tileserver-gl/releases/download/v1.3.0/zurich_switzerland.mbtiles';
|
||||
@ -274,25 +274,26 @@ fs.stat(path.resolve(opts.config), (err, stats) => {
|
||||
const writer = fs.createWriteStream(filename);
|
||||
console.log(`No input file found`);
|
||||
console.log(`[DEMO] Downloading sample data (${filename}) from ${url}`);
|
||||
axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
})
|
||||
.then((response) => {
|
||||
response.data.pipe(writer);
|
||||
writer.on('finish', () => StartWithInputFile(filename));
|
||||
writer.on('error', (err) =>
|
||||
console.error(`Error writing file: ${err}`),
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(`Error downloading file: ${error}`);
|
||||
|
||||
try {
|
||||
const response = await axios({
|
||||
url,
|
||||
method: 'GET',
|
||||
responseType: 'stream',
|
||||
});
|
||||
|
||||
response.data.pipe(writer);
|
||||
writer.on('finish', () => startWithInputFile(filename));
|
||||
writer.on('error', (err) =>
|
||||
console.error(`Error writing file: ${err}`),
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error downloading file: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(`Using specified config file from ${opts.config}`);
|
||||
return StartServer(opts.config, null);
|
||||
return startServer(opts.config, null);
|
||||
}
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ class PMTilesFileSource {
|
||||
}
|
||||
async getBytes(offset, length) {
|
||||
const buffer = Buffer.alloc(length);
|
||||
await ReadFileBytes(this.fd, buffer, offset);
|
||||
await readFileBytes(this.fd, buffer, offset);
|
||||
const ab = buffer.buffer.slice(
|
||||
buffer.byteOffset,
|
||||
buffer.byteOffset + buffer.byteLength,
|
||||
@ -26,7 +26,7 @@ class PMTilesFileSource {
|
||||
* @param buffer
|
||||
* @param offset
|
||||
*/
|
||||
async function ReadFileBytes(fd, buffer, offset) {
|
||||
async function readFileBytes(fd, buffer, offset) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.read(fd, buffer, 0, buffer.length, offset, (err) => {
|
||||
if (err) {
|
||||
@ -41,7 +41,7 @@ async function ReadFileBytes(fd, buffer, offset) {
|
||||
*
|
||||
* @param FilePath
|
||||
*/
|
||||
export function PMtilesOpen(FilePath) {
|
||||
export function openPMtiles(FilePath) {
|
||||
let pmtiles = undefined;
|
||||
|
||||
if (isValidHttpUrl(FilePath)) {
|
||||
@ -59,12 +59,12 @@ export function PMtilesOpen(FilePath) {
|
||||
*
|
||||
* @param pmtiles
|
||||
*/
|
||||
export async function GetPMtilesInfo(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['format'] = getPmtilesTileType(header.tileType).type;
|
||||
metadata['minzoom'] = header.minZoom;
|
||||
metadata['maxzoom'] = header.maxZoom;
|
||||
|
||||
@ -103,23 +103,23 @@ export async function GetPMtilesInfo(pmtiles) {
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
export async function GetPMtilesTile(pmtiles, z, x, y) {
|
||||
export async function getPMtilesTile(pmtiles, z, x, y) {
|
||||
const header = await pmtiles.getHeader();
|
||||
const TileType = GetPmtilesTileType(header.tileType);
|
||||
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 };
|
||||
return { data: zxyTile, header: tileType.header };
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param typenum
|
||||
*/
|
||||
function GetPmtilesTileType(typenum) {
|
||||
function getPmtilesTileType(typenum) {
|
||||
let head = {};
|
||||
let tileType;
|
||||
switch (typenum) {
|
||||
|
@ -12,9 +12,9 @@ import { VectorTile } from '@mapbox/vector-tile';
|
||||
|
||||
import { getTileUrls, isValidHttpUrl, fixTileJSONCenter } from './utils.js';
|
||||
import {
|
||||
PMtilesOpen,
|
||||
GetPMtilesInfo,
|
||||
GetPMtilesTile,
|
||||
openPMtiles,
|
||||
getPMtilesInfo,
|
||||
getPMtilesTile,
|
||||
} from './pmtiles_adapter.js';
|
||||
|
||||
export const serve_data = {
|
||||
@ -53,8 +53,8 @@ export const serve_data = {
|
||||
) {
|
||||
return res.status(404).send('Out of bounds');
|
||||
}
|
||||
if (item.source_type === 'pmtiles') {
|
||||
let tileinfo = await GetPMtilesTile(item.source, z, x, y);
|
||||
if (item.sourceType === 'pmtiles') {
|
||||
let tileinfo = await getPMtilesTile(item.source, z, x, y);
|
||||
if (tileinfo == undefined || tileinfo.data == undefined) {
|
||||
return res.status(404).send('Not found');
|
||||
} else {
|
||||
@ -99,7 +99,7 @@ export const serve_data = {
|
||||
|
||||
return res.status(200).send(data);
|
||||
}
|
||||
} else if (item.source_type === 'mbtiles') {
|
||||
} else if (item.sourceType === 'mbtiles') {
|
||||
item.source.getTile(z, x, y, (err, data, headers) => {
|
||||
let isGzipped;
|
||||
if (err) {
|
||||
@ -223,11 +223,11 @@ export const serve_data = {
|
||||
}
|
||||
|
||||
let source;
|
||||
let source_type;
|
||||
let sourceType;
|
||||
if (inputType === 'pmtiles') {
|
||||
source = PMtilesOpen(inputFile);
|
||||
source_type = 'pmtiles';
|
||||
const metadata = await GetPMtilesInfo(source);
|
||||
source = openPMtiles(inputFile);
|
||||
sourceType = 'pmtiles';
|
||||
const metadata = await getPMtilesInfo(source);
|
||||
|
||||
tileJSON['name'] = id;
|
||||
tileJSON['format'] = 'pbf';
|
||||
@ -245,7 +245,7 @@ export const serve_data = {
|
||||
tileJSON = options.dataDecoratorFunc(id, 'tilejson', tileJSON);
|
||||
}
|
||||
} else if (inputType === 'mbtiles') {
|
||||
source_type = 'mbtiles';
|
||||
sourceType = 'mbtiles';
|
||||
const sourceInfoPromise = new Promise((resolve, reject) => {
|
||||
source = new MBTiles(inputFile + '?mode=ro', (err) => {
|
||||
if (err) {
|
||||
@ -285,7 +285,7 @@ export const serve_data = {
|
||||
tileJSON,
|
||||
publicUrl,
|
||||
source,
|
||||
source_type,
|
||||
sourceType,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
@ -4,7 +4,7 @@ import express from 'express';
|
||||
|
||||
import { getFontsPbf, listFonts } from './utils.js';
|
||||
|
||||
export const serve_font = (options, allowedFonts) => {
|
||||
export const serve_font = async (options, allowedFonts) => {
|
||||
const app = express().disable('x-powered-by');
|
||||
|
||||
const lastModified = new Date().toUTCString();
|
||||
@ -13,25 +13,29 @@ export const serve_font = (options, allowedFonts) => {
|
||||
|
||||
const existingFonts = {};
|
||||
|
||||
app.get('/fonts/:fontstack/:range([\\d]+-[\\d]+).pbf', (req, res, next) => {
|
||||
const fontstack = decodeURI(req.params.fontstack);
|
||||
const range = req.params.range;
|
||||
app.get(
|
||||
'/fonts/:fontstack/:range([\\d]+-[\\d]+).pbf',
|
||||
async (req, res, next) => {
|
||||
const fontstack = decodeURI(req.params.fontstack);
|
||||
const range = req.params.range;
|
||||
|
||||
try {
|
||||
const concatenated = await getFontsPbf(
|
||||
options.serveAllFonts ? null : allowedFonts,
|
||||
fontPath,
|
||||
fontstack,
|
||||
range,
|
||||
existingFonts,
|
||||
);
|
||||
|
||||
getFontsPbf(
|
||||
options.serveAllFonts ? null : allowedFonts,
|
||||
fontPath,
|
||||
fontstack,
|
||||
range,
|
||||
existingFonts,
|
||||
).then(
|
||||
(concated) => {
|
||||
res.header('Content-type', 'application/x-protobuf');
|
||||
res.header('Last-Modified', lastModified);
|
||||
return res.send(concated);
|
||||
},
|
||||
(err) => res.status(400).header('Content-Type', 'text/plain').send(err),
|
||||
);
|
||||
});
|
||||
return res.send(concatenated);
|
||||
} catch (err) {
|
||||
res.status(400).header('Content-Type', 'text/plain').send(err);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
app.get('/fonts.json', (req, res, next) => {
|
||||
res.header('Content-type', 'application/json');
|
||||
@ -40,8 +44,7 @@ export const serve_font = (options, allowedFonts) => {
|
||||
);
|
||||
});
|
||||
|
||||
return listFonts(options.paths.fonts).then((fonts) => {
|
||||
Object.assign(existingFonts, fonts);
|
||||
return app;
|
||||
});
|
||||
const fonts = await listFonts(options.paths.fonts);
|
||||
Object.assign(existingFonts, fonts);
|
||||
return app;
|
||||
};
|
||||
|
@ -37,9 +37,9 @@ import {
|
||||
fixTileJSONCenter,
|
||||
} from './utils.js';
|
||||
import {
|
||||
PMtilesOpen,
|
||||
GetPMtilesInfo,
|
||||
GetPMtilesTile,
|
||||
openPMtiles,
|
||||
getPMtilesInfo,
|
||||
getPMtilesTile,
|
||||
} from './pmtiles_adapter.js';
|
||||
import { renderOverlay, renderWatermark, renderAttribution } from './render.js';
|
||||
|
||||
@ -109,7 +109,7 @@ function createEmptyResponse(format, color, callback) {
|
||||
raw: {
|
||||
width: 1,
|
||||
height: 1,
|
||||
channels: channels,
|
||||
channels,
|
||||
},
|
||||
})
|
||||
.toFormat(format)
|
||||
@ -410,17 +410,17 @@ const respondImage = (
|
||||
if (mode === 'tile' && tileMargin === 0) {
|
||||
pool = item.map.renderers[scale];
|
||||
} else {
|
||||
pool = item.map.renderers_static[scale];
|
||||
pool = item.map.renderersStatic[scale];
|
||||
}
|
||||
pool.acquire((err, renderer) => {
|
||||
const mlglZ = Math.max(0, z - 1);
|
||||
const params = {
|
||||
zoom: mlglZ,
|
||||
center: [lon, lat],
|
||||
bearing: bearing,
|
||||
pitch: pitch,
|
||||
width: width,
|
||||
height: height,
|
||||
bearing,
|
||||
pitch,
|
||||
width,
|
||||
height,
|
||||
};
|
||||
|
||||
if (z === 0) {
|
||||
@ -468,14 +468,14 @@ const respondImage = (
|
||||
image.resize(width * scale, height * scale);
|
||||
}
|
||||
|
||||
const composite_array = [];
|
||||
const composites = [];
|
||||
if (overlay) {
|
||||
composite_array.push({ input: overlay });
|
||||
composites.push({ input: overlay });
|
||||
}
|
||||
if (item.watermark) {
|
||||
const canvas = renderWatermark(width, height, scale, item.watermark);
|
||||
|
||||
composite_array.push({ input: canvas.toBuffer() });
|
||||
composites.push({ input: canvas.toBuffer() });
|
||||
}
|
||||
|
||||
if (mode === 'static' && item.staticAttributionText) {
|
||||
@ -486,11 +486,11 @@ const respondImage = (
|
||||
item.staticAttributionText,
|
||||
);
|
||||
|
||||
composite_array.push({ input: canvas.toBuffer() });
|
||||
composites.push({ input: canvas.toBuffer() });
|
||||
}
|
||||
|
||||
if (composite_array.length > 0) {
|
||||
image.composite(composite_array);
|
||||
if (composites.length > 0) {
|
||||
image.composite(composites);
|
||||
}
|
||||
|
||||
const formatQuality = (options.formatQuality || {})[format];
|
||||
@ -521,7 +521,7 @@ const existingFonts = {};
|
||||
let maxScaleFactor = 2;
|
||||
|
||||
export const serve_rendered = {
|
||||
init: (options, repo) => {
|
||||
init: async (options, repo) => {
|
||||
maxScaleFactor = Math.min(Math.floor(options.maxScaleFactor || 3), 9);
|
||||
let scalePattern = '';
|
||||
for (let i = 2; i <= maxScaleFactor; i++) {
|
||||
@ -570,19 +570,10 @@ export const serve_rendered = {
|
||||
],
|
||||
z,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
return respondImage(
|
||||
options,
|
||||
item,
|
||||
z,
|
||||
tileCenter[0],
|
||||
tileCenter[1],
|
||||
0,
|
||||
0,
|
||||
tileSize,
|
||||
tileSize,
|
||||
scale,
|
||||
format,
|
||||
res,
|
||||
options, item, z, tileCenter[0], tileCenter[1], 0, 0, tileSize, tileSize, scale, format, res,
|
||||
);
|
||||
},
|
||||
);
|
||||
@ -638,35 +629,15 @@ export const serve_rendered = {
|
||||
options,
|
||||
transformer,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
const overlay = await renderOverlay(
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
paths,
|
||||
markers,
|
||||
req.query,
|
||||
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
return respondImage(
|
||||
options,
|
||||
item,
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
format,
|
||||
res,
|
||||
overlay,
|
||||
'static',
|
||||
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static',
|
||||
);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
@ -720,34 +691,15 @@ export const serve_rendered = {
|
||||
options,
|
||||
transformer,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
const overlay = await renderOverlay(
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
paths,
|
||||
markers,
|
||||
req.query,
|
||||
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
return respondImage(
|
||||
options,
|
||||
item,
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
format,
|
||||
res,
|
||||
overlay,
|
||||
'static',
|
||||
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static',
|
||||
);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
@ -853,35 +805,14 @@ export const serve_rendered = {
|
||||
const x = center[0];
|
||||
const y = center[1];
|
||||
|
||||
// prettier-ignore
|
||||
const overlay = await renderOverlay(
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
paths,
|
||||
markers,
|
||||
req.query,
|
||||
z, x, y, bearing, pitch, w, h, scale, paths, markers, req.query,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
return respondImage(
|
||||
options,
|
||||
item,
|
||||
z,
|
||||
x,
|
||||
y,
|
||||
bearing,
|
||||
pitch,
|
||||
w,
|
||||
h,
|
||||
scale,
|
||||
format,
|
||||
res,
|
||||
overlay,
|
||||
'static',
|
||||
options, item, z, x, y, bearing, pitch, w, h, scale, format, res, overlay, 'static',
|
||||
);
|
||||
} catch (e) {
|
||||
next(e);
|
||||
@ -906,25 +837,24 @@ export const serve_rendered = {
|
||||
return res.send(info);
|
||||
});
|
||||
|
||||
return listFonts(options.paths.fonts).then((fonts) => {
|
||||
Object.assign(existingFonts, fonts);
|
||||
return app;
|
||||
});
|
||||
const fonts = await listFonts(options.paths.fonts);
|
||||
Object.assign(existingFonts, fonts);
|
||||
return app;
|
||||
},
|
||||
add: async (options, repo, params, id, publicUrl, dataResolver) => {
|
||||
const map = {
|
||||
renderers: [],
|
||||
renderers_static: [],
|
||||
renderersStatic: [],
|
||||
sources: {},
|
||||
source_types: {},
|
||||
sourceTypes: {},
|
||||
};
|
||||
|
||||
let styleJSON;
|
||||
const createPool = (ratio, mode, min, max) => {
|
||||
const createRenderer = (ratio, createCallback) => {
|
||||
const renderer = new mlgl.Map({
|
||||
mode: mode,
|
||||
ratio: ratio,
|
||||
mode,
|
||||
ratio,
|
||||
request: async (req, callback) => {
|
||||
const protocol = req.url.split(':')[0];
|
||||
// console.log('Handling request:', req);
|
||||
@ -938,25 +868,24 @@ export const serve_rendered = {
|
||||
const parts = req.url.split('/');
|
||||
const fontstack = unescape(parts[2]);
|
||||
const range = parts[3].split('.')[0];
|
||||
getFontsPbf(
|
||||
null,
|
||||
options.paths[protocol],
|
||||
fontstack,
|
||||
range,
|
||||
existingFonts,
|
||||
).then(
|
||||
(concated) => {
|
||||
callback(null, { data: concated });
|
||||
},
|
||||
(err) => {
|
||||
callback(err, { data: null });
|
||||
},
|
||||
);
|
||||
|
||||
try {
|
||||
const concatenated = await getFontsPbf(
|
||||
null,
|
||||
options.paths[protocol],
|
||||
fontstack,
|
||||
range,
|
||||
existingFonts,
|
||||
);
|
||||
callback(null, { data: concatenated });
|
||||
} catch (err) {
|
||||
callback(err, { data: null });
|
||||
}
|
||||
} else if (protocol === 'mbtiles' || protocol === 'pmtiles') {
|
||||
const parts = req.url.split('/');
|
||||
const sourceId = parts[2];
|
||||
const source = map.sources[sourceId];
|
||||
const source_type = map.source_types[sourceId];
|
||||
const sourceType = map.sourceTypes[sourceId];
|
||||
const sourceInfo = styleJSON.sources[sourceId];
|
||||
|
||||
const z = parts[3] | 0;
|
||||
@ -964,8 +893,8 @@ export const serve_rendered = {
|
||||
const y = parts[5].split('.')[0] | 0;
|
||||
const format = parts[5].split('.')[1];
|
||||
|
||||
if (source_type === 'pmtiles') {
|
||||
let tileinfo = await GetPMtilesTile(source, z, x, y);
|
||||
if (sourceType === 'pmtiles') {
|
||||
let tileinfo = await getPMtilesTile(source, z, x, y);
|
||||
let data = tileinfo.data;
|
||||
let headers = tileinfo.header;
|
||||
if (data == undefined) {
|
||||
@ -999,7 +928,7 @@ export const serve_rendered = {
|
||||
|
||||
callback(null, response);
|
||||
}
|
||||
} else if (source_type === 'mbtiles') {
|
||||
} else if (sourceType === 'mbtiles') {
|
||||
source.getTile(z, x, y, (err, data, headers) => {
|
||||
if (err) {
|
||||
if (options.verbose)
|
||||
@ -1084,8 +1013,8 @@ export const serve_rendered = {
|
||||
createCallback(null, renderer);
|
||||
};
|
||||
return new advancedPool.Pool({
|
||||
min: min,
|
||||
max: max,
|
||||
min,
|
||||
max,
|
||||
create: createRenderer.bind(null, ratio),
|
||||
destroy: (renderer) => {
|
||||
renderer.release();
|
||||
@ -1160,7 +1089,7 @@ export const serve_rendered = {
|
||||
|
||||
const queue = [];
|
||||
for (const name of Object.keys(styleJSON.sources)) {
|
||||
let source_type;
|
||||
let sourceType;
|
||||
let source = styleJSON.sources[name];
|
||||
let url = source.url;
|
||||
if (
|
||||
@ -1181,10 +1110,10 @@ export const serve_rendered = {
|
||||
}
|
||||
|
||||
let inputFile;
|
||||
const DataInfo = dataResolver(dataId);
|
||||
if (DataInfo.inputfile) {
|
||||
inputFile = DataInfo.inputfile;
|
||||
source_type = DataInfo.filetype;
|
||||
const dataInfo = dataResolver(dataId);
|
||||
if (dataInfo.inputFile) {
|
||||
inputFile = dataInfo.inputFile;
|
||||
sourceType = dataInfo.fileType;
|
||||
} else {
|
||||
console.error(`ERROR: data "${inputFile}" not found!`);
|
||||
process.exit(1);
|
||||
@ -1197,10 +1126,10 @@ export const serve_rendered = {
|
||||
}
|
||||
}
|
||||
|
||||
if (source_type === 'pmtiles') {
|
||||
map.sources[name] = PMtilesOpen(inputFile);
|
||||
map.source_types[name] = 'pmtiles';
|
||||
const metadata = await GetPMtilesInfo(map.sources[name]);
|
||||
if (sourceType === 'pmtiles') {
|
||||
map.sources[name] = openPMtiles(inputFile);
|
||||
map.sourceTypes[name] = 'pmtiles';
|
||||
const metadata = await getPMtilesInfo(map.sources[name]);
|
||||
|
||||
if (!repoobj.dataProjWGStoInternalWGS && metadata.proj4) {
|
||||
// how to do this for multiple sources with different proj4 defs?
|
||||
@ -1245,7 +1174,7 @@ export const serve_rendered = {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
map.source_types[name] = 'mbtiles';
|
||||
map.sourceTypes[name] = 'mbtiles';
|
||||
|
||||
if (!repoobj.dataProjWGStoInternalWGS && info.proj4) {
|
||||
// how to do this for multiple sources with different proj4 defs?
|
||||
@ -1293,26 +1222,24 @@ export const serve_rendered = {
|
||||
}
|
||||
}
|
||||
|
||||
const renderersReadyPromise = Promise.all(queue).then(() => {
|
||||
// standard and @2x tiles are much more usual -> default to larger pools
|
||||
const minPoolSizes = options.minRendererPoolSizes || [8, 4, 2];
|
||||
const maxPoolSizes = options.maxRendererPoolSizes || [16, 8, 4];
|
||||
for (let s = 1; s <= maxScaleFactor; s++) {
|
||||
const i = Math.min(minPoolSizes.length - 1, s - 1);
|
||||
const j = Math.min(maxPoolSizes.length - 1, s - 1);
|
||||
const minPoolSize = minPoolSizes[i];
|
||||
const maxPoolSize = Math.max(minPoolSize, maxPoolSizes[j]);
|
||||
map.renderers[s] = createPool(s, 'tile', minPoolSize, maxPoolSize);
|
||||
map.renderers_static[s] = createPool(
|
||||
s,
|
||||
'static',
|
||||
minPoolSize,
|
||||
maxPoolSize,
|
||||
);
|
||||
}
|
||||
});
|
||||
await Promise.all(queue);
|
||||
|
||||
return renderersReadyPromise;
|
||||
// standard and @2x tiles are much more usual -> default to larger pools
|
||||
const minPoolSizes = options.minRendererPoolSizes || [8, 4, 2];
|
||||
const maxPoolSizes = options.maxRendererPoolSizes || [16, 8, 4];
|
||||
for (let s = 1; s <= maxScaleFactor; s++) {
|
||||
const i = Math.min(minPoolSizes.length - 1, s - 1);
|
||||
const j = Math.min(maxPoolSizes.length - 1, s - 1);
|
||||
const minPoolSize = minPoolSizes[i];
|
||||
const maxPoolSize = Math.max(minPoolSize, maxPoolSizes[j]);
|
||||
map.renderers[s] = createPool(s, 'tile', minPoolSize, maxPoolSize);
|
||||
map.renderersStatic[s] = createPool(
|
||||
s,
|
||||
'static',
|
||||
minPoolSize,
|
||||
maxPoolSize,
|
||||
);
|
||||
}
|
||||
},
|
||||
remove: (repo, id) => {
|
||||
const item = repo[id];
|
||||
@ -1320,7 +1247,7 @@ export const serve_rendered = {
|
||||
item.map.renderers.forEach((pool) => {
|
||||
pool.close();
|
||||
});
|
||||
item.map.renderers_static.forEach((pool) => {
|
||||
item.map.renderersStatic.forEach((pool) => {
|
||||
pool.close();
|
||||
});
|
||||
}
|
||||
|
@ -11,12 +11,12 @@ import { getPublicUrl } from './utils.js';
|
||||
|
||||
const httpTester = /^(http(s)?:)?\/\//;
|
||||
|
||||
const fixUrl = (req, url, publicUrl, opt_nokey) => {
|
||||
const fixUrl = (req, url, publicUrl) => {
|
||||
if (!url || typeof url !== 'string' || url.indexOf('local://') !== 0) {
|
||||
return url;
|
||||
}
|
||||
const queryParams = [];
|
||||
if (!opt_nokey && req.query.key) {
|
||||
if (req.query.key) {
|
||||
queryParams.unshift(`key=${encodeURIComponent(req.query.key)}`);
|
||||
}
|
||||
let query = '';
|
||||
@ -42,20 +42,10 @@ export const serve_style = {
|
||||
}
|
||||
// mapbox-gl-js viewer cannot handle sprite urls with query
|
||||
if (styleJSON_.sprite) {
|
||||
styleJSON_.sprite = fixUrl(
|
||||
req,
|
||||
styleJSON_.sprite,
|
||||
item.publicUrl,
|
||||
false,
|
||||
);
|
||||
styleJSON_.sprite = fixUrl(req, styleJSON_.sprite, item.publicUrl);
|
||||
}
|
||||
if (styleJSON_.glyphs) {
|
||||
styleJSON_.glyphs = fixUrl(
|
||||
req,
|
||||
styleJSON_.glyphs,
|
||||
item.publicUrl,
|
||||
false,
|
||||
);
|
||||
styleJSON_.glyphs = fixUrl(req, styleJSON_.glyphs, item.publicUrl);
|
||||
}
|
||||
return res.send(styleJSON_);
|
||||
});
|
||||
|
@ -141,11 +141,8 @@ function start(opts) {
|
||||
|
||||
// Load all available icons into a settings object
|
||||
startupPromises.push(
|
||||
new Promise((resolve) => {
|
||||
getFiles(paths.icons).then((files) => {
|
||||
paths.availableIcons = files;
|
||||
resolve();
|
||||
});
|
||||
getFiles(paths.icons).then((files) => {
|
||||
paths.availableIcons = files;
|
||||
}),
|
||||
);
|
||||
|
||||
@ -182,15 +179,15 @@ function start(opts) {
|
||||
item,
|
||||
id,
|
||||
opts.publicUrl,
|
||||
(StyleSourceId, protocol) => {
|
||||
(styleSourceId, protocol) => {
|
||||
let dataItemId;
|
||||
for (const id of Object.keys(data)) {
|
||||
if (id === StyleSourceId) {
|
||||
if (id === styleSourceId) {
|
||||
// Style id was found in data ids, return that id
|
||||
dataItemId = id;
|
||||
} else {
|
||||
const fileType = Object.keys(data[id])[0];
|
||||
if (data[id][fileType] === StyleSourceId) {
|
||||
if (data[id][fileType] === styleSourceId) {
|
||||
// Style id was found in data filename, return the id that filename belong to
|
||||
dataItemId = id;
|
||||
}
|
||||
@ -202,21 +199,21 @@ function start(opts) {
|
||||
} else {
|
||||
if (!allowMoreData) {
|
||||
console.log(
|
||||
`ERROR: style "${item.style}" using unknown file "${StyleSourceId}"! Skipping...`,
|
||||
`ERROR: style "${item.style}" using unknown file "${styleSourceId}"! Skipping...`,
|
||||
);
|
||||
return undefined;
|
||||
} else {
|
||||
let id =
|
||||
StyleSourceId.substr(0, StyleSourceId.lastIndexOf('.')) ||
|
||||
StyleSourceId;
|
||||
if (isValidHttpUrl(StyleSourceId)) {
|
||||
styleSourceId.substr(0, styleSourceId.lastIndexOf('.')) ||
|
||||
styleSourceId;
|
||||
if (isValidHttpUrl(styleSourceId)) {
|
||||
id =
|
||||
fnv1a(StyleSourceId) + '_' + id.replace(/^.*\/(.*)$/, '$1');
|
||||
fnv1a(styleSourceId) + '_' + id.replace(/^.*\/(.*)$/, '$1');
|
||||
}
|
||||
while (data[id]) id += '_'; //if the data source id already exists, add a "_" untill it doesn't
|
||||
//Add the new data source to the data array.
|
||||
data[id] = {
|
||||
[protocol]: StyleSourceId,
|
||||
[protocol]: styleSourceId,
|
||||
};
|
||||
|
||||
return id;
|
||||
@ -239,15 +236,15 @@ function start(opts) {
|
||||
item,
|
||||
id,
|
||||
opts.publicUrl,
|
||||
(StyleSourceId) => {
|
||||
function dataResolver(styleSourceId) {
|
||||
let fileType;
|
||||
let inputFile;
|
||||
for (const id of Object.keys(data)) {
|
||||
fileType = Object.keys(data[id])[0];
|
||||
if (StyleSourceId == id) {
|
||||
if (styleSourceId == id) {
|
||||
inputFile = data[id][fileType];
|
||||
break;
|
||||
} else if (data[id][fileType] == StyleSourceId) {
|
||||
} else if (data[id][fileType] == styleSourceId) {
|
||||
inputFile = data[id][fileType];
|
||||
break;
|
||||
}
|
||||
@ -256,7 +253,7 @@ function start(opts) {
|
||||
inputFile = path.resolve(options.paths[fileType], inputFile);
|
||||
}
|
||||
|
||||
return { inputfile: inputFile, filetype: fileType };
|
||||
return { inputFile, fileType };
|
||||
},
|
||||
),
|
||||
);
|
||||
@ -347,7 +344,7 @@ function start(opts) {
|
||||
result.push({
|
||||
version: styleJSON.version,
|
||||
name: styleJSON.name,
|
||||
id: id,
|
||||
id,
|
||||
url: `${getPublicUrl(
|
||||
opts.publicUrl,
|
||||
req,
|
||||
@ -633,9 +630,9 @@ function start(opts) {
|
||||
enableShutdown(server);
|
||||
|
||||
return {
|
||||
app: app,
|
||||
server: server,
|
||||
startupPromise: startupPromise,
|
||||
app,
|
||||
server,
|
||||
startupPromise,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ const getFontPbf = (allowedFonts, fontPath, name, range, fallbacks) =>
|
||||
}
|
||||
});
|
||||
|
||||
export const getFontsPbf = (
|
||||
export const getFontsPbf = async (
|
||||
allowedFonts,
|
||||
fontPath,
|
||||
names,
|
||||
@ -161,7 +161,8 @@ export const getFontsPbf = (
|
||||
);
|
||||
}
|
||||
|
||||
return Promise.all(queue).then((values) => glyphCompose.combine(values));
|
||||
const values = await Promise.all(queue);
|
||||
return glyphCompose.combine(values);
|
||||
};
|
||||
|
||||
export const listFonts = async (fontPath) => {
|
||||
|
Loading…
Reference in New Issue
Block a user