前言

    因为业务上的需求,要使用Leaflet 制作地图,而本人从未接触过,经过几天的研究,算是入门成功

下载引入

    npm下载 npm install leaflet

    在main.js中引入

import "leaflet/dist/leafle.css" // 引入css 
import * as L from "leaflet"

Vue.prototype.$L= L

    下载源码 

    进入官网下载,点击download,然后选择一个下载就好了

leaflet tiles leaflet tilesystem_map

    CDN方式

<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>

使用

    1.首先我们创建一个简单的地图

     html模块 准备一个div容器

<div id="map" style="width: 100%; height: 100%;"></div>

     js模块

//初始化 地图
var mymap = L.map('map').setView([51.505, -0.09], 13); // setView(LatLng(当前位置),zoom(默认开始显示的聚焦值))

//将图层加载到地图上
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
	maxZoom: 18, // 最大的聚焦值
	attribution: 'Map data © <a                                 
    href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
	'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>', // 右下角展示的连接
	id: 'mapbox/streets-v11' // map样式
	}).addTo(mymap); // 添加挂载到mymap上

    这样一个简单的地图就出来了,接下来讲一讲地图中的标记以及一些配置项

    2.总结的一些map的option设置 

// 初始化
  var mymap = L.map('map',{
        attributionControl:false, // 移除右下角标记
        zoomControl:false, // 移除上面的加减号缩放
        dragging:false // 不允许鼠标拖拽
        doubleClickZoom:true, // 是否可以双击放大 'center' 无论点击哪里,都会以试图中心进行缩放
        zoomSnap:1, // 强制控制放大缩小的比例
        boxZoom:false // 是否允许按住shift键拖拽
        maxZoom: 16, // 地图最大缩放比例
        minZoom:2, // 地图最小缩放比例
        scrollWheelZoom:false // 是否能让鼠标滚轮缩放地图
        wheelDebounceTime:500, // 规定滚轮缩放的时间
        wheelPxPerZoomLevel:1 // 每滚动一下缩放的比例
      }).setView([51.505, -0.09], 13);

    3.绘制marker标记

L.marker([51.5, -0.09]).addTo(mymap)
		.bindPopup("<b>Hello world!</b><br />I am a popup.") // bindPopup点击后提示信息
        .openPopup(); // openPopup关闭上一个bindPopup信息默认打开

    设置marker的自定义icon属性 

    图标方式

var myIcon = L.icon({ // 当前位置标记的自定义图片图标
       iconUrl: require('../../assets/zaiban.png'), // 图片地址 在vue中导入图片地址的方式
       iconSize: [30, 30], // 图标大小 用x和y坐标(以像素为单位)表示一个点。通俗点,x(宽度)y(高度)
       iconAnchor: [20, 84], // 图标的偏移位置 如果不设置 默认为居中
       popupAnchor: [-2, -3], // 提示弹出窗口相对于icon的位置
       shadowUrl: 'my-icon-shadow.png', // 阴影图片的url
       shadowSize: [68, 95], // 阴影图片的大小
       shadowAnchor: [22, 94] // 阴影图片的偏移位置
    });
  L.marker([51.5, -0.09],{
     icon:myIcon, // 自定义图标标记
    }).addTo(mymap)
		.bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();

    标签方式

var myIcon = L.divIcon( // 当前位置标记的自定义div图标
      {
        iconSize: [50, 50], // 图标大小
        className: 'my-div-icon', // div的类名样式
        popupAnchor: [0, -15], // 提示弹出窗口相对于icon的位置
        html:'<p style="width: 100%;height: 100%;">你好你好你好</p>' // 插入html标签
       }
    );
L.marker([51.5, -0.09],{
  icon:myIcon, // 自定义图标标记
}).addTo(mymap)
	.bindPopup("<b>Hello world!</b><br />I am a popup.").openPopup();

    批量增加标记 layerGroup

let marker1 = L.marker([50, 50])
let marker2 = L.marker([50.001, 50.001])
L.layerGroup([marker1, marker2]).addTo(map);

    4.绘制圆形标记 circleMarker

var geojsonMarkerOptions = {
    radius: 8, // 圆形标记的大小
    fillColor: "#ff7800", // 背景颜色
    color: "#000", // 颜色
    weight: 1, // 宽度
    opacity: 1, // 边框的透明度
    fillOpacity: 0.8 // 背景的透明度
};

L.circleMarker([51.508, -0.11],geojsonMarkerOptions).addTo(mymap)

    5.绘制圆形区域 circle

L.circle([51.509, -0.12], {radius: 1000}).addTo(mymap);

    6.绘制三角形 polygon

L.polygon([ // 可以绘制多边形
          [51.509, -0.08],// 第一个坐标点
		  [51.503, -0.06],// 第二个坐标点
		  [51.51, -0.047] // 第三个坐标点
        ]).addTo(mymap).bindPopup("I am a polygon.") // 点击提示内容

    7.画线

L.polyline([[41.80, 123.43], [41.07, 123.00]], {opacity: 1,color: 'firebrick'}).bindPopup('I am red:').addTo(mymap);

    8.为地图添加事件

var popup = L.popup({ // 创建一个点击提示信息
          maxWidth:200, // 最大宽度
          minWidth:200, // 最小宽度
          maxHeight:300 // 最大高度 如果超出 则出现滚动条
     });

function onMapClick(e) { // 当点的时候所触发的函数 里面接收到的就是当前点击地理位置的相关信息
    popup
      .setLatLng(e.latlng) // 设置提示框出现的坐标
      .setContent(`<div style="background-color:red;height: 300px"> You clicked the map at ${e.latlng.toString()}</div>`)
       .openOn(mymap); // openOn关闭上一个提示信息 与openPopup相似
  }

mymap.on('click', onMapClick); // 添加地图点击事件
mymap.on('zoomend', onMapZoom) // 添加地图放大缩小监听事件;

    9.切换地图视野方法 flyTo

mymap.flyTo([35.717, 108.6333], 5, { animate: true, duration: 0.2 }); // 经纬度 zoom  animate开启缩放动画 duration时间

    10.GeoJSON 一种对地理数据结构进行编码的格式,类似于json,支持以下几何类型:点,线,面,多点,多线,多面和几何集

    绘制矩形 

// 画矩形
   var states = [{
        "type": "Feature",
        "properties": {"party": "Republican"}, // 当前标记所携带自定义的数据
         "geometry": {
            "type": "Polygon", // 类型
            "coordinates": [[
              [111.593628,24.507143],
              [100.107422,  28.304381],
              [115.900269,33.797409],
              [124.804688 , 27.683528],
              [111.593628,24.507143]
            ]]
          }
        },{
        "type": "Feature",
        "properties": {"party": "Democrat"}, // 当前标记所携带自定义的数据
         "geometry": {
            "type": "Polygon", // 类型
            "coordinates": [[
              [111.59362,24.50714],
              [100.10742,  28.30438],
              [115.90026,33.79740],
              [124.80468 , 27.68352],
              [111.59362,24.50714]
            ]]
          }
        }];

        this.marker =  L.geoJSON(states, {
          style: function(feature) { // 设置样式 里面得到的相当于states 
            switch (feature.properties.party) { // 根据不同的类型判断颜色
              case 'Republican': return {color: "#ff0000"};
              case 'Democrat':   return {color: "#0000ff"};
            }
          }
        }).addTo(mymap);

    绘制线段

var freeBus = {
          "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "geometry": {
                "type": "LineString", // 线段属性
                "coordinates": [
                  [-105.00341892242432, 39.75383843460583],
                  [-105.0008225440979, 39.751891803969535]
                ]
              },
              "properties": { // 自定义属性写在这里面
                "popupContent": "This is a free bus line that will take you across downtown.",
                "underConstruction": false
              },
              "id": 1
            },
            {
              "type": "Feature",
              "geometry": {
                "type": "LineString",
                "coordinates": [
                  [-105.0008225440979, 39.751891803969535],
                  [-104.99820470809937, 39.74979664004068]
                ]
              },
              "properties": {
                "popupContent": "This is a free bus line that will take you across downtown.",
                "underConstruction": true
              },
              "id": 2
            },
            {
              "type": "Feature",
              "geometry": {
                "type": "LineString",
                "coordinates": [
                  [-104.99820470809937, 39.74979664004068],
                  [-104.98689651489258, 39.741052354709055]
                ]
              },
              "properties": {
                "popupContent": "This is a free bus line that will take you across downtown.",
                "underConstruction": false
              },
              "id": 3
            }
          ]
        };
 L.geoJSON(freeBus, { // 创建线段
     filter: function (feature, layer) { // 过滤属性 配合 properties一 起使用
              if (feature.properties) {
              // If the property "underConstruction" exists and is true, return false (don't render features under construction)
              return feature.properties.underConstruction !== undefined ? !feature.properties.underConstruction : true;
            }
            return false;
      }
 }).addTo(map);

     增加标记 

var coorsField = {
          "type": "FeatureCollection",
          "features": [
            {
              "type": "Feature",
              "properties": {
                "popupContent": "Coors Field" // 点击提示文字
              },
              "geometry": {
                "type": "Point", // 配合 pointToLayer 一起使用
                "coordinates": [-104.99404191970824, 39.756213909328125]
              }
            },
          ]
        };
function onEachFeature(feature, layer) { // 为每一个标记添加点击提示 (该项的属性,标记)
      var popupContent = "<p>I started out as a GeoJSON " + feature.geometry.type + ", but now I'm a Leaflet vector!</p>";
      if (feature.properties && feature.properties.popupContent) { // 判断标记里面是否有内容
            popupContent += feature.properties.popupContent;  // 有则添加
       }
          layer.bindPopup(popupContent); // bind到该标记
}
var coorsLayer = L.geoJSON(coorsField, { // 创建 marker 标记
          pointToLayer: function (feature, latlng) {  // pointToLayer 可以配合标记一起使用
            return L.marker(latlng, {icon: baseballIcon}); // 除了marker 还可以配合circle 与 circleMarker
          },
          onEachFeature: onEachFeature // 添加公共的弹出层样式
 }).addTo(map);

    删除标记

mymap.removeLayer(coorsLayer)

   11.添加自定义控制器 control

var legend = L.control({position: 'bottomright'});
 legend.onAdd = function (map) {
    var div = L.DomUtil.create('div', 'info legend'), // 创建dom元素
     grades = [0, 10, 20, 50, 100, 200, 500, 1000], // 将要添加的内容
     labels = [],
     from, to;
    for (var i = 0; i < grades.length; i++) {
         from = grades[i];
         to = grades[i + 1];
         labels.push(
              `<i style="background: ${getColor(from+1)};display: block;height: 20px">${from + (to ? '–' + to : '+')}</i> `) // 添加每一行的dom
     }
     div.innerHTML = labels.join('');
     return div;
  };
  legend.addTo(map);

结语

    当然,leaflet 能实现的功能不仅限于此。leaflet 提供了可扩展的插件、控件等,在这里你能根据需求创作出你的个人工具,在这四方地图上绘制出你的美好愿景!