一、前言
最近在使用Leaflet时,有客户想实现在地图中通过点击地图中某个要素后,能自动全幅显示;通过另一篇博客我们知道,可以通过map.panBy和map.panTo移动地图,但这种方式还需要手动设置,将地图平移到给定的中心点和按给定像素数平移地图,从而实现交互移动地图的效果;那是否还有更方便简单的方式呢?下面我们一起来看下如何实现吧。
二、实现过程
在实现想要的效果前,我们需要先了解当前在Leaflet中有哪些方法能实现平移地图,能达到鼠标交互一段地图的目的;在原生Leaflet的API中我们可以看到,修改地图映射状态的方法除了panTo、panBy外,还有以下几个接口:
方法 | 描述 |
---|---|
setView | 使用给定的设置地图的视图(地理中心和缩放)动画选项 |
fitBounds | 设置包含给定地理边界的地图视图,并使用 最大缩放级别可能 |
flyTo | 设置地图视图(地理中心和缩放),执行平滑 平移缩放动画 |
flyToBounds | 使用平滑的动画(如 flyTo)设置地图视图, 但采用像 fitBounds 这样的 bounds 参数 |
2.1 方法使用说明
1、setView方法
//设置点位
var point= [lat, lng];
//把map定位到点位上,13为地图的级别,也可以直接marker.getLatLng()
map.setView(point, 13);
2、fitBounds方法
//设置边界范围
var bounds=L.latLngBounds([
[39.9031855750273, 116.39760275470988],
[39.88132436586913, 116.36142920205131]
])
//定位到指定的范围
map.fitBounds(bounds);
3、flyTo方法
//设置点位
var point= [lat, lng];
//把map定位到点位上,13为地图的级别,也可以直接marker.getLatLng()
map.flyTo(point, 13);
//设置定位的位置及级别
map.flyTo(resultLayer.getBounds().getCenter(), 14);
4、flyToBounds方法
//设置要定位到的范围
var polygon = new L.Rectangle(L.latLngBounds([
[39.9031855750273, 116.39760275470988],
[39.88132436586913, 116.36142920205131]
])).addTo(map);
//定位平移到指定的位置
map.flyToBounds(polygon.getBounds());
2.2 代码实现
通过上面描述的几个方法,我们可以得知使用flyToBounds方法更能满足点击要素自动居中显示的效果;那么接下来我们就看下通过代码怎么实现。
1、地图加载
map = L.map('map', {
preferCanvas: true,
crs: L.CRS.EPSG4326,
center: [0, 0],
minZoom: 1,
maxZoom: 18,
zoom: 2
});
new L.supermap.TiledMapLayer(url).addTo(map);
2、设置地图点击事件,获取点击坐标并构建几何查询
map.on("click", function (evt) {
var x = evt.latlng.lng;
var y = evt.latlng.lat;
if (x < -180.0 || x > 180.0 || y < -90 || y > 90) {
return;
}
point = new L.circleMarker([y, x]);
var param = new L.supermap.QueryByGeometryParameters({
queryParams: {name: "Countries@World.2"},
geometry: point
});
new L.supermap.QueryService(url).queryByGeometry(param, function (serviceResult) {
});
})
3、点击要素自动全幅显示
if(resultLayer!=undefined){
resultLayer.remove();
};
var result = serviceResult.result;
resultLayer = L.geoJSON(result.recordsets[0].features, {
onEachFeature: function (feature, layer) {
layer.bindPopup(resources.text_country + ":" + feature.properties.COUNTRY);
}
}).addTo(map);
map.flyToBounds(resultLayer.getBounds());
完整代码
var map, resultLayer, bounds, url = "http://localhost:8090/iserver/services/map-world/rest/maps/World";
map = L.map('map', {
preferCanvas: true,
crs: L.CRS.EPSG4326,
center: [0, 0],
minZoom: 1,
maxZoom: 18,
zoom: 2
});
map.on("click", function (evt) {
var x = evt.latlng.lng;
var y = evt.latlng.lat;
if (x < -180.0 || x > 180.0 || y < -90 || y > 90) {
return;
}
point = new L.circleMarker([y, x]);
var param = new L.supermap.QueryByGeometryParameters({
queryParams: {name: "Countries@World.2"},
geometry: point
});
new L.supermap.QueryService(url).queryByGeometry(param, function (serviceResult) {
if(resultLayer!=undefined){
resultLayer.remove();
};
var result = serviceResult.result;
resultLayer = L.geoJSON(result.recordsets[0].features, {
onEachFeature: function (feature, layer) {
layer.bindPopup(resources.text_country + ":" + feature.properties.COUNTRY);
}
}).addTo(map);
map.flyToBounds(resultLayer.getBounds());
});
})
new L.supermap.TiledMapLayer(url, {noWrap: true}).addTo(map);
三、效果展示
点击要素自动全幅显示
此外还可以使用数据服务,通过对数据集进行几何相交查询,实现上述效果,具体可看附件。