chore: move nested respondImage() function to top level
Signed-off-by: Martin d'Allens <martin.dallens@liberty-rider.com>
This commit is contained in:
parent
2525b29cf4
commit
3437a653b3
1 changed files with 173 additions and 176 deletions
|
|
@ -352,6 +352,175 @@ const calcZForBBox = (bbox, w, h, query) => {
|
||||||
return z;
|
return z;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const respondImage = (
|
||||||
|
options,
|
||||||
|
item,
|
||||||
|
z,
|
||||||
|
lon,
|
||||||
|
lat,
|
||||||
|
bearing,
|
||||||
|
pitch,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
scale,
|
||||||
|
format,
|
||||||
|
res,
|
||||||
|
next,
|
||||||
|
opt_overlay,
|
||||||
|
opt_mode = 'tile',
|
||||||
|
) => {
|
||||||
|
if (
|
||||||
|
Math.abs(lon) > 180 ||
|
||||||
|
Math.abs(lat) > 85.06 ||
|
||||||
|
lon !== lon ||
|
||||||
|
lat !== lat
|
||||||
|
) {
|
||||||
|
return res.status(400).send('Invalid center');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
Math.min(width, height) <= 0 ||
|
||||||
|
Math.max(width, height) * scale > (options.maxSize || 2048) ||
|
||||||
|
width !== width ||
|
||||||
|
height !== height
|
||||||
|
) {
|
||||||
|
return res.status(400).send('Invalid size');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === 'png' || format === 'webp') {
|
||||||
|
} else if (format === 'jpg' || format === 'jpeg') {
|
||||||
|
format = 'jpeg';
|
||||||
|
} else {
|
||||||
|
return res.status(400).send('Invalid format');
|
||||||
|
}
|
||||||
|
|
||||||
|
const tileMargin = Math.max(options.tileMargin || 0, 0);
|
||||||
|
let pool;
|
||||||
|
if (opt_mode === 'tile' && tileMargin === 0) {
|
||||||
|
pool = item.map.renderers[scale];
|
||||||
|
} else {
|
||||||
|
pool = item.map.renderers_static[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,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (z === 0) {
|
||||||
|
params.width *= 2;
|
||||||
|
params.height *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z > 2 && tileMargin > 0) {
|
||||||
|
params.width += tileMargin * 2;
|
||||||
|
params.height += tileMargin * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.render(params, (err, data) => {
|
||||||
|
pool.release(renderer);
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
return res.status(500).header('Content-Type', 'text/plain').send(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix semi-transparent outlines on raw, premultiplied input
|
||||||
|
// https://github.com/maptiler/tileserver-gl/issues/350#issuecomment-477857040
|
||||||
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
const alpha = data[i + 3];
|
||||||
|
const norm = alpha / 255;
|
||||||
|
if (alpha === 0) {
|
||||||
|
data[i] = 0;
|
||||||
|
data[i + 1] = 0;
|
||||||
|
data[i + 2] = 0;
|
||||||
|
} else {
|
||||||
|
data[i] = data[i] / norm;
|
||||||
|
data[i + 1] = data[i + 1] / norm;
|
||||||
|
data[i + 2] = data[i + 2] / norm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const image = sharp(data, {
|
||||||
|
raw: {
|
||||||
|
width: params.width * scale,
|
||||||
|
height: params.height * scale,
|
||||||
|
channels: 4,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (z > 2 && tileMargin > 0) {
|
||||||
|
const [_, y] = mercator.px(params.center, z);
|
||||||
|
let yoffset = Math.max(
|
||||||
|
Math.min(0, y - 128 - tileMargin),
|
||||||
|
y + 128 + tileMargin - Math.pow(2, z + 8),
|
||||||
|
);
|
||||||
|
image.extract({
|
||||||
|
left: tileMargin * scale,
|
||||||
|
top: (tileMargin + yoffset) * scale,
|
||||||
|
width: width * scale,
|
||||||
|
height: height * scale,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z === 0) {
|
||||||
|
// HACK: when serving zoom 0, resize the 0 tile from 512 to 256
|
||||||
|
image.resize(width * scale, height * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
const composite_array = [];
|
||||||
|
if (opt_overlay) {
|
||||||
|
composite_array.push({ input: opt_overlay });
|
||||||
|
}
|
||||||
|
if (item.watermark) {
|
||||||
|
const canvas = renderWatermark(width, height, scale, item.watermark);
|
||||||
|
|
||||||
|
composite_array.push({ input: canvas.toBuffer() });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opt_mode === 'static' && item.staticAttributionText) {
|
||||||
|
const canvas = rendeAttribution(
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
scale,
|
||||||
|
item.staticAttributionText,
|
||||||
|
);
|
||||||
|
|
||||||
|
composite_array.push({ input: canvas.toBuffer() });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (composite_array.length > 0) {
|
||||||
|
image.composite(composite_array);
|
||||||
|
}
|
||||||
|
|
||||||
|
const formatQuality = (options.formatQuality || {})[format];
|
||||||
|
|
||||||
|
if (format === 'png') {
|
||||||
|
image.png({ adaptiveFiltering: false });
|
||||||
|
} else if (format === 'jpeg') {
|
||||||
|
image.jpeg({ quality: formatQuality || 80 });
|
||||||
|
} else if (format === 'webp') {
|
||||||
|
image.webp({ quality: formatQuality || 90 });
|
||||||
|
}
|
||||||
|
image.toBuffer((err, buffer, info) => {
|
||||||
|
if (!buffer) {
|
||||||
|
return res.status(404).send('Not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
res.set({
|
||||||
|
'Last-Modified': item.lastModified,
|
||||||
|
'Content-Type': `image/${format}`,
|
||||||
|
});
|
||||||
|
return res.status(200).send(buffer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const existingFonts = {};
|
const existingFonts = {};
|
||||||
let maxScaleFactor = 2;
|
let maxScaleFactor = 2;
|
||||||
|
|
||||||
|
|
@ -366,182 +535,6 @@ export const serve_rendered = {
|
||||||
|
|
||||||
const app = express().disable('x-powered-by');
|
const app = express().disable('x-powered-by');
|
||||||
|
|
||||||
const respondImage = (
|
|
||||||
item,
|
|
||||||
z,
|
|
||||||
lon,
|
|
||||||
lat,
|
|
||||||
bearing,
|
|
||||||
pitch,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
scale,
|
|
||||||
format,
|
|
||||||
res,
|
|
||||||
next,
|
|
||||||
opt_overlay,
|
|
||||||
opt_mode = 'tile',
|
|
||||||
) => {
|
|
||||||
if (
|
|
||||||
Math.abs(lon) > 180 ||
|
|
||||||
Math.abs(lat) > 85.06 ||
|
|
||||||
lon !== lon ||
|
|
||||||
lat !== lat
|
|
||||||
) {
|
|
||||||
return res.status(400).send('Invalid center');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
Math.min(width, height) <= 0 ||
|
|
||||||
Math.max(width, height) * scale > (options.maxSize || 2048) ||
|
|
||||||
width !== width ||
|
|
||||||
height !== height
|
|
||||||
) {
|
|
||||||
return res.status(400).send('Invalid size');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (format === 'png' || format === 'webp') {
|
|
||||||
} else if (format === 'jpg' || format === 'jpeg') {
|
|
||||||
format = 'jpeg';
|
|
||||||
} else {
|
|
||||||
return res.status(400).send('Invalid format');
|
|
||||||
}
|
|
||||||
|
|
||||||
const tileMargin = Math.max(options.tileMargin || 0, 0);
|
|
||||||
let pool;
|
|
||||||
if (opt_mode === 'tile' && tileMargin === 0) {
|
|
||||||
pool = item.map.renderers[scale];
|
|
||||||
} else {
|
|
||||||
pool = item.map.renderers_static[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,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (z === 0) {
|
|
||||||
params.width *= 2;
|
|
||||||
params.height *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (z > 2 && tileMargin > 0) {
|
|
||||||
params.width += tileMargin * 2;
|
|
||||||
params.height += tileMargin * 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer.render(params, (err, data) => {
|
|
||||||
pool.release(renderer);
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
return res
|
|
||||||
.status(500)
|
|
||||||
.header('Content-Type', 'text/plain')
|
|
||||||
.send(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix semi-transparent outlines on raw, premultiplied input
|
|
||||||
// https://github.com/maptiler/tileserver-gl/issues/350#issuecomment-477857040
|
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
|
||||||
const alpha = data[i + 3];
|
|
||||||
const norm = alpha / 255;
|
|
||||||
if (alpha === 0) {
|
|
||||||
data[i] = 0;
|
|
||||||
data[i + 1] = 0;
|
|
||||||
data[i + 2] = 0;
|
|
||||||
} else {
|
|
||||||
data[i] = data[i] / norm;
|
|
||||||
data[i + 1] = data[i + 1] / norm;
|
|
||||||
data[i + 2] = data[i + 2] / norm;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const image = sharp(data, {
|
|
||||||
raw: {
|
|
||||||
width: params.width * scale,
|
|
||||||
height: params.height * scale,
|
|
||||||
channels: 4,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (z > 2 && tileMargin > 0) {
|
|
||||||
const [_, y] = mercator.px(params.center, z);
|
|
||||||
let yoffset = Math.max(
|
|
||||||
Math.min(0, y - 128 - tileMargin),
|
|
||||||
y + 128 + tileMargin - Math.pow(2, z + 8),
|
|
||||||
);
|
|
||||||
image.extract({
|
|
||||||
left: tileMargin * scale,
|
|
||||||
top: (tileMargin + yoffset) * scale,
|
|
||||||
width: width * scale,
|
|
||||||
height: height * scale,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (z === 0) {
|
|
||||||
// HACK: when serving zoom 0, resize the 0 tile from 512 to 256
|
|
||||||
image.resize(width * scale, height * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
const composite_array = [];
|
|
||||||
if (opt_overlay) {
|
|
||||||
composite_array.push({ input: opt_overlay });
|
|
||||||
}
|
|
||||||
if (item.watermark) {
|
|
||||||
const canvas = renderWatermark(
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
scale,
|
|
||||||
item.watermark,
|
|
||||||
);
|
|
||||||
|
|
||||||
composite_array.push({ input: canvas.toBuffer() });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opt_mode === 'static' && item.staticAttributionText) {
|
|
||||||
const canvas = rendeAttribution(
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
scale,
|
|
||||||
item.staticAttributionText,
|
|
||||||
);
|
|
||||||
|
|
||||||
composite_array.push({ input: canvas.toBuffer() });
|
|
||||||
}
|
|
||||||
|
|
||||||
if (composite_array.length > 0) {
|
|
||||||
image.composite(composite_array);
|
|
||||||
}
|
|
||||||
|
|
||||||
const formatQuality = (options.formatQuality || {})[format];
|
|
||||||
|
|
||||||
if (format === 'png') {
|
|
||||||
image.png({ adaptiveFiltering: false });
|
|
||||||
} else if (format === 'jpeg') {
|
|
||||||
image.jpeg({ quality: formatQuality || 80 });
|
|
||||||
} else if (format === 'webp') {
|
|
||||||
image.webp({ quality: formatQuality || 90 });
|
|
||||||
}
|
|
||||||
image.toBuffer((err, buffer, info) => {
|
|
||||||
if (!buffer) {
|
|
||||||
return res.status(404).send('Not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
res.set({
|
|
||||||
'Last-Modified': item.lastModified,
|
|
||||||
'Content-Type': `image/${format}`,
|
|
||||||
});
|
|
||||||
return res.status(200).send(buffer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
app.get(
|
app.get(
|
||||||
`/:id/:z(\\d+)/:x(\\d+)/:y(\\d+):scale(${scalePattern})?.:format([\\w]+)`,
|
`/:id/:z(\\d+)/:x(\\d+)/:y(\\d+):scale(${scalePattern})?.:format([\\w]+)`,
|
||||||
(req, res, next) => {
|
(req, res, next) => {
|
||||||
|
|
@ -582,6 +575,7 @@ export const serve_rendered = {
|
||||||
z,
|
z,
|
||||||
);
|
);
|
||||||
return respondImage(
|
return respondImage(
|
||||||
|
options,
|
||||||
item,
|
item,
|
||||||
z,
|
z,
|
||||||
tileCenter[0],
|
tileCenter[0],
|
||||||
|
|
@ -664,6 +658,7 @@ export const serve_rendered = {
|
||||||
);
|
);
|
||||||
|
|
||||||
return respondImage(
|
return respondImage(
|
||||||
|
options,
|
||||||
item,
|
item,
|
||||||
z,
|
z,
|
||||||
x,
|
x,
|
||||||
|
|
@ -745,6 +740,7 @@ export const serve_rendered = {
|
||||||
req.query,
|
req.query,
|
||||||
);
|
);
|
||||||
return respondImage(
|
return respondImage(
|
||||||
|
options,
|
||||||
item,
|
item,
|
||||||
z,
|
z,
|
||||||
x,
|
x,
|
||||||
|
|
@ -879,6 +875,7 @@ export const serve_rendered = {
|
||||||
);
|
);
|
||||||
|
|
||||||
return respondImage(
|
return respondImage(
|
||||||
|
options,
|
||||||
item,
|
item,
|
||||||
z,
|
z,
|
||||||
x,
|
x,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue