当前位置:   article > 正文

Leaflet聚合图层 Leaflet.markercluster 附源码以及中文文档、npm安装教程、Leaflet封装成组件(在摸索中前行)_leaflet中文文档

leaflet中文文档

文章底部附上全部源码

效果(有问题留言)

中文文档 

Leaflet.markercluster 中文文档 V1.5.4_冰樱湛蓝的博客-CSDN博客_leaflet中文文档

官网 

Documentation - Leaflet - 一个交互式地图 JavaScript 库

处理大量的标记

该插件可以处理10,000 甚至 50,000 个标记 (在chrome浏览器下). IE9 在 50,000 数量下会存在一些问题。

 

 如何使用

在你的页面的leaflet库引入处之后,引入本插件的css及js文件。你可以选择如下几种引入方式

  • 使用unpkg的CDN: https://unpkg.com/leaflet.markercluster@1.4.1/dist/
  • 通过npm命令安装: npm install leaflet.markercluster

这里我选择使用npm命令安装

main.js中引入

  1. // 引入 leaflet.markercluster 聚合插件
  2. import "leaflet.markercluster/dist/MarkerCluster.css"
  3. import "leaflet.markercluster/dist/MarkerCluster.Default.css"
  4. import "leaflet.markercluster";

HTML(因为我封装成了组件便于重复使用,所以用了父组件传值来动态设置高度,如不需要自行修改CSS)

<div id="map" :style="'height:'+ mapHeight"></div>

<script>下(为后续生成随机点做准备)

  1. //生成随机点
  2. const getRandomLatLng = map => {
  3. let bounds = map.getBounds(),
  4. southWest = bounds.getSouthWest(),
  5. northEast = bounds.getNorthEast(),
  6. lngSpan = northEast.lng - southWest.lng,
  7. latSpan = northEast.lat - southWest.lat;
  8. return L.latLng(
  9. southWest.lat + latSpan * Math.random(),
  10. southWest.lng + lngSpan * Math.random()
  11. );
  12. };

props 接收父组件传参(也包含默认值)

如果只需要聚合 复制如下就够了

  1. mapCenter: { //地图中心点
  2. type: Object,
  3. default: () => ({
  4. lat: 27.982965,
  5. lng: 120.754488
  6. })
  7. },
  8. mapHeight: { //高度
  9. type: String,
  10. default: 'calc(100vh - 50px)'
  11. },

扩展封装(Marker、多边形、圆形、线)

  1. markerList: { //Marker标记
  2. type: Array,
  3. default () {
  4. return [
  5. // {
  6. // lng: 120.74176311492921,
  7. // lat: 27.97600231947459,
  8. // bindPopup: '芜湖' //点击弹框
  9. // },
  10. ]
  11. }
  12. },
  13. polygonList: { //多边形绘制
  14. type: Object,
  15. default () {
  16. return {
  17. bindPopup: '我是多边形多边形多边形!~',
  18. layerTitle: '多边形', //图层名
  19. layerType: false, //是否以多图层形式
  20. latlng: [
  21. // {
  22. // lng: 120.7526206970215,
  23. // lat: 27.971056199299756,
  24. // },
  25. // {
  26. // lng: 120.7683277130127,
  27. // lat: 27.969085268308145,
  28. // },
  29. // {
  30. // lng: 120.7559680938720,
  31. // lat: 27.962793209235148,
  32. // }
  33. ]
  34. }
  35. }
  36. },
  37. circleList: { //圆形
  38. type: Object,
  39. default () {
  40. return {
  41. layerTitle: '圆形', //图层名
  42. layerType: false, //是否以多图层形式
  43. circle: [
  44. // {
  45. // color: '#000',
  46. // fillColor: '#00b4ff',
  47. // fillOpacity: 0.5, //不透明度
  48. // radius: 500, //半径
  49. // bindPopup: '第一园',
  50. // lat: 27.97164368137987,
  51. // lng: 120.7324504852295
  52. // }, {
  53. // color: '#fff',
  54. // fillColor: 'red',
  55. // fillOpacity: 0.5, //不透明度
  56. // radius: 500, //半径
  57. // bindPopup: '第二园',
  58. // lat: 27.973860923634668,
  59. // lng: 120.78257560729982
  60. // },
  61. ]
  62. }
  63. }
  64. },
  65. lineList: { //线
  66. type: Object,
  67. default () {
  68. return {
  69. layerTitle: '线', //图层名
  70. layerType: false, //是否以多图层形式
  71. circle: [
  72. /* {
  73. color: 'red',
  74. fillOpacity: 0.5, //不透明度
  75. bindPopup: '第一线',
  76. latlngs: [
  77. [27.974865300428114, 120.7456684112549],
  78. [27.975206407400496, 120.74957370758057],
  79. [27.976580299561842, 120.75139760971071],
  80. ]
  81. }, {
  82. color: '#000',
  83. fillOpacity: 0.5, //不透明度
  84. bindPopup: '第二线',
  85. latlngs: [
  86. [27.95634915407091, 120.75571060180665],
  87. [27.95926797966058, 120.77832698822023],
  88. [27.965560244261578, 120.7740354537964],
  89. ]
  90. }, */
  91. ]
  92. }
  93. }
  94. }

data(){}

  1. data() {
  2. return {
  3. map: '', //挂载
  4. mapIconLatlngData: [], //点击生成的经纬度
  5. dialogVisible: false,
  6. marker_group: [],
  7. mapMarkerType: false, //点击生成icon
  8. LatlngList: [], //循环生成固定icon的经纬度
  9. }
  10. }

methods()中

以下关键聚合代码

                //生图标模板  再按模板生成多个图标
                var transportIcon = L.Icon.extend({
                    options: {
                        iconSize: ['auto', 24],

                    }
                });
                var carIcon = new transportIcon({
                    iconUrl: require('./logo.png'), //这里图片地址要换成自己本地的
                })
                // 聚合
                var markers = L.markerClusterGroup();

                //生成多个随机点
                for (let i = 0; i < 1000; i++) {

                     //map传入  根据地图中心点随机生成附近经纬度
                    let latlng = getRandomLatLng(map); 

                     //将生成的 latlng 传入聚合
                    markers.addLayer(L.marker(latlng, {
                        icon: carIcon
                    }));
                }

                map.addLayer(markers)//将聚合添加到地图上

整个方法源码(复制可用)这里的方法我用了多图层的形式加载到图层中

  1. initDateNew() {
  2. const elem = this
  3. // 初始化地图 状态选项
  4. console.log(elem.mapCenter, '====')
  5. var map = L.map('map', {
  6. // center: [27.973768, 120.73438],
  7. center: [elem.mapCenter.lat, elem.mapCenter.lng],
  8. zoom: 14,
  9. attributionControl: false, // 移除右下角leaflet标识
  10. });
  11. // 多个图层切换
  12. var baseLayers = {
  13. '高德卫星': L.tileLayer('https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}', {
  14. maxZoom: 18
  15. }),
  16. "高德矢量": L.tileLayer.wms(
  17. 'http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}', {
  18. maxZoom: 18
  19. }).addTo(map),
  20. "外网矢量": L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  21. maxZoom: 18
  22. }),
  23. "腾讯地图": L.tileLayer(
  24. 'http://rt0.map.gtimg.com/realtimerender?z={z}&x={x}&y={-y}&type=vector&style=0', {
  25. maxZoom: 18
  26. }),
  27. };
  28. //多图层
  29. var overlays = {
  30. };
  31. // -----
  32. //生图标模板 再按模板生成多个图标
  33. var transportIcon = L.Icon.extend({
  34. options: {
  35. iconSize: ['auto', 24],
  36. }
  37. });
  38. var carIcon = new transportIcon({
  39. iconUrl: require('./logo.png'),
  40. })
  41. // 聚合
  42. var markers = L.markerClusterGroup();
  43. //生成多个点为
  44. for (let i = 0; i < 1000; i++) {
  45. let latlng = getRandomLatLng(map);
  46. markers.addLayer(L.marker(latlng, {
  47. icon: carIcon
  48. }));
  49. }
  50. // map.addLayer(markers);
  51. elem.markerList.forEach(a => {
  52. L.marker([a.lat, a.lng], {
  53. icon: carIcon
  54. }).bindPopup(a.bindPopup).addTo(map)
  55. })
  56. //把圆形添加到聚合中 也可注释不需要
  57. // 添加聚合方式 markers.addLayer(circle)
  58. var cities3 = L.layerGroup()
  59. if (elem.circleList.circle.length > 0) {
  60. elem.circleList.circle.forEach((a, index) => {
  61. var circle = L.circle([a.lat, a.lng], {
  62. color: a.color, //边框颜色
  63. fillColor: a.fillColor, //内部填充颜色
  64. fillOpacity: a.fillOpacity,
  65. radius: a.radius
  66. }).bindPopup(a.bindPopup).on('click', val => {
  67. map.pm.disableDraw("Polygon");
  68. // console.log('我都是',val)
  69. elem.dialogVisible = true
  70. })
  71. markers.addLayer(circle)
  72. })
  73. }
  74. overlays['聚合'] = markers
  75. //
  76. var bj = L.marker([elem.mapCenter.lat, elem.mapCenter.lng], {
  77. icon: new L.Icon({
  78. iconUrl: require('./logo.png'),
  79. iconSize: ['auto', 28],
  80. })
  81. }).bindPopup('中心点');
  82. // var sh = L.marker([31.213, 121.445]).bindPopup('这里是上海');
  83. // var gz = L.marker([23.16, 113.23]).bindPopup('这里是广州');
  84. var cities = L.layerGroup([bj]).addTo(map);
  85. // -----
  86. var cities2 = L.layerGroup(); //多边形
  87. // 多边形绘制 layerType
  88. if (elem.polygonList.latlng.length > 0) {
  89. if (elem.polygonList.layerType) {
  90. var polygon = L.polygon(elem.polygonList.latlng).bindPopup(elem.polygonList.bindPopup).addTo(
  91. cities2);
  92. overlays[elem.polygonList.layerTitle] = cities2
  93. } else {
  94. var polygon = L.polygon(elem.polygonList.latlng).bindPopup(elem.polygonList.bindPopup).addTo(map)
  95. }
  96. }
  97. // //圆形
  98. // var cities3 = L.layerGroup()
  99. // var cities3Circle = []
  100. // if (elem.circleList.circle.length > 0) {
  101. // elem.circleList.circle.forEach((a, index) => {
  102. // var circle = L.circle([a.lat, a.lng], {
  103. // color: a.color, //边框颜色
  104. // fillColor: a.fillColor, //内部填充颜色
  105. // fillOpacity: a.fillOpacity,
  106. // radius: a.radius
  107. // }).bindPopup(a.bindPopup).on('click', val => {
  108. // map.pm.disableDraw("Polygon");
  109. // // console.log('我都是',val)
  110. // elem.dialogVisible = true
  111. // })
  112. // cities3Circle.push(circle)
  113. // })
  114. // elem.marker_group = new L.layerGroup(cities3Circle).addTo(elem.circleList.layerType ? cities3 : map);
  115. // if (elem.circleList.layerType) {
  116. // overlays[elem.circleList.layerTitle] = cities3
  117. // }
  118. // }
  119. // cities3.clearLayers()
  120. // 创建折线
  121. var cities4 = L.layerGroup()
  122. if (elem.lineList.circle.length > 0) {
  123. elem.lineList.circle.forEach(a => {
  124. L.polyline(a.latlngs, {
  125. color: a.color,
  126. title: a.bindPopup,
  127. }).bindPopup(a.bindPopup).addTo(elem.lineList.layerType ? cities4 : map);
  128. })
  129. if (elem.lineList.layerType) {
  130. overlays[elem.lineList.layerTitle] = cities4
  131. }
  132. }
  133. var layerControl = L.control.layers(baseLayers, overlays, {
  134. position: 'bottomright',
  135. collapsed: false //是否折叠
  136. }).addTo(map);
  137. // L.clearLayers()
  138. // 线
  139. // removeLayer
  140. // map.fitBounds(polyline.getBounds()); //将地图的视图设置在给定的矩形地理范围内,地图会自动计算最大缩放级别和中心点
  141. // var layerControl = L.control.layers(baseLayers, overlays).addTo(map);
  142. //循环添加多个点
  143. // elem.LatlngList.forEach((a => {
  144. // L.marker([a.lat, a.lng], {
  145. // icon: new L.Icon({
  146. // className: "lmap-icon",
  147. // iconUrl: require('./logo.png'),
  148. // iconSize: [24, 24], // 图标尺寸
  149. // iconAnchor:[0,0] // 图标偏移
  150. // }),
  151. // title: '我是一个icon'
  152. // }).addTo(map);
  153. // }))
  154. // zoom the map to the polyline
  155. // console.log(getRandomLatLng(map), '+++++')
  156. //比列尺
  157. L.control.scale({
  158. imperial: false
  159. }).addTo(map);
  160. // //单机事件
  161. map.on('click', i => {
  162. // 点击获取地图上的经纬度
  163. // console.log(i, i.latlng.lng, i.latlng.lat)
  164. var latlng = {
  165. lng: i.latlng.lng,
  166. lat: i.latlng.lat
  167. }
  168. if (elem.mapMarkerType) {
  169. //存储点击icon 坐标
  170. elem.mapIconLatlngData.push(latlng)
  171. //点击处画icon
  172. L.marker([i.latlng.lat, i.latlng.lng], {
  173. icon: new L.Icon({
  174. className: "lmap-icon",
  175. iconUrl: require('./logo.png'),
  176. iconSize: ['auto', 24],
  177. })
  178. }).addTo(map);
  179. }
  180. //添加弹框
  181. // L.popup()
  182. // .setLatLng(latlng)
  183. // .setContent('单机弹框')
  184. // .openOn(map);
  185. // console.log(elem.mapIconLatlngData)
  186. })
  187. },

mounted(){}页面渲染后调用方法

  1. mounted() {
  2. this.initDateNew(); //正式
  3. }

右下角的聚合√要打上 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/234841
推荐阅读
相关标签
  

闽ICP备14008679号