地图信息 leaflet +vue3 一个文档让你掌握leaflet基础用法

参考仓库:

leaflet学习: leaflet基础学习 (gitee.com)

 leaflet基本用法

1.引入leafletjs资源:

  1. 手动  下载地址:https://leafletjs.com/download.html  引入css和js
  2. npm npm install leaflet --save 在组件或者main.js中引入

2.创建容器存放地图

<div id="map"></div>

3.初始化地图

坐标,纬度在前,经度在后,初始化地图必有两个参数,一个坐标,一个初始缩放倍数

<script setup>
import L from 'leaflet'
import 'leaflet/dist/leaflet.css'
import { onMounted} from 'vue'
const initMap = () => {
  let map = L.map('map', {
    center: [29.44916482692468, 106.47399902343751],//中心坐标
    zoom: null,//初始缩放,因为在下文写了展示全地图,所以这里不设置,也可以设置
    minZoom: 3,
    maxZoom: 18,
    zoomControl: true, //缩放组件
    // attributionControl: false, //去掉右下角logol
  })
// let map=L.map("map").setview([29.44916482692468, 106.47399902343751],9);
}
onMounted(() => {
  initMap()
})
</script>

4.给容器设置宽高,显示地图

<style>
#map {
  height: 800px;
  width: 1000px;
  margin: auto;
  border: 10px solid pink;
}
</style>

leaflet布局,图层

L.tileLayer加载底图,第一个参数为底图资源,第二个参数中attribution为版权

   L.tileLayer(
        "https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
        {
          attribution:
            '&copy; <p>OpenStreetMap</p> contributors',
        }
      ).addTo(map);

leaflet标记

使用L.marker()第一个参数为经纬度,第二个参数为自定义标记图标。

addTo()添加到图层;bindPopup()显示弹框内容,openPopup()自动打开弹框。

弹框也可使用bindTooltip()

let markerIcon = L.icon({
    iconUrl: "https://unpkg.com/leaflet@1.9.3/dist/images/marker-icon.png",
     iconSize: [20, 30],
    }); 
 let marker = L.marker([29.44916482692468, 106.47399902343751], { icon: markerIcon })
        .addTo(map)
        .bindPopup("标记")
        .openPopup();
//--------------------------------
//marker.bindTooltip('我是标记', { //添加提示文字
//  permanent: true, //是永久打开还是悬停打开
//direction: 'top' //方向
//}).openTooltip(); //在图层打开

leaflet线段,形状

线段:使用 L.polyline()第一个参数为线段两端的位置坐标,第二个参数为线段的样式。

同样也可使用弹框来做数据展示。

let line = L.polyline([[29.44, 106.473], [27.595, 106.9]],
         {
           opacity: 1,
           color: 'red'
         }).addTo(map)

 圆形:使用 L.circle(),对于圆形只需要一个坐标和圆的半径;第一个参数为圆点,第二个参数为圆的样式。同样也可使用弹框来做数据展示。

  L.circle([29.44, 106.473], {
          color: "black", //轨迹颜色
          fillColor: "pink", //默认和轨迹色一样
          fillOpacity: 0.3, //圆的填充色
          radius: 500 * 100, //半径,单位为米
        }).addTo(map);

矩形:使用 L.rectangle(),对于矩形有对角线只需要确定两个坐标;第一个参数为坐标,第二个参数为矩形的样式

let rectangle = L.rectangle(
         [29.44, 106.473],
          { color: "pink" }
        ).addTo(map);

多边形:使用L.polygon(),该坐标为数组,长度大于2,。

let polygon = L.polygon(坐标数组, { color: "red" }).addTo(map);

leaflet弹框

使用L.popup()如下,弹框中的内容可以是变量也可以展示dom元素。

L.popup({
    closeButton: true, //是否有关闭按钮
     closeOnClick: true, // 点击空白是否关闭
     className: "pop-style", //弹框样式类名
    })
      .setLatLng(坐标) // 弹框坐标
      .setContent(content) //弹框内容 可动态内容
  //  .setContent("你好xxx")
      .openOn(map);

leaflet事件

点击获取到的e.latlng是所点击位置的经纬度坐标。可使用map.setView()重置中心位置和缩放倍数。

在以上的部分中,需要用到坐标的都在事件中进行获取,可以用数组收集起来展示多边形。

let arrLatlng = [];
map.on("click", function (e) {
        let latlng = e.latlng;
        map.setView(latlng, 7);
        //动态线段
        arrLatlng.push(latlng);
        if (arrLatlng.length > 1) {
          // 线段 连续线段--------------------------------------
          let line = L.polyline(
            [arrLatlng[arrLatlng.length - 2], arrLatlng[arrLatlng.length - 1]],
            {
              opacity: 1,
              color: "green",
            }
          ).addTo(map);
        }
})

leaflet底图切换

定义一些地图底层瓦片数据,在第一条数据调用addTo(map),表示默认展示地图;在L.tileLayer()中将两个参数置空,也可以设置默认值。

对于osm地图无法显示:leaflet+Openstreetmap地图无法显示_leaflet openstreetmap 地址-CSDN博客 

瓦片数据地址:https://zhuanlan.zhihu.com/p/641436984

通过L.control.layers()创建一个Layer Control,参数:

1.第一个参数是创建的包含所有底图的对象baseLayer;

2.第二个参数是覆盖Layer对象的图层;

3.底图控制的位置

// 地图底层数据
  const baseLayer = {
    '高德地图': L.tileLayer(
      "https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
      { attribution: "高德" }
    ).addTo(map),
    'ArcGIS卫星影像': L.tileLayer(      "https://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png",
     { attribution: "ArcGIS卫星影像" }
    ),
    '白色底图': L.tileLayer(
      "http://10.87.211.254:8099/title/{z}/{x}/{y}.png",
     { attribution: "白色底图" }
    ),
    '天地图影像图': L.tileLayer(
      "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", 
    ),
    '天地图街道图': L.tileLayer(
      "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=d0cf74b31931aab68af181d23fa23d8d", 
    ),

  }
  // 配置布局
  L.tileLayer("", { attribution: "版权归xxx" }).addTo(map);
  // 地图底层控制
  L.control.layers(
    baseLayer, {}, {
    position: 'topright'
  }
  ).addTo(map)

leaflet.pm 图层

在Leaflet中,有两种Layer:(1)base layers——底图(在我们的GIS系统中一次只能显示一张底图);(2)overlays——覆盖Layer(放在底图上的Layer)。

使用L.layerGroup()来声明图层组,

  let markerIcon = L.icon({
    iconUrl: require("../leaflet/person1.png"),
    iconSize: [50, 50],
  });  
  //声明图层组,存储城市标记marker
  let cities = L.layerGroup();
  // 声明两个城市的坐标加入图层组
  L.marker([29.44916482692468, 106.47399902343751], { icon: markerIcon }).bindPopup('这里属于重庆').addTo(cities);
  L.marker([35.51, 117.92], { icon: markerIcon }).bindPopup('这里属于青岛').addTo(cities);
  // 新建图层控件的数据源 - 城市
  let overlays = {
    '城市': cities
  };
  L.control.layers(
    baseLayer, overlays, {
    position: 'topright'
  }
  ).addTo(map)

leaflet.pm 几何图形的编辑

需要安装leaflet.pm插件 / 也可使用安装Leaflet-Geoman/也可以使用leaflet-drawLeaflet-draw使用方法(个人觉得该编辑插件最好用) 使用之前卸载leaflet.pm

npm install leaflet.pm

 页面引入

import 'leaflet.pm';
import 'leaflet.pm/dist/leaflet.pm.css';

在组件中运用

map.pm.setLang()函数使工具条提示显示中文; map.pm.addControls()增加图形绘制控件

  // 添加绘制工具
  map.pm.setLang('zh')
  map.pm.addControls({
    position: "topleft",
    drawPolygon: true, //绘制多边形
    drawMarker: false, //绘制标记点
    drawCircleMarker: false, //绘制圆形标记
    drawPolyline: true, //绘制线条
    drawRectangle: false, //绘制矩形
    drawCircle: false, //绘制圆圈
    editMode: true, //编辑多边形
    dragMode: true, //拖动多边形
    cutPolygon: true, //添加⼀个按钮以删除多边形⾥⾯的部分内容
    removalMode: true, //清除多边形
  })
  // 全局绘制样式
  map.pm.setPathOptions({
    color: "orange",
    fillColor: "green",
    fillOpacity: 0.4,
  })
  // 或者单独设置绘制样式
  let options = {
    // 连接线标记之间的线 实线 
    templineStyle: {
      color: "red",
    },
    // 提⽰线从最后⼀个标记到⿏标光标的线虚线
    hintlineStyle: {
      color: "red",
      dashArray: [5, 5],
    },
    // 绘制完成的样式
    pathOptions: {
      color: "orange",
      fillColor: "green",
    },
  }
  // 激活绘制多边形功能、绘制多边形时的样式
  map.pm.enableDraw("Polygon", options)
  // 启用绘制--多边形功能
  map.pm.enableDraw("Polygon", {
    snappable: true, //启⽤捕捉到其他绘制图形的顶点
    snapDistance: 20, //顶点捕捉距离
  })
  // 关闭绘制--注意也可以关闭其他模式的绘制功能
  map.pm.disableDraw("Polygon")
  // 绘制事件监听
  map.on("pm:drawstart", (e) => {
    console.log(e, "绘制开始第一个点");
  })
  map.on("pm:drawend", (e) => {
    console.log(e, "禁⽌绘制、绘制结束");
  })
  map.on("pm:create", (e) => {
    console.log(e, "绘制完成时调⽤");
    if (e.shape == "Circle") {
      console.log(e.layer._latlng, e.layer._radius, "绘制坐标");
    } else {
      console.log(e.layer._latlngs[0], "绘制坐标");
    }
  })
  map.on("pm:globalremovalmodetoggled", (e) => {
    console.log(e, "清除图层时调用");
  })

leafletGeoJson格式数据应用

geoJson是一种基于Json的地理空间数据交换格式。它定义了几种类型的json对象,以及将他们结合起来表示有关地理特征、属性和空间范围的数据的方式。

推荐一篇文章关于GeoJson对象解释以及他的几何类型:GeoJSON三分钟入门教程 - 知乎 (zhihu.com)

 应用geojson数据:可以定义一个geojson格式数据,( 中国各地geojson格式数据来源:DataV.GeoAtlas地理小工具系列 (aliyun.com))如下:

var geojsonFeature={
    "type": "Feature",
    "properties": {
        "name": "Coors Field",
        "amenity": "Baseball Stadium",
        "popupContent": "This is where the Rockies play!"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [-104.99404, 39.75621]
    }
};

通过L.geoJson(数据,样式)来解析这种数据结构,以下通过axios获取:

    const getData = function () {
        axios.get('https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json')
            .then(function (res) {
               let list = res.data
                const lakeLayer = L.geoJson(list, {
                    style: {
                            weight: 2,  //外边框宽度
                            opacity: 0.2,
                            color: 'black',//外边框颜色
                            fillOpacity: 0.2,//填充透明度
                            fillColor: '#6ba7de'//填充的颜色
                            },
                }).addTo(map);
            })
            .catch(function (error) {
                console.log(error);
            })

    }

 除此之外,还可以先创建一个geoJosn的空图层,然后后面再添加格式进去:

let myLayer=L.geoJSON().addTo(map)
myLayer.addData(list)

 onEachFeature函数,可以遍历集中的所有要素feature,并为要素赋予一些属性或进行一些操作,如下:

 可以对获得的范围进行点击,鼠标移动事件,feature是遍历出的单独小版块,和触发事件e.target.feature一样,layer则是触发事件e.target,通过bindTooltip()鼠标经过哪些部分就可以展示相应的内容。

// 创建geoJson图层   
const lakeLayer = L.geoJson(list, {
                        style: lakeLayerstyleNew,
                        onEachFeature: ((feature, layer) => { 
                            layer.on({
                                //鼠标移入方法
                                mouseover: (() => {
                                    parentCode = feature.properties.parent.adcode
                                    // 移入的效果
                                    if (parentCode == adcode.value) {
                                        layer.setStyle({
                                            weight: 2,
                                            color: '#2f8ffc',
                                            fillColor: '#ffffff',
                                            fillOpacity: 0.4,
                                        });
                                    }
                                }),
                                //鼠标移出方法
                                mouseout: (() => {
                                    if (parentCode == adcode.value) {
                                        layer.setStyle(lakeLayerstyleNew);
                                    }
                                }),
                                //点击方法,变色
                                click: (() => {
                                    layer.setStyle({
                                        weight: 4,
                                        color: 'red',
                                    });
                                    // 获取code
                                    adcode.value = feature.properties.adcode;
                                    level.value = feature.properties.level
                                }),
                            });
                        })
                    }).bindTooltip(function (layer) {  // 只要使用这个bindTooltip方法,
                        // 弹框内容
                        let content = 'adcode:' + `${layer.feature.properties.adcode}` + '<br/>' + 'name:' + `${layer.feature.properties.name}` + '<br/>' + 'level:' + `${layer.feature.properties.level}`
                        return content;
                    }).addTo(map);
  //定位到该图层 显示geoJson图层整个视图,若不加,则会展示初始位置视图范围
                    // fitBounds用于调整地图的视图以适应指定的边界。
                    map.fitBounds(lakeLayer.getBounds());

问题

  1. 以 http://localhost:8080/打开,编辑图层的功能,编辑多边形不可用,卡死,获取的geojson数据视图展示出;以 http://192.xxx.xx.xxx/打开,编辑图层可用,但,获取的geojson数据展示不出。

解决

localhost运行能展示geojson数据,通过电脑IP运行展示不出,公共资源访问403,原因:在我们请求的时候会带我们的浏览器信息到阿里云,阿里云做了访问限制

在Vue 3中,你可以通过在项目的public/index.html文件中直接添加<meta>标签来配置referrer-policy。这样做可以确保在你的Vue应用中所有的HTTP请求都不会发送Referer头部。

  • 27
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值