Leaflet 官方教程 Zoom levels 縮放級別

A deeper look into what zoom levels are.

本教程帶你深入瞭解縮放級別。

Zoom levels

縮放級別

Leaflet works with latitudelongitude and “zoom level”.

Leaflet包括經度、緯度以及"縮放級別"。

Lower zoom levels means that the map shows entire continents, while higher zoom levels means that the map can show details of a city.

低縮放級別地圖顯示大洲,到高縮放級別地圖可能會顯示城市細節。

To understand how zoom levels work, first we need a basic introduction to geodesy.

爲了弄清縮放級別,我們有必要先來介紹一些大地測量學的基礎知識。

The shape of the earth

地球的形狀

Let’s have a look at a simple map locked at zoom zero:

我們來看一下一個縮放級別鎖定爲0的簡單地圖。

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

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

    map.setView([0, 0], 0);

 
See this example stand-alone.

Notice that the “whole earth” is just one image, 256 pixels wide and 256 pixels high:

注意,“全世界”只有一張圖片,256*256像素大小:

Just to be clear: the earth is not a square. Rather, the earth is shaped like a weird potato that can be approximated to something similar to a sphere.

你要清楚:地球不是方的。事實上,地球形狀倒像個怪土豆,接近於球體。

GRACE globe animation 
Potato earth image by NASA/JPL/University of Texas Center for Space Research
 with help of the GRACE satellites.

So we assume that the earth is mosly round. To make it flat, we put an imaginary cylinder around, unroll it, and cut it so it looks square:

我們假設地球基本上是圓的。爲了讓它變成平的,我們用一個想象的圓柱套住它,然後展開,並進行切分,然後她看起來就是平的了。

Usgs map mercator 
This is called a "cylindrical map projection".
這被稱爲“圓柱投影”

This is not the only way of displaying the surface on the earth on a plane. There are hundreds of ways, each of them with its own advantages and disadvantages. The following 6-minute video is a nice introduction to the topic:

這並非在平面上展示地球表面的唯一方法。有上百種方法可以實現,每一種都有自己的優缺點。下面的6分鐘的視頻對此作了很好的介紹(視頻來自YouTube,看不了)。

Things like geodesy, map projections and coordinate systems are hard, very hard (and out of scope for this tutorial). Assuming that the earth is a square is not always the right thing to do, but most of the time works fine enough, makes things simpler, and allows Leaflet (and other map libraries) to be fast.

大地測量學、地圖投影、座標系統等知識都很難,很難(同時也超出了本教程的的範圍)。假設地球表面展開後是方的並不總是正確的,不過大部分情況下運行良好,這使問題變得簡單,讓Leaflet(以及其他地圖包)運行更快。

Powers of two

加倍的效果

For now, let’s just assume that the world is a square:

現在,我們只管假設世界是方的:

When we represent the world at zoom level zero, it’s 256 pixels wide and high. When we go into zoom level one, it doubles its width and height, and can be represented by four 256-pixel-by-256-pixel images:

我們展示0級世界地圖時,它是256*256像素大小。切換到1級別時,寬和高都變爲原來的兩倍,需要4個256*256像素圖片表示。

At each zoom level, each tile is divided in four, and its size (length of the edge, given by the tileSize option) doubles, quadrupling the area. (in other words, the width and height of the world is 256·2zoomlevel pixels):

在每一層級,每個切片都被一分爲四,其大小(邊的長度,有tileSize option給出)加倍,(屏幕像素)面積變爲原來的四倍。(也即:世界的長和寬爲256*2^zoomlevel 像素):

This goes on and on. Most tile services offer tiles up to zoom level 18, depending on their coverage. This is enough to see a few city blocks per tile.

這一特性在每個層級延續。有好些切片服務能夠提供到18級的切片,這取決於他們的規模。到18級就可以看清城市的街區了。

A note about scale

scale筆記

One of the disadvantages of using a cylindrical projection is that the scale is not constant, and measuring distances or sizes is not reliable, specially at low zoom levels.

圓柱投影的問題之一在於其比例尺不是一個常數,測量的距離和麪積都不可信,尤其是縮放級別較低時。

In technical terms, the cylindrical projection that Leaflet uses is conformal (preserves shapes), but not equidistant(does not preserve distances), and not equal-area (does not preserve areas, as things near the equator appear smaller than they are).

用行話來說就是,Leaflet使用的圓柱投影是等角的(保持形狀),但不是等距的(有長度變形),也不是等面積的(有面積變形,在赤道附近面積會變小)。

By adding a L.Control.Scale to a map, and panning to the equator and to 60° north, we can see how the scale factor doubles. The following example uses javascript timeouts to do this automatically:

爲地圖添加一個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);
 
See this example stand-alone.

L.Control.Scale shows the scale which applies to the center point of the map. At high zoom levels, the scale changes very little, and is not noticeable.

L.Control.Scale顯示地圖中心點位置的比例尺。在高縮放級別下,(拖動地圖)比例尺變化不明顯,不容易觀察出來。

Controlling the zoom

控制縮放

A leaflet map has several ways to control the zoom level shown, but the most obvious one is setZoom(). For example, map.setZoom(0); will set the zoom level of map to 0.

Leaflet 地圖有很多方式控制顯示級別,最常用的是方法setZoom()。例如,map.setZoom(0);會將地圖的縮放級別設置爲0。

This example again uses timeouts to alternate between zoom levels 0 and 1 automatically:

下面的例子同樣使用了setTimeout方法來控制縮放級別在0 和1 之間自動輪換:

    setInterval(function(){
        map.setZoom(0);
        setTimeout(function(){
            map.setZoom(1);
        }, 2000);
    }, 4000);
 
See this example stand-alone.

Notice how the images shown at zoom levels 0 and one correspond with the images shown in the previous section!

注意觀察0級和1級的圖片,與上一節展示的一致。

Other ways of setting the zoom are:

其他設置縮放級別的方法:

  • setView(center, zoom), which also sets the map center
  • setView(center, zoom),該方法可以同時設置地圖中心點座標
  • flyTo(center, zoom), like setView but with a smooth animation
  • flyTo(center,zoom),與setView類似,區別在於有一個平滑動畫效果
  • zoomIn() / zoomIn(delta), zooms in delta zoom levels, 1 by default
  • zoomIn()/zoomIn(delta),放大delta指定的縮放級別,delta默認值爲1
  • zoomOut() / zoomOut(delta), zooms out delta zoom levels, 1 by default
  • zoomOut()/zoomOut(delta),縮小delta 縮放級別,delta默認爲1
  • setZoomAround(fixedPoint, zoom), sets the zoom level while keeping a point fixed (what scrollwheel zooming does)
  • setZoomAround(fixedPoint, zoom),設置縮放級別,保持一個點座標不變(滾輪縮放就是這樣的)
  • fitBounds(bounds), automatically calculates the zoom to fit a rectangular area on the map
  • fitBounds(bounds),自動計算縮放級別,適配參數指定的矩形座標區域。

Fractional zoom

帶小數的縮放級別

A feature introduced in Leaflet 1.0.0 was the concept of fractional zoom. Before this, the zoom level of the map could be only an integer number (012, and so on); but now you can use fractional numbers like 1.5 or 1.25.

Leaflet 1.0.0引入了一個新特性帶小數的縮放級別。在此之前縮放級別只能是整數(0,1,2等等);現在可以使用小數了,例如1.5或者1.25。

Fractional zoom is disabled by default. To enable it, use the map’s zoomSnap option. The zoomSnap option has a default value of 1 (which means that the zoom level of the map can be 012, and so on).

小數縮放級別默認是禁用的。可以通過地圖的zoomSnap屬性啓用。zoomSnap屬性默認值爲1(這意味着縮放級別是0,1,2這樣的數)。

If you set the value of zoomSnap to 0.5, the valid zoom levels of the map will be 00.511.52, and so on.

如果將zoomSnap的值設爲0.5,縮放級別的有效值將會是0,0.5,1,1.5,2等等。

If you set a value of 0.1, the valid zoom levels of the map will be 00.10.20.30.4, and so on.

如果設置爲0.1,縮放級別的有效值會變爲0,0.1,0.2,0.3,0.4等等。

The following example uses a zoomSnap value of 0.25:

下面的例子中地圖zoomSnap屬性被設置爲0.25:

    var map = L.map('map', {
        zoomSnap: 0.25
    });
 
See this example stand-alone.

As you can see, Leaflet will only load the tiles for zoom levels 0 or 1, and will scale them as needed.

可以看到,Leaflet只會加載0,1級別的切片,並在其他非整數縮放級別將切片縮放展示。

Leaflet will snap the zoom level to the closest valid one. For example, if you have zoomSnap: 0.25 and you try to do map.setZoom(0.8), the zoom will snap back to 0.75. The same happens with map.fitBounds(bounds), or when ending a pinch-zoom gesture on a touchscreen.

Leaflet 會將縮放級別約束爲最接近的有效值。例如,如果你將zoomSnap設置爲0.25,並調用map.setZoom(0.8),縮放級別將被調整爲0.75。同樣的,當調用map.fitBounds(bounds)或在觸摸屏上通過手指縮放時zoomSnap都會起作用。

zoomSnap can be set to zero. This means that Leaflet will not snap the zoom level.

zoomSnap可以設置爲0,這意味着,Leaflet將不再約束縮放級別。

There is another important map option related to zoomSnapthe zoomDelta option. This controls how many zoom levels to zoom in/out when using the zoom buttons (from the default L.Control.Zoom) or the +/- keys in your keyboard.

還有一個與zoomSnap相關的重要的地圖屬性:zoomDelta屬性。該屬性控制 縮放控件(L.Control.Zoom)及鍵盤+/-鍵  每次縮放地圖的級別。

For the mousewheel zoom, the wheelPxPerZoomLevel option controls how fast the mousewheel zooms in or out.

對於滾輪縮放, wheelPxPerZoomLevel屬性控制管輪縮放的速度。

Here is an example with zoomSnap set to zero:

下面的例子中zoomSnap值爲0:

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

Try the following, and see how the zoom level changes:

嘗試下面的操作,觀察縮放級別的變化情況:

  • Pinch-zoom if you have a touchscreen
  • 通過手勢縮放,如果你的屏幕是觸摸屏。
  • Zoom in/out with your mousewheel
  • 通過鼠標滾輪縮放
  • Do a box zoom (drag with your mouse while pressing the shift key in your keyboard)
  • 框選縮放(按下shift鍵並拖拽鼠標)
  • Use the zoom in/out buttons
  • 通過縮放組件縮放。
 
See this example stand-alone.

That concludes this tutorial. Now play with your zoom levels in your maps!

教程結束,動手試試吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章