Leaflet

一个开源并且对移动端友好的
交互式地图 JavaScript 库

← 教程

Zoom levels 缩放比例

Leaflet 适用于 latitude, longitudezoom level

较低的缩放比例意味着地图可以显示整个大陆,而较高的缩放比例意味着地图可以显示一个城市的细节。

要了解 zoom levels 工作原理,首先我们需要对 geodesy 进行基本介绍。

地球的形状

让我们来看一张缩放比例为零的简单地图:

var map = L.map('map', {
	minZoom: 0,
	maxZoom: 0
});

var cartodbAttribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://carto.com/attribution">CARTO</a>';

var positron = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
	attribution: cartodbAttribution
}).addTo(map);

map.setView([0, 0], 0);
查看单独示例。

请注意,整个地球只是一张图像,宽 256 像素,高 256 像素:

我们要明白的是:地球不是一个正方形。相反,地球有一个不规则的形状,可以近似于类似于球体的东西

所以我们假设地球大部分是圆的。为了使它平坦,我们在周围放了一个假想的圆柱体,展开它,然后将其切割成方形:

Usgs map mercator
This is called a "cylindrical map projection".

当然这并不是在平面上显示地球表面的唯一方法。 有数百种方法,每一种方法都有自己的优点和缺点。下面这段6分钟的视频很好的介绍了这个主题:

诸如大地测量、地图投影和坐标系之类的事情很难,非常难 (并且超出了本教程的范围)。假设地球是一个正方形并不总是正确的做法,但大多数情况下都可以正常工作,使事情变得更简单,并且允许 Leaflet(和其他地图库)变得更快。

Powers of two

现在,让我们假设世界是一个正方形:

当我们以0缩放级别表示世界时,它的宽度和高度为 256 像素。当我们进入缩放级别1时,它的宽度和高度加倍,可以用四个 256 像素 x 256 像素的图像表示:

在每个缩放级别,每个图块被分成四份,其大小(边的长度,由 tileSize 选项给出)加倍,使面积翻四倍 (换句话说,世界的宽度和高度都是 256·2zoomlevel 像素):

Zoom 0Zoom 1Zoom 2

这一直持续下去。大多数瓦片(Tile)服务提供最高缩放级别为 18 的磁贴,具体取决于它们的覆盖范围。这足以让每个瓦片(Tile)看到几个城市街区。

关于缩放比例的说明

使用圆柱投影的缺点之一是比例不恒定,测量距离或尺寸不可靠,特别是在低缩放级别时。

技术术语中,Leaflet 使用的圆柱投影是共形的(保留形状),但不是等距的(不保留距离),也不是等面积的 (不保留面积,因为赤道附近的东西看起来比它们小)。

通过在地图上添加 L.Control.Scale,并平移到赤道和北纬60°,我们可以看到比例尺是如何翻倍的。以下示例使用 javascript timeouts 自动执行此操作:

L.control.scale().addTo(map);

setInterval(function(){
	map.setView([0, 0]);
	setTimeout(function(){
		map.setView([60, 0]);
	}, 2000);
}, 4000);
查看单独示例。

L.Control.Scale 显示适用于地图中心点的比例。 在高缩放级别,比例尺的变化很小,并不明显。

控制地图缩放

Leaflet 地图有多种方法可以控制显示的缩放级别,但最明显的一种是 setZoom()。例如,map.setZoom(0); 将缩放级别设置 map0

这个例子再次使用超时在缩放级别01之间自动交替:

setInterval(function(){
	map.setZoom(0);
	setTimeout(function(){
		map.setZoom(1);
	}, 2000);
}, 4000);
查看单独示例。

请注意缩放级别 0 和 1 显示的图像与上一节中显示的图像是如何对应的!

其他设置缩放的方法有:

Fractional zoom(以分数为单位进行缩放,例如:0.1)

在 Leaflet 1.0.0 中引入的一个功能是 fractional zoom 的概念。 在这之前,地图的缩放级别只能是一个整数(012,等等), 但现在你可以使用小数,如1.51.25

默认情况下,分数缩放是禁用的。要启用它,请使用 [地图的 zoomSnap 选项](/reference.html#map-zoomsnap)。 zoomSnap 选项的默认值是 1(这意味着地图的缩放级别可以是 0)。 这意味着地图的缩放级别可以是 012,以此类推)。)

如果你把 “zoomSnap “的值设置为 “0.5”,那么地图的有效缩放级别为 将是 00.511.52,以此类推。

如果你设置的值是 “0.1”,地图的有效缩放级别将是 00.10.20.30.4,以此类推。

以下示例使用 zoomSnap0.25

var map = L.map('map', {
	zoomSnap: 0.25
});
查看单独示例。

如您所见,Leaflet 只会加载缩放级别 01 的图块,并根据需要缩放它们。

Leaflet 将 snap 缩放到最接近的有效级别。比如说: 如果你有 zoomSnap: 0.25,而你试图做 map.setZoom(0.8),缩放会 缩回到 0.75map.fitBounds(bounds) 在结束 触摸屏上的捏合缩放手势时也会发生同样的情况。

zoomSnap 可以设置为零。这意味着 Leaflet 将不会捕捉缩放级别。

还有涉及到另一个重要的地图选项 zoomSnapzoomDelta 选项。这控制了使用缩放按钮(默认为 L.Control.Zoom)或键盘中的+/-键时要放大/缩小的缩放级别。

对于鼠标滚轮缩放,该 wheelPxPerZoomLevel 选项控制鼠标滚轮放大或缩小的速度。

这是一个 zoomSnap 设置为零的示例:

var map = L.map('map', {
	zoomDelta: 0.25,
	zoomSnap: 0
});

尝试以下操作,看看缩放级别如何变化:

查看单独示例。

本教程到此结束。现在,在你的地图中使用缩放比例试试吧!