在缩放级别计算每像素米的传单

Posted

技术标签:

【中文标题】在缩放级别计算每像素米的传单【英文标题】:Leaflet calculating meters per pixel at zoom level 【发布时间】:2015-02-17 03:40:08 【问题描述】:

我正在尝试确定一种方法来计算在 Leaflet 中给定缩放级别和地理中心点下 1 个像素表示的米数。任何人都可以指导我所涉及的数学,或者是否有办法在传单中开箱即用地做到这一点?我在那里找不到太多东西。

【问题讨论】:

【参考方案1】:

您可以使用L.Map 的containerPointToLatLng 转换函数来获取给定像素坐标的latLng 坐标。如果您取第一个像素中的一个和下一个像素,则可以使用L.LatLng 的distanceTo 实用方法来计算它们之间的距离(以米为单位)。见以下代码(假设 map 是 L.Map 的一个实例):

var centerLatLng = map.getCenter(); // get map center
var pointC = map.latLngToContainerPoint(centerLatLng); // convert to containerpoint (pixels)
var pointX = [pointC.x + 1, pointC.y]; // add one pixel to x
var pointY = [pointC.x, pointC.y + 1]; // add one pixel to y

// convert containerpoints to latlng's
var latLngC = map.containerPointToLatLng(pointC);
var latLngX = map.containerPointToLatLng(pointX);
var latLngY = map.containerPointToLatLng(pointY);

var distanceX = latLngC.distanceTo(latLngX); // calculate distance between c and x (latitude)
var distanceY = latLngC.distanceTo(latLngY); // calculate distance between c and y (longitude)

应该可以,感谢 Jarek Piórkowski 在编辑前指出我的错误。

【讨论】:

“我不知道你为什么提到中心点,因为无论你从哪里得到结果都是一样的。”不,他们不会。纬度和经度的长度因纬度而异,在大尺度上它会有所不同。您可以在例如csgnetwork.com/degreelenllavcalc.html 啊当然 :) 我知道,不知何故忘记了。我会编辑我的答案,非常感谢 这在缩小时对我有用,但在放大时失败 - distanceX 为零。选择 100 像素外的像素,然后将结果除以 100 似乎效果更好。我不知道这是否是一种有效的方法。【参考方案2】:

您可以使用它来计算每像素的米数:

metresPerPixel = 40075016.686 * Math.abs(Math.cos(map.getCenter().lat * Math.PI/180)) / Math.pow(2, map.getZoom()+8);

【讨论】:

很有意思,能再扩展一点吗?我很好奇 2^(zoom+8) 来自哪里,以及“缩放级别”数字是否独立于所使用的投影。我猜这个神奇的数字是地球赤道的长度。 只是为了确认:上面的答案似乎是正确的,我已经实现了 iH8 提供的解决方案和 sy​​nkyo 提供的解决方案,它们将相同的结果返回到小数点后 6 位。来源:wiki.openstreetmap.org/wiki/Zoom_levels 这里有更多补充说明:***.com/questions/30703212/… 我认为上面的意思是...Math.cos(map.getCenter().lat Math.PI/180))...而不是... Math.cos(map.getCenter().lat * 180/Math.PI))...,因为我们正在从度数转换为弧度。 传单开发人员 (Per Liedman) 告诉我,此方法仅适用于 EPSG:3857。【参考方案3】:

看看openstreetmap.org page on zoom levels。它给出了计算每像素米数的公式:

一个像素(S)表示的距离由下式给出

S=C*cos(y)/2^(z+8) 哪里...

C 是地球的(赤道)周长

z 是缩放级别

y 是您对比例感兴趣的纬度。

【讨论】:

传单开发人员 (Per Liedman) 告诉我,此方法仅适用于 EPSG:3857。【参考方案4】:

如果我错了,请纠正我,恕我直言,每像素的米数 = 以米为单位的地图高度/以像素为单位的地图高度

function metresPerPixel() 
    const southEastPoint = map.getBounds().getSouthEast();
    const northEastPoint = map.getBounds().getNorthEast();
    const mapHeightInMetres = southEastPoint.distanceTo(northEastPoint);
    const mapHeightInPixels = map.getSize().y;

    return mapHeightInMetres / mapHeightInPixels;

【讨论】:

以上是关于在缩放级别计算每像素米的传单的主要内容,如果未能解决你的问题,请参考以下文章

仅当使用 LayersControl 的缩放级别> 8 时,才在 Shiny 的传单地图中显示图层?

无论如何在谷歌地图上计算英里或米到像素以计算缩放级别?

在传单中获取WMS的最小缩放级别

带有自定义图块的传单地图上的标记位置随着更高的缩放级别而变化

如何在没有服务器支持的情况下使用传单放大浏览器

使用固定缩放和边界框导出传单地图而不填充