最近公司计划研发一套智慧城市治理系统,需要对接iserver发布好的地图。不出意外,地图技术调研及选型的任务落到我的肩上。正好上个项目告一段落,住的社区也被封控了,我可以居家办公,集中精力完成这个任务。
首要问题是需要选择地图框架。在openlayers和leaflet之间,我倾向于leaflet,个人觉得leaflet文档及Api更加清晰易懂,且很多功能可以拿来即用,而openlayers往往要定制开发。尽管了解到这个系统需求十分复杂,但leaflet强大的扩展插件库可以充当我的稳固靠山。
Leaflet 是领先的用于移动友好交互式地图的开源 JavaScript 库。
参照官方文档(Leaflet官方文档),我搭建了个demo,于是有了这篇笔记。预计后续项目开发阶段的笔记也会记录于此。
一、初始化地图
1.index.html引入leaflet相关资源
1 | <!-- leaflet基础资源 --> |
2.初始化地图并加载底图
1 | const { L } = window; |
3.添加其他tiledMapLayer图层
1 | const layer = L.supermap.tiledMapLayer(layer, mapOptions); |
4.添加相关控件
1 | // 比例尺 |
5.地图监听事件
1 | map.on('zoom', (e) => { |
6.设置地图视口
1 | map.setView([50.5, 30.5], 5); |
7.更新地图
1 | map.invalidateSize(true); // 可用于地图容器大小变化,更新地图 |
二、操作地图
1.添加marker
1 | L.marker([50.5, 30.5]).addTo(map); |
2.添加多个marker
可以将marker放入layerGroup,添加到地图
1 | const arr = [ |
3.遍历并操作图层组中的所有layer
1 | myGroup.eachLayer((layer) => { |
4.地图清除图层
1 | map.removeLayer(layer); |
5.清除layerGroup的所有layer
1 | myGroup.clearLayers(); |
6.自定义清除图层通用方法,接收layerGroup类型的数组
1 | //清除图层通用方法 |
7.加载geoJSON数据
1 | const layer = L.geoJSON(data, { |
8.获取地图边界
1 | const boundRef = map.getBounds(); |
9.设置地图边界
1 | map.fitBounds(boundRef); |
10.添加线
1 | L.polyline( |
11.添加多边形区域
1 | const latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]; |
三、使用插件
1.点聚合
使用的是Leaflet.markercluster,传送门:Leaflet.markercluster。相关配置项可以参考这篇文章Leaflet聚合图层—Leaflet.markercluster。
使用步骤如下:
(1)引入插件
1 | <!-- 点聚合 --> |
(2)初始化聚合点图层
地图渲染后,调用initClusterLayer方法初始化聚合点图层
1 | let clusterLayer; |
定义聚合样式
1 | .customstyle { |
(3)添加标注点
1 | const layers = [marker1, marker2, marker2]; |
实际效果图如下(无地图底图):
(4)清除聚合点图层
可以调用上文的清除图层通用方法
1 | cleanMap([clusterLayer]); |
2.热力图
使用的是Leaflet.heat,传送门:Leaflet.heat
使用步骤如下:
(1)引入插件
1 | <!-- 热力图 --> |
(2)渲染热力图
1 | let heatLayer; |
实际效果图如下(无地图底图):
(3)判断是否存在热力图
1 | const bool = map.hasLayer(heatLayer); |
(4)清除热力图
1 | heatLayer && heatLayer.remove(); |
3.canvas标注点
在地图上添加大批量marker时,会出现严重的性能问题。打开控制台会发现每个标注点是独立的dom元素,造成了卡顿。可以引入Leaflet.Canvas-Markers插件,以Canvas的绘图方式绘制Marker,从而解决问题。
(1)引入插件
1 | <!-- 海量marker渲染优化 --> |
(2)初始化Canvas-Markers图层
1 | const canvasLayer = L.canvasIconLayer({}).addTo(map); |
(3)添加标注点
1 | canvasLayer.addMarker(marker); |
(4)批量添加标注点
1 | canvasLayer.addMarkers([marker1, marker2]); |
(5)清除Canvas-Markers图层
同样可以使用清除图层方法
1 | cleanMap([canvasLayer]); |
(6)问题:图标与地图缩放不同步
使用优化过的版本,参考链接:leaflet加载geojson数据_leaflet如何加载10万数据