为什么投影与平铺的比例值不同?
Why the difference in scale values in projection vs. tile?
正在使用d3.geo.tile plugin, examples all have a difference between the scale of the map projection and the scale passed to the tile() function. In particular, tile_scale = projection_scale * 2 * Math.PI
. See examples here and here。
这个2*PI的乘法是什么意思?
一些 d3
投影,包括 d3.geo.mercator
(在这些示例中使用)具有自然比例,经度范围从 -π
到 π
:
var s = d3.geo.mercator().translate([0,0]).scale(1);
s([180, 0]); // [3.141592653589793, 0]
s([-180, 0]); // [-3.141592653589793, 0]
这是一个简单的默认比例,因为正如您在 d3.geo.mercator
投影 (Wikipedia formula), the projected x
value scales linearly with the longitude angle. This makes perfect sense if you think about the Web Mercator projection as unrolling and flattening a perfect sphere - 1 degree around the sphere's circumference is going to equal 1 unit of x
distance. So the D3 implementation doesn't scale longitude at all - it just returns it as the x
value (see code) 中看到的那样。经度以弧度输入到此函数,因此它具有从 -π
到 π
的自然范围,即描述圆周的 2π
角。
但要点是每个尺度的比例因子是 effectively arbitrary,并且在不同的投影中不一致。
所以基本上,2 * Math.PI
代表比例的最大范围,除以这个因子意味着将这个范围归一化为 1
以便于数学计算。
要理解为什么在使用 d3.geo.tile 插件时会有一个额外的因素 2π 应用于比例尺,了解两者之间的区别很重要d3.geoMercator()
使用的投影和绘制栅格图块时使用的投影。
D3
D3 使用以下公式实现标准 Mercator projection:
此投影使用以格林威治子午线为中心的单位圆半径 R = 1。到目前为止,没有缩放,也没有应用任何翻译。投影将从以下时间间隔产生输出值:
在 D3 v4 中,这是 implemented as
export function mercatorRaw(lambda, phi) {
return [lambda, log(tan((halfPi + phi) / 2))];
}
D3 v3 使用略有不同的符号,它更类似于上述公式,当然,等同于较新的实现:
function d3_geo_mercator(λ, φ) {
return [λ, Math.log(Math.tan(π / 4 + φ / 2))];
}
间隔的值经常被 d3.geo.mercator()
使用 translation and scaling 的默认值这一事实所掩盖。您必须明确地将它们设置为 .translate([0,0]).scale(1)
才能获得上述间隔。
瓷砖
另一方面,图块使用墨卡托投影的略微修改版本,称为 Web Mercator。相关公式为
该投影的核心是使用与标准墨卡托投影相同的计算。从上述等式右侧的黑色项可以很容易地看出这一点,这些项与墨卡托投影使用的项完全相同。只是通过应用一些缩放和平移来调整输出间隔以更好地适应屏幕显示的需要。
首先,对于南北纬度都超过
的情况,投影被截断
从而将整个地图投影到一个正方形上。之后进行了三个调整(根据上面等式中的颜色匹配):
- 将原点移至左上角(0, 0) — 蓝色调整π
- 将间隔标准化为 [0, 1] — 除以 2π 绿色
- 放大以适应 256 × 256 的区域 — 乘以红色的 256。
这将从间隔中产生输出值
这是所涉及的投影比例的差异,这就是为什么你需要乘以/除以 2π 的原因。如果要在同一张地图中同时使用 d3.geo.mercator()
和图块,则需要修改比例以相互匹配。
对标准墨卡托投影施加与 Web 墨卡托投影相同的纬度限制,最终得到以下间隔:
标准墨卡托投影
区间项目
具有 长度 = 2π.
Web 墨卡托投影
区间项目
具有 长度 = 256。
设置投影比例时已更正此问题
var projection = d3.geoMercator()
.scale((1 << 12) / 2 / Math.PI );
使用简单的求幂数学,比例因子可以重写为
(1 << 4) * (1 << 8) / 2 / Math.PI
进一步
(1 << 4) * 256 / ( 2 * Math.PI )
第一项 (1 << 4)
等于 24 这是要使用的实际缩放系数: 16。这将获得 zoom level 4 的图块。下学期
是调整比例的校正因子,其中包括 2π 你的问题。
正在使用d3.geo.tile plugin, examples all have a difference between the scale of the map projection and the scale passed to the tile() function. In particular, tile_scale = projection_scale * 2 * Math.PI
. See examples here and here。
这个2*PI的乘法是什么意思?
一些 d3
投影,包括 d3.geo.mercator
(在这些示例中使用)具有自然比例,经度范围从 -π
到 π
:
var s = d3.geo.mercator().translate([0,0]).scale(1);
s([180, 0]); // [3.141592653589793, 0]
s([-180, 0]); // [-3.141592653589793, 0]
这是一个简单的默认比例,因为正如您在 d3.geo.mercator
投影 (Wikipedia formula), the projected x
value scales linearly with the longitude angle. This makes perfect sense if you think about the Web Mercator projection as unrolling and flattening a perfect sphere - 1 degree around the sphere's circumference is going to equal 1 unit of x
distance. So the D3 implementation doesn't scale longitude at all - it just returns it as the x
value (see code) 中看到的那样。经度以弧度输入到此函数,因此它具有从 -π
到 π
的自然范围,即描述圆周的 2π
角。
但要点是每个尺度的比例因子是 effectively arbitrary,并且在不同的投影中不一致。
所以基本上,2 * Math.PI
代表比例的最大范围,除以这个因子意味着将这个范围归一化为 1
以便于数学计算。
要理解为什么在使用 d3.geo.tile 插件时会有一个额外的因素 2π 应用于比例尺,了解两者之间的区别很重要d3.geoMercator()
使用的投影和绘制栅格图块时使用的投影。
D3
D3 使用以下公式实现标准 Mercator projection:
此投影使用以格林威治子午线为中心的单位圆半径 R = 1。到目前为止,没有缩放,也没有应用任何翻译。投影将从以下时间间隔产生输出值:
在 D3 v4 中,这是 implemented as
export function mercatorRaw(lambda, phi) {
return [lambda, log(tan((halfPi + phi) / 2))];
}
D3 v3 使用略有不同的符号,它更类似于上述公式,当然,等同于较新的实现:
function d3_geo_mercator(λ, φ) {
return [λ, Math.log(Math.tan(π / 4 + φ / 2))];
}
间隔的值经常被 d3.geo.mercator()
使用 translation and scaling 的默认值这一事实所掩盖。您必须明确地将它们设置为 .translate([0,0]).scale(1)
才能获得上述间隔。
瓷砖
另一方面,图块使用墨卡托投影的略微修改版本,称为 Web Mercator。相关公式为
该投影的核心是使用与标准墨卡托投影相同的计算。从上述等式右侧的黑色项可以很容易地看出这一点,这些项与墨卡托投影使用的项完全相同。只是通过应用一些缩放和平移来调整输出间隔以更好地适应屏幕显示的需要。
首先,对于南北纬度都超过
的情况,投影被截断从而将整个地图投影到一个正方形上。之后进行了三个调整(根据上面等式中的颜色匹配):
- 将原点移至左上角(0, 0) — 蓝色调整π
- 将间隔标准化为 [0, 1] — 除以 2π 绿色
- 放大以适应 256 × 256 的区域 — 乘以红色的 256。
这将从间隔中产生输出值
这是所涉及的投影比例的差异,这就是为什么你需要乘以/除以 2π 的原因。如果要在同一张地图中同时使用 d3.geo.mercator()
和图块,则需要修改比例以相互匹配。
对标准墨卡托投影施加与 Web 墨卡托投影相同的纬度限制,最终得到以下间隔:
标准墨卡托投影
区间项目
具有 长度 = 2π.
Web 墨卡托投影
区间项目
具有 长度 = 256。
设置投影比例时已更正此问题
var projection = d3.geoMercator()
.scale((1 << 12) / 2 / Math.PI );
使用简单的求幂数学,比例因子可以重写为
(1 << 4) * (1 << 8) / 2 / Math.PI
进一步
(1 << 4) * 256 / ( 2 * Math.PI )
第一项 (1 << 4)
等于 24 这是要使用的实际缩放系数: 16。这将获得 zoom level 4 的图块。下学期
是调整比例的校正因子,其中包括 2π 你的问题。