2018年5月21日月曜日

Leaflet 1.3 - 4-7 Zoom levels

4-7 Zoom levels

Zoom levels

Leaflet works with latitude, longitude 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 cartodbAttribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="http://cartodb.com/attributions">CartoDB</a>';

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

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


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

全地球は、幅256ピクセルと高さ256ピクセルのちょうど一つの画像ということに注意押してください:
(訳注:Web ブラウザが Firefox なら、表示されたマップを右クリックして、「ページの情報を表示」をクリックします。「ページ情報」ダイアログで「メディア」をクリックすると、「メディアプレビュー」に画像が表示されます。「名前をつけて保存」ボタンをクリックして保存ができます。


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分ビデオはトピックの良い入門です:

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
2の累乗

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ピクセルです。ズームレベル1にするとき、その幅と高さを2倍にし、そして、4つの256x256ピクセルの画像によって表示されます:

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):

各ズームレベルで、各タイルは4つに分割され、そして、そのサイズ(tileSize オプションによって与えられる縁の長さ)は2倍、面積は4倍、になります。(言い換えれば、世界の幅と高さは、256·2zoomlevel ピクセルです):
       
Zoom 0    Zoom 1    Zoom 2

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までタイルを提供します。これは、1タイルごとに2、3のシティブロックを見るのに十分です。


A note about 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度にパンするとき、どのようにスケールファクタが2倍になるかわかります。次の例は、これを自動的に実行するために javascript timeout を使用します:
L.control.scale().addTo(map);

setInterval(function(){
 map.setView([0, 0]);
 setTimeout(function(){
  map.setView([60, 0]);
 }, 2000);
}, 4000);



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:

この例では、timeout をズームレベル0と1の間を自動的に選択するために再び使用します:
setInterval(function(){
 map.setZoom(0);
 setTimeout(function(){
  map.setZoom(1);
 }, 2000);
}, 4000);



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
● flyTo(center, zoom), like setView but with a smooth animation
● zoomIn() / zoomIn(delta), zooms in delta zoom levels, 1 by default
● zoomOut() / zoomOut(delta), zooms out delta zoom levels, 1 by default
● setZoomAround(fixedPoint, zoom), sets the zoom level while keeping a point fixed (what scrollwheel zooming does)
● fitBounds(bounds), automatically calculates the zoom to fit a rectangular area on the map

● setView(center, zoom), マップの中心も設定します
● flyTo(center, zoom), setView に似ていますが滑らかなアニメーションです
● zoomIn() / zoomIn(delta), delta ズームレベルにズームインします, 初期値は1
● zoomOut() / zoomOut(delta), delta ズームレベルにズームアウトします, 初期値は1
● setZoomAround(fixedPoint, zoom), 固定された点を維持しながらズームレベルを設定します(スクロールホイールズーム機能)
● 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 (0, 1, 2, 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 0, 1, 2, and so on).

分数(端数)ズームはデフォルトにできません。それを可能にするために、map の 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 0, 0.5, 1, 1.5, 2, 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 0, 0.1, 0.2, 0.3, 0.4, and so on.

もし zoomSnap 後を 0.1 に設定するとマップの有効なズームレベルは0、0.1、0.2、0.3、0.4 などになります。

The following example uses a zoomSnap value of 0.25:

次の例は、0.25 の zoomSnap 値を使用します:
var map = L.map('map', {
 zoomSnap: 0.25
});


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 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 zoomSnap: the 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 から)ズームボタンを、または、キーボードの +/- キーを使用するとき、ズームを in/out するズームレベルの数をコントロールします。

For the mousewheel zoom, the wheelPxPerZoomLevel option controls how fast the mousewheel zooms in our(訳注:or[?]) out.

マウスホイールズームのために、wheelPxPerZoomLevel オプションは、マウスホイールがズームイン、または、アウトする速さをコントロールします。

Here is an example with zoomSnap set to zero:

これは、0 に設定された zoomSnap を使用した例です:
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)
● Use the zoom in/out buttons

● タッチスクリーンがあるならピンチズーム
● マウスホイールでズームをイン/アウト
● ボックスズームを実行(キーボードの shift キーを押しながらマウスをドラッグ)
● ズームン/アウトボタンを使用


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

それはこのチュートリアル締めくくります。では、マップでズームレベルを使ってみましょう。

全コード
<!DOCTYPE html>
<html>
 <head>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="./leaflet13/leaflet.css" />
  <script src="./leaflet13/leaflet.js"></script>
  <title>Zoom levels</title>
 </head>
 <body>
  <div id="map" style="width: 600px; height: 400px;"></div>
  <script>
   //The shape of the earth
   /*
   var map = L.map('map', {
    minZoom: 0,
    maxZoom: 0
   });
   */
   //A note about scale
   /*
   var map = L.map('map', {
    minZoom: 1,
    maxZoom: 1,
    dragging: false
   });
   */
   //Controlling the zoom
   /*
   var map = L.map('map', {
    minZoom: 0,
    maxZoom: 1
   });
   */
   //Fractional zoom 1
   /*
   var map = L.map('map', {
    zoomSnap: 0.25
    });
   */
   //Fractional zoom 2
   var map = L.map('map', {
    zoomDelta: 0.25,
    zoomSnap: 0
   });
   var cartodbAttribution = '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, © <a href="http://cartodb.com/attributions">CartoDB</a>';
   var positron = L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
    attribution: cartodbAttribution
   }).addTo(map);
   //A note about scale
   /*
   L.control.scale({maxWidth: 150}).addTo(map);

   setInterval(function(){
    map.setView([0, 0]);
    setTimeout(function(){
     map.setView([60, 0]);
    }, 2000);
   }, 4000);
   */
   //Controlling the zoom
   /*
   setInterval(function(){
    map.setZoom(0);
    setTimeout(function(){
     map.setZoom(1);
    }, 2000);
   }, 4000);
   */
   //Fractional zoom
   var ZoomViewer = L.Control.extend({
    onAdd: function(){
     var container= L.DomUtil.create('div');
     var gauge = L.DomUtil.create('div');
     container.style.width = '200px';
     container.style.background = 'rgba(255,255,255,0.5)';
     container.style.textAlign = 'left';
     map.on('zoomstart zoom zoomend', function(ev){
      gauge.innerHTML = 'Zoom level: ' + map.getZoom();
      })
     container.appendChild(gauge);
     return container;
    }
   });
   (new ZoomViewer).addTo(map);
   map.setView([0, 0], 0);
   //Fractional zoom 1
   // map.setZoom(0.8);
  </script>
 </body>
</html>

0 件のコメント: