fix: 512 tiles being wrong level for maplibre-js
Signed-off-by: Andrew Calcutt <acalcutt@techidiots.net>
This commit is contained in:
parent
90100e79d9
commit
5e8288cceb
2 changed files with 43 additions and 34 deletions
|
|
@ -108,6 +108,7 @@
|
||||||
for (tile_url in tile_urls) {
|
for (tile_url in tile_urls) {
|
||||||
L.tileLayer(tile_urls[tile_url], {
|
L.tileLayer(tile_urls[tile_url], {
|
||||||
tileSize: 512,
|
tileSize: 512,
|
||||||
|
zoomOffset: -1,
|
||||||
minZoom: tile_minzoom,
|
minZoom: tile_minzoom,
|
||||||
maxZoom: tile_maxzoom,
|
maxZoom: tile_maxzoom,
|
||||||
attribution: tile_attribution
|
attribution: tile_attribution
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,8 @@ const PATH_PATTERN =
|
||||||
/^((fill|stroke|width)\:[^\|]+\|)*(enc:.+|-?\d+(\.\d*)?,-?\d+(\.\d*)?(\|-?\d+(\.\d*)?,-?\d+(\.\d*)?)+)/;
|
/^((fill|stroke|width)\:[^\|]+\|)*(enc:.+|-?\d+(\.\d*)?,-?\d+(\.\d*)?(\|-?\d+(\.\d*)?,-?\d+(\.\d*)?)+)/;
|
||||||
const httpTester = /^(http(s)?:)?\/\//;
|
const httpTester = /^(http(s)?:)?\/\//;
|
||||||
|
|
||||||
const mercator = new SphericalMercator();
|
const mercator_256 = new SphericalMercator();
|
||||||
|
const mercator_512 = new SphericalMercator({size: 512});
|
||||||
const getScale = (scale) => (scale || '@1x').slice(1, 2) | 0;
|
const getScale = (scale) => (scale || '@1x').slice(1, 2) | 0;
|
||||||
|
|
||||||
mlgl.on('message', (e) => {
|
mlgl.on('message', (e) => {
|
||||||
|
|
@ -348,8 +349,8 @@ const calcZForBBox = (bbox, w, h, query) => {
|
||||||
|
|
||||||
const padding = query.padding !== undefined ? parseFloat(query.padding) : 0.1;
|
const padding = query.padding !== undefined ? parseFloat(query.padding) : 0.1;
|
||||||
|
|
||||||
const minCorner = mercator.px([bbox[0], bbox[3]], z);
|
const minCorner = mercator_256.px([bbox[0], bbox[3]], z);
|
||||||
const maxCorner = mercator.px([bbox[2], bbox[1]], z);
|
const maxCorner = mercator_256.px([bbox[2], bbox[1]], z);
|
||||||
const w_ = w / (1 + 2 * padding);
|
const w_ = w / (1 + 2 * padding);
|
||||||
const h_ = h / (1 + 2 * padding);
|
const h_ = h / (1 + 2 * padding);
|
||||||
|
|
||||||
|
|
@ -380,14 +381,6 @@ const respondImage = (
|
||||||
overlay = null,
|
overlay = null,
|
||||||
mode = 'tile',
|
mode = 'tile',
|
||||||
) => {
|
) => {
|
||||||
if (
|
|
||||||
Math.abs(lon) > 180 ||
|
|
||||||
Math.abs(lat) > 85.06 ||
|
|
||||||
lon !== lon ||
|
|
||||||
lat !== lat
|
|
||||||
) {
|
|
||||||
return res.status(400).send('Invalid center');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
Math.min(width, height) <= 0 ||
|
Math.min(width, height) <= 0 ||
|
||||||
|
|
@ -413,7 +406,15 @@ const respondImage = (
|
||||||
pool = item.map.renderersStatic[scale];
|
pool = item.map.renderersStatic[scale];
|
||||||
}
|
}
|
||||||
pool.acquire((err, renderer) => {
|
pool.acquire((err, renderer) => {
|
||||||
const mlglZ = Math.max(0, z - 1);
|
|
||||||
|
// For 512px tiles, use the actual maplibre-native zoom. For 256px tiles, use zoom - 1
|
||||||
|
let mlglZ
|
||||||
|
if (width === 512) {
|
||||||
|
mlglZ = Math.max(0, z);
|
||||||
|
} else {
|
||||||
|
mlglZ = Math.max(0, z - 1);
|
||||||
|
}
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
zoom: mlglZ,
|
zoom: mlglZ,
|
||||||
center: [lon, lat],
|
center: [lon, lat],
|
||||||
|
|
@ -423,12 +424,14 @@ const respondImage = (
|
||||||
height,
|
height,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (z === 0) {
|
// HACK(Part 1) to allow for zoom 0 256px images. (z - 1) used byt 256 tiles would be -1, which isn't support. Instead a double size image is requested from zoom 0 and it is later resized.
|
||||||
|
if (z === 0 && width === 256) {
|
||||||
params.width *= 2;
|
params.width *= 2;
|
||||||
params.height *= 2;
|
params.height *= 2;
|
||||||
}
|
}
|
||||||
|
// END HACK(Part 1)
|
||||||
|
|
||||||
if (z > 2 && tileMargin > 0) {
|
if (((z > 2 && width === 256) || (z > 1 && width === 512)) && tileMargin > 0) {
|
||||||
params.width += tileMargin * 2;
|
params.width += tileMargin * 2;
|
||||||
params.height += tileMargin * 2;
|
params.height += tileMargin * 2;
|
||||||
}
|
}
|
||||||
|
|
@ -449,12 +452,16 @@ const respondImage = (
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (z > 2 && tileMargin > 0) {
|
if (((z > 2 && width === 256) || (z > 1 && width === 512)) && tileMargin > 0) {
|
||||||
const [_, y] = mercator.px(params.center, z);
|
let y
|
||||||
let yoffset = Math.max(
|
let yoffset
|
||||||
Math.min(0, y - 128 - tileMargin),
|
if (width === 512) {
|
||||||
y + 128 + tileMargin - Math.pow(2, z + 8),
|
y = mercator_512.px(params.center, z)[1]
|
||||||
);
|
yoffset = Math.max(Math.min(0, y - 256 - tileMargin), y + 256 + tileMargin - Math.pow(2, z + 8));
|
||||||
|
} else {
|
||||||
|
y = mercator_256.px(params.center, z)[1]
|
||||||
|
yoffset = Math.max(Math.min(0, y - 128 - tileMargin), y + 128 + tileMargin - Math.pow(2, z + 8));
|
||||||
|
}
|
||||||
image.extract({
|
image.extract({
|
||||||
left: tileMargin * scale,
|
left: tileMargin * scale,
|
||||||
top: (tileMargin + yoffset) * scale,
|
top: (tileMargin + yoffset) * scale,
|
||||||
|
|
@ -463,10 +470,11 @@ const respondImage = (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z === 0) {
|
// HACK(Part 2) to allow for zoom 0 256px images. (z - 1) used byt 256 tiles would be -1, which isn't support. Instead a double size image is requested from zoom 0 and it is resized here.
|
||||||
// HACK: when serving zoom 0, resize the 0 tile from 512 to 256
|
if ((z === 0 && width === 256)) {
|
||||||
image.resize(width * scale, height * scale);
|
image.resize(width * scale, height * scale);
|
||||||
}
|
}
|
||||||
|
// END HACK(Part 2)
|
||||||
|
|
||||||
const composites = [];
|
const composites = [];
|
||||||
if (overlay) {
|
if (overlay) {
|
||||||
|
|
@ -564,13 +572,13 @@ export const serve_rendered = {
|
||||||
) {
|
) {
|
||||||
return res.status(404).send('Out of bounds');
|
return res.status(404).send('Out of bounds');
|
||||||
}
|
}
|
||||||
const tileCenter = mercator.ll(
|
|
||||||
[
|
let tileCenter
|
||||||
((x + 0.5) / (1 << z)) * (tileSize << z),
|
if (tileSize === 512) {
|
||||||
((y + 0.5) / (1 << z)) * (tileSize << z),
|
tileCenter = mercator_512.ll([((x + 0.5) / (1 << z)) * (tileSize << z),((y + 0.5) / (1 << z)) * (tileSize << z)],z);
|
||||||
],
|
} else {
|
||||||
z,
|
tileCenter = mercator_256.ll([((x + 0.5) / (1 << z)) * (tileSize << z),((y + 0.5) / (1 << z)) * (tileSize << z)],z);
|
||||||
);
|
}
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return respondImage(
|
return respondImage(
|
||||||
|
|
@ -615,7 +623,7 @@ export const serve_rendered = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformer = raw
|
const transformer = raw
|
||||||
? mercator.inverse.bind(mercator)
|
? mercator_256.inverse.bind(mercator)
|
||||||
: item.dataProjWGStoInternalWGS;
|
: item.dataProjWGStoInternalWGS;
|
||||||
|
|
||||||
if (transformer) {
|
if (transformer) {
|
||||||
|
|
@ -662,7 +670,7 @@ export const serve_rendered = {
|
||||||
let center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];
|
let center = [(bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2];
|
||||||
|
|
||||||
const transformer = raw
|
const transformer = raw
|
||||||
? mercator.inverse.bind(mercator)
|
? mercator_256.inverse.bind(mercator)
|
||||||
: item.dataProjWGStoInternalWGS;
|
: item.dataProjWGStoInternalWGS;
|
||||||
|
|
||||||
if (transformer) {
|
if (transformer) {
|
||||||
|
|
@ -758,7 +766,7 @@ export const serve_rendered = {
|
||||||
const format = req.params.format;
|
const format = req.params.format;
|
||||||
|
|
||||||
const transformer = raw
|
const transformer = raw
|
||||||
? mercator.inverse.bind(mercator)
|
? mercator_256.inverse.bind(mercator)
|
||||||
: item.dataProjWGStoInternalWGS;
|
: item.dataProjWGStoInternalWGS;
|
||||||
|
|
||||||
const paths = extractPathsFromQuery(req.query, transformer);
|
const paths = extractPathsFromQuery(req.query, transformer);
|
||||||
|
|
@ -790,8 +798,8 @@ export const serve_rendered = {
|
||||||
bbox[3] = Math.max(bbox[3], pair[1]);
|
bbox[3] = Math.max(bbox[3], pair[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bbox_ = mercator.convert(bbox, '900913');
|
const bbox_ = mercator_256.convert(bbox, '900913');
|
||||||
const center = mercator.inverse([
|
const center = mercator_256.inverse([
|
||||||
(bbox_[0] + bbox_[2]) / 2,
|
(bbox_[0] + bbox_[2]) / 2,
|
||||||
(bbox_[1] + bbox_[3]) / 2,
|
(bbox_[1] + bbox_[3]) / 2,
|
||||||
]);
|
]);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue