Showing
1 changed file
with
44 additions
and
41 deletions
| ... | @@ -47,14 +47,6 @@ function sliceImageToTiles(image, bounds, zoomLevel) { | ... | @@ -47,14 +47,6 @@ function sliceImageToTiles(image, bounds, zoomLevel) { |
| 47 | tileStartY = Math.min(tileStartY, tileEndY); | 47 | tileStartY = Math.min(tileStartY, tileEndY); |
| 48 | tileEndY = Math.max(tileStartY, tileEndY); | 48 | tileEndY = Math.max(tileStartY, tileEndY); |
| 49 | 49 | ||
| 50 | - // console.warn(`瓦片编号: X(${tileStartX} -> ${tileEndX}), Y(${tileStartY} -> ${tileEndY})`); | ||
| 51 | - | ||
| 52 | - const cols = tileEndX - tileStartX + 1; | ||
| 53 | - const rows = tileEndY - tileStartY + 1; | ||
| 54 | - | ||
| 55 | - const tileWidth = imgWidth / cols; | ||
| 56 | - const tileHeight = imgHeight / rows; | ||
| 57 | - | ||
| 58 | const scaleFactor = 2; // 调高分辨率倍率 | 50 | const scaleFactor = 2; // 调高分辨率倍率 |
| 59 | 51 | ||
| 60 | canvas.width = tileSize * scaleFactor; | 52 | canvas.width = tileSize * scaleFactor; |
| ... | @@ -66,39 +58,50 @@ function sliceImageToTiles(image, bounds, zoomLevel) { | ... | @@ -66,39 +58,50 @@ function sliceImageToTiles(image, bounds, zoomLevel) { |
| 66 | 58 | ||
| 67 | let tileIndex = 0; // 瓦片索引,用来给每个瓦片命名 | 59 | let tileIndex = 0; // 瓦片索引,用来给每个瓦片命名 |
| 68 | 60 | ||
| 69 | - for (let x = 0; x < cols; x++) { | 61 | + // 计算每个瓦片的经纬度范围 |
| 70 | - for (let y = 0; y < rows; y++) { | 62 | + for (let tileX = tileStartX; tileX <= tileEndX; tileX++) { |
| 71 | - ctx.clearRect(0, 0, tileSize, tileSize); | 63 | + for (let tileY = tileStartY; tileY <= tileEndY; tileY++) { |
| 72 | - | 64 | + // 计算当前瓦片的经纬度范围 |
| 73 | - ctx.drawImage( | 65 | + const tileLonStart = tileX * 360 / Math.pow(2, zoomLevel) - 180; |
| 74 | - image, | 66 | + const tileLonEnd = (tileX + 1) * 360 / Math.pow(2, zoomLevel) - 180; |
| 75 | - x * tileWidth, y * tileHeight, tileWidth, tileHeight, // 源图像区域 | 67 | + const tileLatStart = Math.atan(Math.sinh(Math.PI * (1 - 2 * (tileY + 1) / Math.pow(2, zoomLevel)))) * 180 / Math.PI; |
| 76 | - 0, 0, tileSize, tileSize // 目标画布区域 | 68 | + const tileLatEnd = Math.atan(Math.sinh(Math.PI * (1 - 2 * tileY / Math.pow(2, zoomLevel)))) * 180 / Math.PI; |
| 77 | - ); | 69 | + |
| 78 | - | 70 | + // 计算图片在当前瓦片中的位置和尺寸 |
| 79 | - canvas.toBlob((blob) => { | 71 | + const tileImgX = (lonStart - tileLonStart) / (tileLonEnd - tileLonStart) * tileSize; |
| 80 | - if (!blob) { | 72 | + const tileImgY = (tileLatEnd - latEnd) / (tileLatEnd - tileLatStart) * tileSize; |
| 81 | - console.error("瓦片转换失败!"); | 73 | + const tileImgWidth = (lonEnd - lonStart) / (tileLonEnd - tileLonStart) * tileSize; |
| 82 | - return; | 74 | + const tileImgHeight = (latEnd - latStart) / (tileLatEnd - tileLatStart) * tileSize; |
| 83 | - } | 75 | + |
| 84 | - const tileX = tileStartX + x; | 76 | + ctx.clearRect(0, 0, tileSize * scaleFactor, tileSize * scaleFactor); |
| 85 | - const tileY = tileStartY + y; | 77 | + |
| 86 | - // console.warn(`保存瓦片: ${tileX}_${tileY}_${zoomLevel}.png`); | 78 | + // 根据图片在瓦片中的实际位置和尺寸绘制 |
| 87 | - // saveTile(blob, `${tileX}_${tileY}_${zoomLevel}.png`); | 79 | + ctx.drawImage( |
| 88 | - | 80 | + image, |
| 89 | - // 获取当前北京时间(UTC+8) | 81 | + 0, 0, imgWidth, imgHeight, // 源图像区域(使用完整图片) |
| 90 | - const beijingTime = dayjs().add(8, "hour").toDate(); | 82 | + tileImgX, tileImgY, tileImgWidth, tileImgHeight // 目标画布区域(保持实际位置和比例) |
| 91 | - | 83 | + ); |
| 92 | - // 使用 JSZip 将每个瓦片添加到压缩包中 | 84 | + |
| 93 | - zip.file(`${tileX}_${tileY}_${zoomLevel}.png`, blob, { date: beijingTime }); | 85 | + canvas.toBlob((blob) => { |
| 94 | - tileIndex++; | 86 | + if (!blob) { |
| 95 | - | 87 | + console.error("瓦片转换失败!"); |
| 96 | - // 如果所有瓦片都处理完,生成并下载压缩包 | 88 | + return; |
| 97 | - if (tileIndex === cols * rows) { | 89 | + } |
| 98 | - generateAndDownloadZip(zip, zoomLevel); | 90 | + |
| 99 | - } | 91 | + // 获取当前北京时间(UTC+8) |
| 100 | - }, "image/png", 1.0); | 92 | + const beijingTime = dayjs().add(8, "hour").toDate(); |
| 101 | - } | 93 | + |
| 94 | + // 使用 JSZip 将每个瓦片添加到压缩包中 | ||
| 95 | + zip.file(`${tileX}_${tileY}_${zoomLevel}.png`, blob, { date: beijingTime }); | ||
| 96 | + tileIndex++; | ||
| 97 | + | ||
| 98 | + // 如果所有瓦片都处理完,生成并下载压缩包 | ||
| 99 | + const totalTiles = (tileEndX - tileStartX + 1) * (tileEndY - tileStartY + 1); | ||
| 100 | + if (tileIndex === totalTiles) { | ||
| 101 | + generateAndDownloadZip(zip, zoomLevel); | ||
| 102 | + } | ||
| 103 | + }, "image/png", 1.0); | ||
| 104 | + } | ||
| 102 | } | 105 | } |
| 103 | } | 106 | } |
| 104 | // 经纬度转换为瓦片坐标 | 107 | // 经纬度转换为瓦片坐标 | ... | ... |
-
Please register or login to post a comment