gpt4 book ai didi

javascript - 带有 tilelayer : the map appears to have a vertical offset? 的传单非地理 map

转载 作者:行者123 更新时间:2023-12-05 03:38:05 24 4
gpt4 key购买 nike

为了维护我为游戏社区选择的社区项目,我试图了解传单的工作原理。特别是,我正在尝试使用自定义图 block 服务显示非地理 map 。

根据传单文档以及一系列教程和 stackoverflow 答案,我能想到的最好的代码是以下代码。标记被添加到 [0,0] 和 [maxLat, maxLong] 以验证它们是否与 map 对齐(我试图在我的项目中解决的问题是它们不是):

<!DOCTYPE HTML>
<html lang="en">

<head>

<meta charset="utf-8">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<style>
#map { height: 1080px; width: 1920px; }
</style>

</head>

<body>

<div id="map"></div>

<script>
var yx = L.latLng;

var xy = function(x, y) {
if (L.Util.isArray(x)) {
return yx(x[1], x[0]);
}
return yx(y, x);
};


var minZoom = 0;
var maxZoom = 7;
var img = [
18475,
12791
];

L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
transformation: new L.Transformation(1 / 128, 0, 1 / 128, 0)
});

var bounds = [xy(0, 0), xy(img)];

var map = L.map("map", {
attributionControl: false,
crs: L.CRS.MySimple,
maxBounds: bounds,
minZoom: minZoom,
maxZoom: maxZoom
});

L.tileLayer('https://d1w6xpzk1h0aj5.cloudfront.net/kuban/{z}/{x}/{y}.png', {
bounds: bounds,
noWrap: true,
minZoom: minZoom,
maxZoom: maxZoom,
tms: true,
continuousWorld: false,
maxNativeZoom: 7
}).addTo(map);

map.fitBounds(bounds);

L.marker(L.latLng([ 0, 0 ])).addTo(map);
L.marker(L.latLng(xy(img))).addTo(map);
</script>

</body>

</html>

如果我在我的浏览器上打开它, map 会在所有缩放级别正确显示(即以正确的顺序提供图 block ,并且传单按预期拼接它们)。问题是 map 在垂直方向上偏离了中心,而标记虽然在水平方向上完全对齐,但在垂直方向上存在偏移。

这正是我在主项目中遇到的问题。

我做错了什么,为什么?

最佳答案

这里的问题是您的光栅图像以奇怪的方式平铺。

我坚信坐标原点是左下角,因为 0,0,0 瓦片是如何与左下角对齐的,在顶部和右侧留下空白:

z0 tiles

缩放级别 1 的图 block 也与左下角对齐:

z1 tiles

在缩放级别 2,事情变得有趣:

z2 tiles

现在,如果坐标的原点在左下角,则图 block 坐标的原点应该在左下角

事实并非如此。如果它,那么这将是一个 TMS 样式的 tilelayer,其中 tile Y 坐标“向上”,并且 Leaflet 需要具有定义边界的非无限 CRS,如 this question ,东西会起作用,每个人都会很高兴。

因此,换句话说:第 0 个(垂直)像素位于左下角,但第 0 个(垂直)图 block 位于左上角。

这种切片方式的一个值得注意的后果是最左上角的图 block 的左上角坐标随缩放级别而变化。

因此对于缩放级别 0 的图 block ,最上面图 block 的笛卡尔 Y 坐标是 2^15 = 32768,但 z1 是 2^14 = 16384。对于 z2 和 z3,它又是 16384,但对于 z4,它是 7*(2^11) = 14336,对于 z5,它是 13*(2^10) = 13312。在一般情况下,它是图像的高度 (12791) 填充到最接近的缩放级别的更高二次幂加 7(类似于... Math.pow(2,7+z) * Math.ceil( 12791/Math.pow(2,7+z) ),我相信。

处理这个(我能想到的)的最干净的 hack 是类似于 this other answer 的东西,比如

    var map = L.map("map", {

crs: L.CRS.Simple,
minZoom: -7,
maxZoom: 2
});

var tiles = L.tileLayer('https://d1w6xpzk1h0aj5.cloudfront.net/kuban/{z}/{x}/{y}.png', {
minZoom: -7,
maxNativeZoom: 0,
zoomOffset: 7
}).addTo(map);

tiles.getTileUrl = function(coords) {
if (coords.z === -7) {coords.y += 1}
if (coords.z === -6) {coords.y += 1}
if (coords.z === -5) {coords.y += 2}
if (coords.z === -4) {coords.y += 4}
if (coords.z === -3) {coords.y += 7}
if (coords.z === -2) {coords.y += 13}
if (coords.z === -1) {coords.y += 25}
if (coords.z === 0) {coords.y += 50}

return L.TileLayer.prototype.getTileUrl.bind(tiles)(coords);
}

我把它放在 working example, over here 中。


我强烈建议您以更明智的方式将图像切成小块

如果您的坐标系是笛卡尔坐标系,则切片图 block 的 gravity 应该在左下角(即空白区域应该在顶部和右侧),0-0 图 block 为任何给定的缩放级别都应该包含最底部和最左侧的像素。

同样,如果您的坐标系类似于屏幕(倒 Y 的笛卡尔坐标系,参见 this answer for an explainer ),则切片图 block 的重力应该在左上角(即空白空间应该在底部,右),并且任何给定缩放级别的 0-0 图 block 应该包含最左上角的像素。

如果瓷砖不以这种方式切片,事情会变得困惑(就像你的情况一样)。

关于javascript - 带有 tilelayer : the map appears to have a vertical offset? 的传单非地理 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69098129/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com