hookehuyr

✨ feat: 最后切出来的图片,按照实际图片在瓦片的位置,而不是填充满瓦片的长宽

......@@ -47,14 +47,6 @@ function sliceImageToTiles(image, bounds, zoomLevel) {
tileStartY = Math.min(tileStartY, tileEndY);
tileEndY = Math.max(tileStartY, tileEndY);
// console.warn(`瓦片编号: X(${tileStartX} -> ${tileEndX}), Y(${tileStartY} -> ${tileEndY})`);
const cols = tileEndX - tileStartX + 1;
const rows = tileEndY - tileStartY + 1;
const tileWidth = imgWidth / cols;
const tileHeight = imgHeight / rows;
const scaleFactor = 2; // 调高分辨率倍率
canvas.width = tileSize * scaleFactor;
......@@ -66,14 +58,28 @@ function sliceImageToTiles(image, bounds, zoomLevel) {
let tileIndex = 0; // 瓦片索引,用来给每个瓦片命名
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
ctx.clearRect(0, 0, tileSize, tileSize);
// 计算每个瓦片的经纬度范围
for (let tileX = tileStartX; tileX <= tileEndX; tileX++) {
for (let tileY = tileStartY; tileY <= tileEndY; tileY++) {
// 计算当前瓦片的经纬度范围
const tileLonStart = tileX * 360 / Math.pow(2, zoomLevel) - 180;
const tileLonEnd = (tileX + 1) * 360 / Math.pow(2, zoomLevel) - 180;
const tileLatStart = Math.atan(Math.sinh(Math.PI * (1 - 2 * (tileY + 1) / Math.pow(2, zoomLevel)))) * 180 / Math.PI;
const tileLatEnd = Math.atan(Math.sinh(Math.PI * (1 - 2 * tileY / Math.pow(2, zoomLevel)))) * 180 / Math.PI;
// 计算图片在当前瓦片中的位置和尺寸
const tileImgX = (lonStart - tileLonStart) / (tileLonEnd - tileLonStart) * tileSize;
const tileImgY = (tileLatEnd - latEnd) / (tileLatEnd - tileLatStart) * tileSize;
const tileImgWidth = (lonEnd - lonStart) / (tileLonEnd - tileLonStart) * tileSize;
const tileImgHeight = (latEnd - latStart) / (tileLatEnd - tileLatStart) * tileSize;
ctx.clearRect(0, 0, tileSize * scaleFactor, tileSize * scaleFactor);
// 根据图片在瓦片中的实际位置和尺寸绘制
ctx.drawImage(
image,
x * tileWidth, y * tileHeight, tileWidth, tileHeight, // 源图像区域
0, 0, tileSize, tileSize // 目标画布区域
0, 0, imgWidth, imgHeight, // 源图像区域(使用完整图片)
tileImgX, tileImgY, tileImgWidth, tileImgHeight // 目标画布区域(保持实际位置和比例)
);
canvas.toBlob((blob) => {
......@@ -81,10 +87,6 @@ function sliceImageToTiles(image, bounds, zoomLevel) {
console.error("瓦片转换失败!");
return;
}
const tileX = tileStartX + x;
const tileY = tileStartY + y;
// console.warn(`保存瓦片: ${tileX}_${tileY}_${zoomLevel}.png`);
// saveTile(blob, `${tileX}_${tileY}_${zoomLevel}.png`);
// 获取当前北京时间(UTC+8)
const beijingTime = dayjs().add(8, "hour").toDate();
......@@ -94,7 +96,8 @@ function sliceImageToTiles(image, bounds, zoomLevel) {
tileIndex++;
// 如果所有瓦片都处理完,生成并下载压缩包
if (tileIndex === cols * rows) {
const totalTiles = (tileEndX - tileStartX + 1) * (tileEndY - tileStartY + 1);
if (tileIndex === totalTiles) {
generateAndDownloadZip(zip, zoomLevel);
}
}, "image/png", 1.0);
......