Leaflet 官方教程-Non-geographical maps 非地理地图

Not of this earth

Sometimes, maps do not represent things on the surface of the earth and, as such, do not have a concept of geographical latitude and geographical longitude. Most times this refers to big scanned images, such as game maps.

有时候,地图并不展示地球表面的物体,这种情况下也就没有地理坐标的概念。多数情况下涉及到展示一个大图片,例如游戏地图。

For this tutorial we’ve picked a starmap from Star Control II, a game that is now available as the open-source
project The Ur-Quan Masters
. These maps were made with a tool to read the open-source data files of
the game, and look like this:

在本教程中,我们挑选了一张来自Star Control II(开源游戏 The Ur-Quan Masters)的星图,这些地图是用工具读取游戏的开源数据文件制作的。像下面这样:



The game has a built-in square coordinate system, as can be seen in the corners. This will allow us to establish a coordinate system.

这款游戏内置了方形坐标系,从角上就可以看到。这使我们可以创建一个坐标系。



CRS.Simple

CRS stands for coordinate reference system, a term used by geographers to explain what
the coordinates mean in a coordinate vector. For example, [15, 60] represents a point in the Indian Ocean if using latitude-longitude on the earth, or the solar system Krueger-Z in our starmap.

CRS表示坐标参考系统,它是一个地理术语,用以表述坐标在坐标系中的意义。例如,[15, 60],在地球经纬度坐标系中,表示印度洋中的一个点,而在我们的星图的星系坐标系中则表示Krueger-Z
号星。

A Leaflet map has one CRS (and one CRS only), that can be changed when creating the map. For our game map we’ll use CRS.Simple, which represents a square grid:

Leaflet中每个地图都有一个坐标系(并且只有一个坐标系),可以在创建地图时修改地图的坐标系。在我们的游戏地图中我们会使用CRS.Simple,表示一个矩形格网:

var map = L.map('map', {
    crs: L.CRS.Simple
});

Then we can just add a L.ImageOverlay with the starmap image and its approximate bounds:

之后我们添加L.ImageOverlay并设置星图及其大概的像素范围参数。

var bounds = [[0,0], [1000,1000]];
var image = L.imageOverlay('uqm_map_full.png', bounds).addTo(map);

And show the whole map:

显示全图。

map.fitBounds(bounds);
 
See
this example stand-alone.
在独立页面中运行该示例

This example doesn’t quite work, as we cannot see the whole map after doing a fitBounds().

这个例子并没有按照预期的那样运行,调用fitBounds()方法之后我们并没有看到全图。

Common gotchas in CRS.Simple maps

CRS.Simple坐标系地图的常见易混淆点

In the default Leaflet CRS, CRS.Earth, 360 degrees of longitude are mapped to 256 horizontal pixels (at zoom level 0) and approximately 170 degrees of latitude are mapped to 256 vertical pixels (at zoom level
0).

在Leaflet默认的坐标系,CRS.Earth坐标系中,360度的经度投影到256个水平像素(在0缩放级别 ),大约170度的纬度被投影到256个垂直像素(在0 缩放级别)。

In a CRS.Simple, one horizontal map unit is mapped to one horizontal pixel, and idem with vertical. This means that the whole map is about 1000×1000 pixels big and won’t fit in our HTML container. Luckily,
we can set minZoom to values lower than zero:

在CRS.Simple坐标系中,一个水平地图单位投影到一个水平像素,垂直方向也一样。这意味着整个地图大小约为1000*1000像素,与HTML容器不匹配。不过,我们可以将minZoom设置为小于0的值:

var map = L.map('map', {
    crs: L.CRS.Simple,
    minZoom: -5
});

Pixels vs. map units

像素和地图单位

One common mistake when using CRS.Simple is assuming that the map units equal image pixels. In this case, the map covers 1000×1000 units, but the image is 2315×2315 pixels big. Different cases will call for one
pixel = one map unit, or 64 pixels = one map unit, or anything. Think in map units in a grid, and then add your layers (L.ImageOverlays, L.Markers
and so on) accordingly.

使用CRS.Simple时一个常见的错误是认为地图单位就是图片像素。在本例中,地图大小为1000*1000单位,但是图片大小为2315*2315像素大小。在不同的实例中,可能一像素=一地图单位,或者64像素=一地图单位,以及其他任意值。在坐标系中以地图单位来思考,按照地图单位来添加自己的图层(L.ImageOverlay,L.Marker等等)。

In fact, the image we’re using covers more than 1000 map units – there is a sizable margin. Measuring how many pixels there are between the 0 and 1000 coordinates, and extrapolating, we can have the right coordinate bounds for this image:

事实上,我们使用的图片覆盖范围超过1000地图单位-还有一个挺宽的边距。量一下0-1000坐标之间有多少像素,就可以计算出图片的正确坐标。

var bounds = [[-26.5,-25], [1021.5,1023]];
var image = L.imageOverlay('uqm_map_full.png', bounds).addTo(map);

While we’re at it, let’s add some markers:

然后,我们添加一些maker。

var sol = L.latLng([ 145, 175.2 ]);
L.marker(sol).addTo(map);
map.setView( [70, 120], 1);
 
See
this example stand-alone.在独立页面中运行该示例

This is not the LatLng you’re looking for

LatLng并非你想使用的类

You’ll notice that Sol is at coordinates [145,175] instead of [175,145], and the same happens with the map center. Coordinates in CRS.Simple take
the form of [y, x] instead of [x, y], in the same way Leaflet uses [lat, lng]instead of [lng,
lat]
.

Sol坐标为[145,175]而不是我们认为的 [175,145],地图中心点也是这样。CRS.Simple坐标系中,坐标样式为[y,
x]
而非 [x, y],同样的Leaflet 使用[lat, lng]([纬度,经度])而非 [lng,
lat]([经度,纬度])
.

(In technical terms, Leaflet prefers to use [northing,
easting]
 over [easting, northing] – the first coordinate in a coordinate pair points “north” and the second points “east”)

(在技术方面,Leaflet倾向于使用[南北,东西]而非[东西,南北]-第一个参数表示南北,第二个参数表示东西)

The debate about whether [lng, lat] or [lat, lng] or [y, x] or [x, y] is
not new, and there is no clear consensus
. This lack of consensus is why Leaflet has a class named L.LatLng instead of the more confusion-prone L.Coordinate.

使用[lng,lat]还是[lat,lng]或者[y,x] 或者[x,y]的争论并不新鲜,一直没有达成共识。由于缺乏共识,Leaflet使用L.LatLng类表示经纬度,而避免使用更有歧义的L.Coordinate。

If working with [y, x] coordinates with something named L.LatLng doesn’t make much sense to you, you can easily create wrappers for them:

使用名字为L.LatLng的[y, x]坐标很不直观,我们可以很方便的为其创建适配器:

var yx = L.latLng;

var xy = function(x, y) {
    if (L.Util.isArray(x)) {    // When doing xy([x, y]);
        return yx(x[1], x[0]);
    }
    return yx(y, x);  // When doing xy(x, y);
};

Now we can add a few stars and even a navigation line with [x, y] coordinates:

我们可以通过 [x, y] 坐标添加一些星星以及航线:

var sol      = xy(175.2, 145.0);
var mizar    = xy( 41.6, 130.1);
var kruegerZ = xy( 13.4,  56.5);
var deneb    = xy(218.7,   8.3);

L.marker(     sol).addTo(map).bindPopup(      'Sol');
L.marker(   mizar).addTo(map).bindPopup(    'Mizar');
L.marker(kruegerZ).addTo(map).bindPopup('Krueger-Z');
L.marker(   deneb).addTo(map).bindPopup(    'Deneb');

var travel = L.polyline([sol, deneb]).addTo(map);

The map looks pretty much the same, but the code is a bit more readable:

地图看起来和之前一样,但是代码可读性变得更好了:

 
See
this example stand-alone.在独立页面中运行该示例

转载自:https://blog.csdn.net/pyluyuan/article/details/77944844

You may also like...

退出移动版