Leaflet中如何限制地图的拖动范围

一、背景

       在Leaflet默认的地图载模式中,假如没有对地图的一个范围进行限制,那就会带来一个问题,随着地图可以拖动,当地图往右拖动越多,每跨一屏(这里的一屏指地图投影后在页面上的平铺位置)经度会加360度。同理,如果往左边拖一屏,也是相应的嫌少-360度。这是目标点的一个定位问题。

        第二个问题是,假如我们在,[120.146484,29.649869]这个点标一个marker,你会发现,当拖动一屏后,它并没有在同一个位置也标上这个点。如果把此时的地图给用户看的话,肯定会产生一种错觉。

二、问题展示

      1、经度大于180度的场景

        使用鼠标拖拽地图到右边,使用鼠标选点展示坐标可以看到,此时坐标的经度468.984375,明显超出了正常经度的范围值。   

Leaflet中如何限制地图的拖动范围_第1张图片

      2、经度小于-180度的场景

        使用鼠标拖拽地图到左边,使用鼠标选点展示坐标可以看到,此时坐标的经度 -241.171875,明显超出了正常经度的范围值。 

Leaflet中如何限制地图的拖动范围_第2张图片

      3、marker标错

        使用如下代码进行一个marker的标定,你会发现,无论将地图往左边拖或者右边拖,地图上始终只有一个点。

L.marker([22.024546, 110.654297]).addTo(mymap)
		.bindPopup("Hello world!
我是一个提示框.").openPopup();

Leaflet中如何限制地图的拖动范围_第3张图片

 三、原因分析

        造成以上问题的原因是什么呢?众所周知,在地理信息系统中,对地理范围是有一个明确的定义的。经度范围是0-180°,纬度范围是0-90°。从0°经线算起,向东、向西各分作180°,以东的180°属于东经,习惯上用“百E”作代号,以西的180°属于西经,习惯上用“W”作代号。我们通常说的纬度度指的是大地纬度。其数值在0至90度之间。位于赤道以北的点的纬度叫北纬,记为N;位于赤道以南的点的纬度称南纬,记为S。为了研究问题方便,人们把纬度分问为低、 中、高纬度。0°~30°为低纬度, 30°~ 60°为中纬度, 60~90°为高答纬度。

Leaflet中如何限制地图的拖动范围_第4张图片

Leaflet中如何限制地图的拖动范围_第5张图片

        了解了上述的知识后就知道了解决上述问题的办法,只需要在Leaflet中定义地图时,限制以下地图的经纬度范围。

四、Leaflet API

      通过查找Leaflet的api我们发现了,在地图参数中有以下的定义:

Leaflet中如何限制地图的拖动范围_第6张图片

maxBounds LatLngBounds null When this option is set, the map restricts the view to the given geographical bounds, bouncing the user back if the user tries to pan outside the view. To set the restriction dynamically, use setMaxBounds method.

        默认的情况下,maxBounds参数设置为空。设置此选项后,地图会将视图限制在给定的地理范围内,如果用户试图在视图之外平移,则将用户弹回。要动态设置限制,请使用 setMaxBounds方法。通过这种方式就能限制地图的最大范围。

五、代码实现

1、leaflet资源引入


	经纬度投影-限制地图拖动范围
	
	
	
	
    

2、地图定义

L.CRS.CustomEPSG4326 = L.extend({}, L.CRS.Earth, {
		code: 'EPSG:4326',
		projection: L.Projection.LonLat,
		transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),
		scale: function (zoom) {
			return 256 * Math.pow(2, zoom - 1);
		}
	});

// 第一种设置方式,可行
//限制地图的拖动范围是正负90到正负180,这样才合理。
var corner1 =  L.latLng(-90, -180); //设置左上角经纬度
var corner2 = L.latLng(90, 180);	//设置右下点经纬度
var bounds = L.latLngBounds(corner1, corner2); //构建视图限制范
var mymap = L.map('mapid',{crs:L.CRS.CustomEPSG4326,maxBounds:bounds}).setView([29.052934, 104.0625], 5);

      这里的关键代码就是如下代码,通过这两个位置来限制拖动情况。地图的定义在crs这里,我使用了一个自己的转换规则,这取决你的瓦片读取方式。如果标准的WGS84投影,可以不需要这么定义,直接使用默认的方式加载即可。

var corner1 =  L.latLng(-90, -180); //设置左上角经纬度
var corner2 = L.latLng(90, 180);	//设置右下点经纬度
var bounds = L.latLngBounds(corner1, corner2); //构建视图限制范围

        除了使用这种初始定义的方式,还可以使用setMaxBounds(args)这种函数调用来进行,效果是一样的,调用代码:mymap.setMaxBounds(bounds);这种方式对控制显得更灵活方便。

3、完整代码实例




	经纬度投影-限制地图拖动范围
	
	
	
	
    


六、最终效果

       最终我们可以在界面上看到,当你想拖动地图到左边或者右边时,地图会默认弹回。这样就合理的避免了坐标太大超出范围的问题,以及点在地图上的标定问题。

你可能感兴趣的:(leaflet,js,gis,leaflet,地理可视化,gis)