Leaflet创建图层的方式

主要使用的是栅格图层和GeoJson图层这两种图层

  • 在栅格图层里使用的是TileLayer.WMS

TileLayer.WMS的使用

官方文档里给我们介绍,这个方法有两个参数,第一个是路径,第二个是参数设置

 L.tileLayer.wms(`${this.layerUrl}/api/v1/geoserver/getwmts/`, {
          layers: 'db:geoserver_sarlayer',
          maxZoom: 24,
          transparent: 'true',
          version: '1.1.0',
          format: 'image/png',
        }).addTo(this.map);
选项说明
layers(必需)要显示的 WMS 图层的逗号分隔列表
maxZoom此图层将显示的最大缩放级别(包括最大)
transparent如果为 true,WMS 服务将返回具有透明度的图像
version要使用的 WMS 服务的版本
formatWMS 图像格式 (对具有透明度的图层使用 ‘image/png’ for layers with transparency)
version这个参数需要注意下,必须和你后端发图层服务的版本一样,我这里后端图层服务版本是1.1.0

GeoJSON 图层的使用 官方文档里给我们介绍,这个方法有两个参数,第一个是路径,第二个是参数设置

L.geoJSON(data, {配置项}).addTo(this.map);

选择类型违约描述
crsCRSL.CRS.EPSG3857要使用的坐标参考系。如果您不是,请不要更改此设置 确定这意味着什么。
centerLatLngundefined地图的初始地理中心
zoomNumberundefined初始地图缩放级别
minZoomNumber*地图的最小缩放级别。 如果未指定,并且地图中至少有一个网格图层或切片图层, 将改用他们最低的选项。minZoom
maxZoomNumber*地图的最大缩放级别。 如果未指定,并且地图中至少有一个网格图层或切片图层, 将改用他们最高的选项。maxZoom
layersLayer[][]最初将添加到地图的图层数组
maxBoundsLatLngBoundsnull设置此选项后,地图会将视图限制为给定的视图 地理边界,如果用户尝试平移,则会将用户弹回 视野外。若要动态设置限制,请使用 setMaxBounds 方法。
rendererRenderer*在地图上绘制矢量图层的默认方法。默认情况下为 L.SVG 或 L.Canvas,具体取决于浏览器支持。

添加标记、圆等图形

  //添加标记
  //图上添加一个标记
  var marker = L.marker([30.550317, 114.309043]).addTo(map);
 


  //添加矩形
  var circle = L.circle([30.570317, 114.319043], {
    color: 'red', //边框色
    fillColor: '#f03', //填充色
    fillOpacity: 0.5, //透明度
    radius: 500 //半径
  }).addTo(map);


添加弹窗

注意,当页面刷新时,会弹出最后渲染的弹窗

bindPopup(弹窗中内容,解析为html)

openPopup()打开弹窗

 //添加弹窗
  marker.bindPopup("<b>Hello world!</b><br>黄鹤楼边上.").openPopup();

有的时候,弹窗无需依附对象

但是要注意,需要最后渲染,否则渲染不出来,具体原因查看文档

页面显示弹窗位置,而不是设置的中心位置

 //弹窗
  // 弹出窗口用作图层,不依附与标记等对象
  //在这里我们使用而不是因为它在打开新弹出窗口时处理以前打开的弹出窗口的自动关闭,这对可用性有好处。openOnaddTo
  var popup = L.popup()
    .setLatLng([30.450317, 114.309043])
    .setContent("I am a standalone popup.")
    .openOn(map);

事件

 //处理事件

  //事件
   function onMapClick(e) { //e为对象,触发事件的对象
     alert("You clicked the map at " + e.latlng);
     console.log(e); //对象本身有很多可以使用的属性,如latlng是经纬度layerpoint当前点击位置等
   }

   map.on('click', onMapClick); //注册事件


  //一下代码实现在点击位置显示弹窗
  var popup = L.popup();

  function onMapClick(e) {
    popup
      .setLatLng(e.latlng) //给弹窗添加坐标
      .setContent("<b>Hello world!</b><br>You clicked the map at " + e.latlng.toString()) //弹窗内容,可以写html代码,能够渲染
      .openOn(map);
  }

  map.on('click', onMapClick);

  • 创建地图(map)
let map= L.map('map', {
  minZoom: 4,
  maxZoom: 17,
  zoom: 14,
  center: [37.632111, 114.91680237],
  attributionControl: false,
});

options选项

  • maxZoom:地图最大的缩放等级

  • minZoom:地图最小的缩放等级

  • zoom:地图默认的缩放等级

  • center:地图默认的中心点位置[纬度,经度]

  • attributionControl:是否将 attribution 版权控件添加到地图中

  • zoomControl:是否将zoom缩放控件添加到地图中

  • crs:地图使用的坐标系,默认使用的是EPSG3857坐标系

  • layers:添加到地图的图层

  • closePopupOnClick:用户点击图层时打开的弹框是否自动关闭

  • dragging:地图是否可以进行拖动,滑动

  • 添加图层(tileLayer)

let tileLayer = L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/.../',{
    maxZoom: 17,
    minZoom: 4,
}).addTo(map);   

创建标记(marker)

let marker = L.marker([纬度,经度], { icon: 图标 })

icon:将创建的标记改为一个图标 title:鼠标移动到标记上时显示的标记 opacity:标记的不透明度

注意: icon不定义就会使用leaflet自带的图标
  • 图标(icon/divIcon) icon图标:提供一个图片或图像代替标记
var myIcon = L.icon({
    iconUrl: 'my-icon.png',
    iconSize: [38, 95],
    iconAnchor: [22, 94],
    popupAnchor: [-3, -76],
    shadowUrl: 'my-icon-shadow.png',
    shadowSize: [68, 95],
    shadowAnchor: [22, 94]
});

option选项

iconUrl:图标图像的地址(URL) iconSize:图标图像的尺寸,单位为像素(number) className:设置一个class自定义图标的CSS属性 popupAnchor:弹出的窗口的坐标,相对于图标的描点而言,将在这里打开弹框 ([0,0]) iconAnchor:图标相对其左上角的坐标,默认情况下,图标的左上角是标记的位置([0,0])

  • divIcon图标:提供一个div元素作为图标代替标记
let divIcon = L.divIcon({
   html: `<div style="width:30px;height:30px;background:red;border- 
         radius:30px;text-align:center;line-height:30px;color:#ffffff">
         北京</div>`,
   className: 'icon',   // 图标父节点的class属性
   popupAnchor: [8, 2], // 弹出框(popup)的坐标,相对于图标描点而言,将从该点打开
});

html:自定义HTML代码,放入div元素内 divIcon继承icon的option选项

弹框(bindPopup)

marker.bindPopup("我是popup",options).openPopup(); options选项 maxWidth(最大宽度):弹出框的最大宽度。 minWidth(最小宽度):弹出框的最小宽度。 maxHeight(最大高度):设置后,如果内容超过弹出窗口的给定高度则产生一个可以滚动的容器。 autoPan(自动平移):如果你不想地图自动平移来适应打开的弹出框,就设置其为false。 closeButton(关闭按钮):设置弹出窗口中是否出现关闭按钮。 offset(补偿值):弹出窗口位置的补偿值。在同一图层中打开弹出窗口时对于控制锚点比较有用。 autoPanPadding(自动平移填补):在地图视图自动平移产生后弹出窗口和地图视图之间的边缘。 zoomAnimation:决定是否在所在级别上弹出窗口。如果你在弹出窗口中有flash内容的最好将其设置为不可用。 closeOnClick:默认为true,如果不想用户点击地图时弹框自动关闭,就请设置为false className:设置一个class自定义弹出窗口的CSS属性 方法 addTo:将弹出窗口添加到地图上。 openOn:将弹出窗口添加到地图上并将之前的一个关闭。与map.oenPopup(popup)方法相同。 setLatLng:设置弹出窗口打开的地理上的点位。 setContent:设置弹出窗口的HTML内容。

  • 工具提示(bindTooltip)

  • 使用示例

marker.bindTooltip("my tooltip text",options).openTooltip();
options选项
direction:打开tooltip的方向,可以为left,right,bottom,top,center,auto
permanent:是永久打开tooltip还是只在鼠标移动时打开
sticky:如果为true,tooltip将跟随鼠标移动,而不是固定在特征中心
opacity:tooltip的透明度

窗格(pane)

map.createPane('pane'); // 创建窗格
map.getPane('pane').style.zIndex = 999;  // 设置窗格的层级
var positronLabels = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_nolabels/{x}/{y}/{z}.png'),{
        attribution: '©OpenStreetMap, ©CartoDB',
        pane: 'labels'   // 绑定窗格
}).addTo(map);

常用方法和事件

  • 将给定的图层添加到地图中

map.addLayer(this.tileLayer);

  • 遍历所有图层然后删除
map.eachLayer(function (layer) {
    layer.remove();
})

// eachLayer()方法:遍历地图上所有图层

  • 删除地图上单个图层

map.removeLayer(layer)

  • 设置地图的中心点和层级

map.setView([lat: 30.890944, lng: 120.606944],10);

  • 获取地图当前缩放级别

map.getZoom();

  • 获取当前地图中心点

map.getCenter();

  • 设置地图的最小或最大缩放级别
map.setMinZoom(10);
map.setMaxZoom(16);
  • 判断地图上是否已存在某个图层

map.hasLayer(this.tileLayer);

leaflet限制地图拖动范围

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

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

地理信息系统

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

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);


var corner1 =  L.latLng(-90, -180); //设置左上角经纬度
var corner2 = L.latLng(90, 180);	//设置右下点经纬度
var bounds = L.latLngBounds(corner1, corner2); //构建视图限制范围
  • maxBounds参数设置为空。设置此选项后,地图会将视图限制在给定的地理范围内,如果用户试图在视图之外平移,则将用户弹回。

  • 要动态设置限制,请使用 setMaxBounds方法。通过这种方式就能限制地图的最大范围。

  • 你必须使用 bounds 作为 L.tileLayer 的选项,而不是 maxBounds.

You must use bounds as an option of L.tileLayer, and not maxBounds.

边界参考 另外,您似乎在 JSFiddle 中为 leaflet.css 加载了错误的文件,正确的来源是:http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css 最后,避免在 JSFiddle 中使用百分比大小,而是使用像素大小.这是一个有效的 JSFiddle:http://jsfiddle.net/1zyL4q4a/4/

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



 L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png' , {
            bounds: mybounds,
            maxZoom: 18,
            minZoom: 16 
   }).addTo(map);

vue leaflet

<template>
  <!-- <div>{{ ln }}</div> -->
  <div ref="map_doma"></div>
</template>
<script setup >
import L from "leaflet";
import "leaflet/dist/leaflet.css";

import { ref, onMounted } from "vue";
let map_doma = ref(null);
let ln = ref('')
onMounted(() => {

  //   L.Marker.prototype.options.icon = DefaultIcon;
  //   var wmsLayer= L.tileLayer.wms(
  //       "http://127.0.0.1:8880/geoserver/zxhy/wms", { // 链接要改对应的
  //           layers: 'zxhy:test',//需要加载的图层,就是我们刚刚新建的。map 和 图层名
  //           format: 'image/png',//返回的数据格式
  //           transparent: true
  //       }
  //   );
  // let wmsLayer = L.tileLayer(
  //   "http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}"
  // );

  let wmsLayer = L.tileLayer(
    "http://127.0.0.1/gda/{z}/{x}/{y}.png"
  );
  // https://plugins.qgis.org/plugins/QMetaTiles/
  /**
   Leaflet中有两种表示坐标点的数据结构,一种是最常用的LatLng,另一种是Point。
  
  LatLng是是描述经纬度的坐标类,代表具有一定纬度和经度的地理点。
  
  LatLng有三个属性: lat 纬度(以度为单位),lng 经度(以度为单位),和 alt 海拔高度(米)(可选


    {lat: Number, lng: Number, alt: Number}
  54.62266
  70.21749
   */

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

  // --------------------------------------------绘制经纬度网格线 Specify divisions every 10 degrees

  //   let map_dom = wmsLayer.addTo(map_doma.value);
  let map_dom = L.map(map_doma.value, {
    center: [36.421894, 114.214961],
    zoom: 5, // 初始化缩放
    layers: [wmsLayer],
    zoomControl: false,
    maxBounds: bounds,
    bounds: bounds,
    attributionControl: false,
  });
  L.control
    .zoom({
      zoomInTitle: "放大",
      zoomOutTitle: "缩小",
    })
    .addTo(map_dom);

/*
  var mousePositionControl = L.control({
    position: 'bottomleft'
  });
  mousePositionControl.onAdd = function (map) {
    var div = L.DomUtil.create('div', 'mouse-position');
    div.innerHTML = '经度: ' + 0 + ' 纬度: ' + 0;
    return div;
  };
  mousePositionControl.updatePosition = function ({ latlng }) {
    var lat = latlng.lat.toFixed(5);
    var lng = latlng.lng.toFixed(5);
    this._container.innerHTML = '经度: ' + lng + ' 纬度: ' + lat;

    // lnd.innerHTML= '经度: ' + lng + ' 纬度: ' + lat;
  };
  mousePositionControl.addTo(map_dom);


  map_dom.on('mousemove', function (latlng) {
    // 在此处编写获取经纬度和显示的代码
    mousePositionControl.updatePosition(latlng);

  });

  */
  
    L.polyline(
      [
        [36.433698, 114.21603],
        [36.427757, 114.231931],
        [36.435255, 114.227845],
      ],
      { color: "green" }
    )
      .addTo(map_dom)
      .bindPopup("2020-06-30巡检路径");
    L.marker([36.433698, 114.21603]).addTo(map_dom).bindPopup("1号巡检点");
    L.marker([36.427757, 114.231931]).addTo(map_dom).bindPopup("2号巡检点");
    L.marker([36.435255, 114.227845]).addTo(map_dom).bindPopup("3号巡检点");
 

});
 


</script>