angular里leaflet基础使用

目录

一、导入leaflet并初始化地图

二、地图基本操作

1、地图上添加标记Mark

2、地图上画圆

3、地图上画多边形

4、地图上绘制弹出框(Popup)

5、简单click事件响应,点击显示经纬度

6、切换地图底图

7、实现输入经纬度跳转

8、angular引入leaflet插件

9、实现地图卷帘效果,叠加显示

10、画各种线

①带一个箭头的线

②虚线/面

③点线点线效果

④带标记点的线

⑤带自定义图案的线

⑥带多箭头的线

11、定位用户位置(精度较低)

①leaflet自带的方法

②使用leaflet.locate插件


一、导入leaflet并初始化地图

1、安装leaflet模块

npm install leaflet

2、在style.less全局样式文件中引入leaflet.css

@import '../node_modules/leaflet/dist/leaflet.css';

3、创建map组件,定义一个地图容器,,id设置就是后面引用的地图容器名字,记得设置高度

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

4、ts文件引入leaflet和初始化地图主要代码

import { Component } from '@angular/core';
import * as L from 'leaflet' //导入模块
@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.less']
})
export class MapComponent {
  map: any
  layer: any
  ngOnInit() {
    this.initMap()  //初始化地图
  }

  initMap() {
    this.map = L.map('map', {//这里的‘map’,就是div容器的id
      zoom: 13,//默认缩放级别
      center: [31, 117]//中心点
    })
    this.layer = L.tileLayer('http://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',//瓦片链接
      {
        maxZoom: 18,//最大缩放级别
        zIndex: 10//层级,越高,图层越上面
      }).addTo(this.map)//add进地图里,才能显示出来
  }
}

5、页面展示

二、地图基本操作

1、地图上添加标记Mark

    L.marker([31, 117]).addTo(this.map);//在位置[31, 117]添加一个标记

2、地图上画圆

    L.circle([31, 117], {
      color: 'green',//边框颜色
      fillColor: '#f03',//填充颜色
      fillOpacity: 0.5,//透明度
      radius: 200//圆的半径
    }).addTo(this.map)

3、地图上画多边形

    let latlngs = [
      [31, 117] as LatLngExpression, //类型断言 不然下面引用会报错
      [31.01, 117.05] as LatLngExpression,
      [31.02, 117.05] as LatLngExpression,
    ];
    let polygon=L.polygon(latlngs, {
      color: 'green',
      fillColor: 'red',//填充颜色
    }).addTo(this.map)
    // 将地图放大到多边形的位置
    this.map.fitBounds(polygon.getBounds());

4、地图上绘制弹出框(Popup)

    let marker = L.marker([31, 117]).addTo(this.map);//在位置[31, 117]添加一个标记
    marker.bindPopup('marke').openPopup() //.openPopup()表示默认打开,地图上只允许同时打开1个,或者使用 Map.addLayer 打开任意多个。
.....
    polygon.bindPopup('<p style="color:red">Hello world!<br />这是一个绘制的多边形</p>')

都用这个方法加弹框,就可以同时显示多个

    marker.bindPopup('marke').openPopup()

    L.popup().setLatLng([31.01, 117])
      .setContent('<p style="color:red">Hello world!<br />这是一个绘制的多边形</p>')
      .addTo(this.map)
    L.popup().setLatLng([31.015, 117])
      .setContent('<p style="color:red">Hello world!<br />这是一个绘制的多边形</p>')
      .addTo(this.map)

5、简单click事件响应,点击显示经纬度

    this.map.on('click', (e: any) => { //简单的地图点击事件响应,绘制弹出框显示经纬度
      L.popup().setLatLng([e.latlng.lat, e.latlng.lng])
        .setContent(`纬度:${e.latlng.lat}<br/>经度:${e.latlng.lng}`)
        .addTo(this.map)
    })

对地图实例做监听,在Leaflet中每种实现对象都可以添加事件。

    //对地图实例做监听,在Leaflet中每种实现对象都可以添加事件
    marker.on('click',(e:any)=>{
      L.popup().setLatLng(e.latlng).setContent('我被点击了').addTo(this.map)
    })

6、切换地图底图

添加一个basemaps地图底图图层对象,初始化地图并设置底图图层,添加图层控制器

    //定义了一个 basemaps 对象,包含了一些不同的底图图层选项
    var basemaps = {
      世界影像: L.tileLayer('http://server.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        attribution: '添加地图图层的归属声明,地图数据的来源和相关版权信息。通常会显示在地图的角落'
      }),
      arc街道: L.tileLayer('http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'),
      '行政区': L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}'),
      '地形': L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}'),
    };

    this.map = L.map('map', {//这里的‘map’,就是div容器的id
      layers: [basemaps.世界影像], // 设置默认显示的底图
      zoom: 13,//默认缩放级别
      center: [31, 117]//中心点
    })
    L.control.scale().addTo(this.map);//添加比例尺
    L.control.layers(basemaps).addTo(this.map); //使用 L.control.layers(basemaps).addTo(map) 添加了一个图层控制器,允许用户在不同的图层之间进行切换

7、实现输入经纬度跳转

<div>
    <input type="number" #jingdu>
    <input type="number" #weidu>
    <button (click)="location(jingdu.value,weidu.value)">定位</button>
</div>
  // 声明一个成员变量保存当前标记
  private marker?: L.Marker;
  location(a: any, b: any) {
    if (this.marker) {
      this.map.removeLayer(this.marker)//清除上一个标记点
    }
    this.marker = L.marker([a, b]).addTo(this.map)//添加标记点
    this.map.flyTo([a, b])//fly到坐标点的位置
    this.map.planTo([a, b])//平移到坐标点的位置,动画效果不顺滑
  }

8、angular引入leaflet插件

①下载插件

②打开插件的index.html,查看引用的样式和js文件,

③把这几个文件放到angular项目的index.html文件中。

④angular.json文件中全局引用一下leaflet-side-by-side.js文件

⑤配置插件被ts识别,终端输入。操作完成后,会在node_modules文件夹下生成@types下leaflet-side-by-side文件夹。可查看文件夹下的index.d.ts文件。导入完成可正常使用插件了。

 npm install @types/leaflet-side-by-side --save

除此外,某些插件可以直接npm安装

npm install leaflet-side-by-side

安装插件时的一些报错解决方法:

①需要修改WEBPACK 配置和自定义 LOADER 处理实例

安装webpack插件,版本号根据angular cli来

npm i -D @angular-builders/custom-webpack@16.0.0

添加webpack.config.js文件,文件内容为:

module.exports = {
    // ...其他配置...
    module: {
      rules: [
        // 处理 .css 文件
        {
          test: /\.css$/,
          use: [
            // 将 CSS 插入到 DOM 中
           'style-loader',
            // 将 CSS 转换为 JavaScript 模块
            'css-loader',
          ],
        },
      ],
    },
  };

修改angular.json文件

"architect": {
  "build": {
    "builder": "@angular-builders/custom-webpack:browser",
    //.....省略....
    "customWebpackConfig": {
      "path": "./webpack.config.js"
    },
    //.....省略....
  },
  "serve": {
    "builder": "@angular-builders/custom-webpack:dev-server",
    //.....省略....
  },

②找不到模块

npm 安装

npm install style-loader

9、实现地图卷帘效果,叠加显示

分别定义左右两个地图图层

    let leftLayers = L.tileLayer(`https://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}`);
    let rightLayers = L.tileLayer(`http://wprd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}`);

使用sideBySide()方法,三个属性

    L.control.sideBySide(rightLayers, rightLayers).addTo(this.map)
// 参数分为别左、右图层(数组)、选项配置
L.control.sideBySide(leftLayer[s], rightLayer[s],options)

let sideBySide = L.control.sideBySide(leftLayers, [rightLayersText, rightLayers], { padding: 0, thumbSize: 42 }).addTo(map);

// 修改左侧图源
sideBySide.setLeftLayers(purplishBlueLayer)
// 修改右侧图源
// sideBySide.setRightLayers(purplishBlueLayer)

效果图,可左右滑动,拖动地图

10、画各种线

安装 PolylineDecorator 插件:

npm install leaflet-polylinedecorator

配置插件被ts识别

 npm install @types/leaflet-polylinedecorator --save

在ts里面导入后就可以正常使用了

import 'leaflet-polylinedecorator';

①带一个箭头的线

    let arrow = L.polyline([//画一段普通线
      [30, 105],
      [30.5, 104],
      [30.6, 105.2],
      [30.7, 104.8],
    ], {}).addTo(this.map);

    L.polylineDecorator(arrow, {//生成带箭头线
      patterns: [{
        offset: '100%',//符号的起点为折线的终点。
        repeat: 0,//只应用一次该符号模板,不重复。
        //表示装饰的图案效果为一个箭头
        symbol: L.Symbol.arrowHead({
          pixelSize: 15,//箭头的大小,15 像素。
          polygon: false,//箭头的形状为点到线的箭头而非多边形。
          pathOptions: {
            stroke: true//箭头应用与折线相同的线条配置,这里表示使用折线的线条样式(颜色、宽度等)。
          }
        })
      }]
    }).addTo(this.map);

②虚线/面

let polygon = L.polygon([ //绘制一个面
      [
          [54, -6],
          [55, -7],
          [56, -2],
          [55, 1],
          [53, 0]
      ],
      [
          [54, -3],
          [54, -2],
          [55, -1],
          [55, -5]
      ]
  ], {
      color: "#ff7800",
      weight: 3
  }).addTo(this.map);

  L.polylineDecorator(polygon as any, { 
    // patterns:定义装饰的图案效果
      patterns: [{
          offset: 0,//符号的起点为多边形的起点
          repeat: 10,//每隔一定的距离(这里为符号的长度)就重复一次该符号,直到覆盖整个多边形。
          symbol: L.Symbol.dash({//装饰的图案效果为无间隔虚线,每条线段的长度为 pixelSize 像素。pixelSize 被设置为 0,表示线段长度为默认值(5 像素)。
              pixelSize: 0
          })
      }]
  }).addTo(this.map);

③点线点线效果

let aa = L.polyline([
      [49.543519, -12.469833],
      [49.808981, -12.895285],
      [50.056511, -13.555761],
      [50.217431, -14.758789],
      [50.476537, -15.226512],
      [50.377111, -15.706069],
      [50.200275, -16.000263],
    ])
    L.polylineDecorator(aa, {
      patterns: [{
        offset: 12,//符号的起点距离折线的起点的长度为 12 个像素。
        repeat: 25,
        //装饰的图案效果为一条红色的虚线,每条线段的长度为 10 个像素
        symbol: L.Symbol.dash({
          pixelSize: 10,
          pathOptions: {
            color: '#f00',
            weight: 5
          }
        })
      },
      {//示装饰的图案效果为一条实线
        offset: 0,
        repeat: 25,
        symbol: L.Symbol.dash({
          pixelSize: 0
        })
      }
      ]
    }
    ).addTo(this.map);

④带标记点的线

    let markerLine = L.polyline([
      [58.44773, -28.65234],
      [52.9354, -23.33496],
      [53.01478, -14.32617],
      [58.1707, -10.37109],
      [59.68993, -0.65918]
    ], {}).addTo(this.map);

    L.polylineDecorator(markerLine, {
      patterns: [{
        offset: '5%',
        repeat: '10%',
        symbol: L.Symbol.marker()//标记符号是一个圆形,可以通过传递配置选项对象修改其外观。
      }]
    }).addTo(this.map);

⑤带自定义图案的线

 let aaa = L.polyline([
      [42.9, -15],
      [44.18, -11.4],
      [45.77, -8.0],
      [47.61, -6.4],
      [49.41, -6.1],
      [51.01, -7.2]
    ])
    L.polylineDecorator(aaa, {
      patterns: [{
        offset: 0,
        repeat: 10,
        symbol: L.Symbol.dash({ //黑色透明度0.2宽度2px的虚线
          pixelSize: 5,
          pathOptions: {
            color: '#000',
            weight: 2,
            opacity: 0.2
          }
        })
      },
      {
        offset: '16%',
        repeat: '33%',
        symbol: L.Symbol.marker({
          rotate: true,
          markerOptions: {
            icon: L.icon({
              iconUrl: './assets/images/icon_plane.png',//自定义的飞机图案
              iconAnchor: [16, 16]
            })
          }
        })
      }
      ]
    }
    ).addTo(this.map);

⑥带多箭头的线

let multiCoords1 = [
      [
        [47.5468, -0.7910],
        [48.8068, -0.1318],
        [49.1242, 1.6699],
        [49.4966, 3.2958],
        [51.4266, 2.8564],
        [51.7542, 2.1093]
      ],
      [
        [48.0193, -2.8125],
        [46.3165, -2.8564],
        [44.9336, -1.0107],
        [44.5278, 1.5820],
        [44.8714, 3.7353],
        [45.8287, 5.1855],
        [48.1953, 5.1416]
      ],
      [
        [45.9205, 0.4394],
        [46.7699, 0.9228],
        [47.6061, 2.5488],
        [47.7540, 3.3837]
      ]
    ] as LatLngExpression[][];
    let plArray = [];
    for (let i = 0; i < multiCoords1.length; i++) {
      //在每次迭代中,创建一个新的 Polyline 对象,
      plArray.push(L.polyline(multiCoords1[i]).addTo(this.map));
    }
    L.polylineDecorator(plArray, {
      patterns: [{
        offset: 25,
        repeat: 50,
        //表示装饰的图案效果为一个箭头符号。箭头的大小为 15 个像素。该符号模板还设置了箭头的颜色透明度为 1,线宽为 0。
        symbol: L.Symbol.arrowHead({
          pixelSize: 15,
          pathOptions: {
            fillOpacity: 1,
            weight: 0
          }
        })
      }]
    }).addTo(this.map);

11、定位用户位置(精度较低)

①leaflet自带的方法

    this.map.locate({
      setView: true, // 是否将地图视角移动到当前位置
      maxZoom: 18, // 最大缩放级别
      watch: true, // 是否持续监听位置变化
      enableHighAccuracy: true ,// 是否启用高精度定位(可能会耗费更多的时间和电量)
      timeout: 100000 // 设置 timeout 选项为 10 秒
    });

    this.map.on('locationfound', (e: any) => {
      if (this.marker) {
        this.marker.setLatLng(e.latlng); // 更新标记的位置
      } else {
        this.marker = L.marker(e.latlng).addTo(this.map).bindPopup("<b>你在这儿!</b>").openPopup(); // 创建标记并添加到地图
      }
    });

②使用leaflet.locate插件

安装插件、使ts识别,导入

npm install --save leaflet.locatecontrol
npm install @types/leaflet.locatecontrol --save
import 'leaflet.locatecontrol' // Import plugin
import 'leaflet.locatecontrol/dist/L.Control.Locate.min.css'

 实现代码

    L.control.locate({
      position: "topright",//定位按钮放在右上角
      initialZoomLevel: 15,//开始的缩放级别
      strings: {
        title: "Show me where I am, yo!"
      },
      locateOptions: {
        maxZoom: 16,// 设置最大缩放级别
      },
    }).addTo(this.map);

点击定位按钮跳转

 

使用画图工具栏

npm install leaflet-draw
npm install @types/leaflet-draw

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值