首页 > 其他分享 >地图:leaflet基本使用

地图:leaflet基本使用

时间:2023-03-31 15:44:38浏览次数:46  
标签:基本 map 标记 地图 leaflet 添加 featureGroup marker

leaflet:一个开源并且对移动端友好的交互式地图 JavaScript 库

中文文档:https://leafletjs.cn/reference.html
官网(英文):https://iclient.supermap.io/examples/leaflet/examples.html#iServer

该项目基于vue3+ts搭建

项目地址 gitee:https://gitee.com/philippines-kisses-snow/leaflet-map

地图组成与名词解释

建议在学习之前先了解一些相关名词,以便理解:
高德官网的名词解释:https://lbs.amap.com/api/javascript-api/guide/abc/components

效果:
image

下载库:

npm i leaflet

引入css:

// main.ts
import "leaflet/dist/leaflet.css"

在组件中使用leaflet:

  1. 引入:
import L from 'leaflet'

若引入时leaflet没有类型文件报错,需在.d.ts文件中加入:

// shims-vue.d.ts
declare module 'leaflet';
  1. 添加HTML地图节点,节点需要有宽高
<div id="map"></div>
  1. 初始化:
import { onMounted } from 'vue';

/*
 * layer: 地图切片地址,用于显示地图,该切片地址为高德地图使用的地址
 * 具体出处在高德官网并未找到,从相关博客推测可能是某个大佬抓包或其他方式获取到的
 * 相关博客:https://blog.csdn.net/fredricen/article/details/77189453
 */
const layer = L.tileLayer('http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}')
let map: any = {}

onMounted(() => {
  // 'map'为HTML节点id
  map = L.map('map', {
    center: [30.745922638363268, 104.00415658374735],//中心坐标
    zoom: 10,//缩放级别
    zoomControl: true, //缩放组件
    attributionControl: false, //去掉右下角logol
    layers: [layer],//图层
  })
})

效果:
image

  1. 将地图点位到指定点,并放大16倍(可显示街道)
map.setView([30.745922638363268, 104.00415658374735], 16)

效果:
image
5. 添加标记
(1)直接添加,官网当中是直接建立一个标记,并添加到地图(不推荐,不好管理)

L.marker([50.5, 30.5]).addTo(map);

(2)添加一个要素组,将标记添加到要素组里面管理(推荐)

// 添加标记组
let featureGroup: any = {}
featureGroup = L.featureGroup().addTo(map)

// 设置标记点:[纬度, 经度]
const marker = L.marker([30.745922638363268, 104.00415658374735])
featureGroup.addLayer(marker)

若标记后报错:
image
在引入时还需要独引入图片并更改默认Icon:

import L from 'leaflet'

// 图片
import _ICON from 'leaflet/dist/images/marker-icon.png';
import _ICONSHADOW from 'leaflet/dist/images/marker-shadow.png';
/*
 * 测试过几组数据,当使用自定义icon时,若不配置iconSize、iconAnchor,图标会在放大地图时位置发送偏移
 * iconAnchor:图标 "tip" 的坐标(相对于其左上角),该值大致为:[iconSize宽的一半,iconSize高]
 * iconAnchor需要在配置iconSize之后才会生效
 * popupAnchor:标记的弹出框的位置(使用默认弹出框时需要
 * popupAnchor若不配置,则默认为经纬度位置,会遮盖标记图标,-50表示将弹出框相对于经纬度位置向上移动50px
 */
let _L_DEFAULT_ICON = L.icon({
    iconUrl: _ICON,
    shadowUrl: _ICONSHADOW,
    iconSize: [25, 41],
    iconAnchor: [12, 40],
    popupAnchor: [0, -50]
});
L.Marker.prototype.options.icon = _L_DEFAULT_ICON

(3)给标记添加事件与弹出框-bindPopup(只支持简单添加)

// 给标记添加事件
marker.on('click', () => { })
// 给标记添加弹出框
marker.bindPopup('弹出内容').openPopup();

(4)给标记添加事件与弹出框-popup(高级用法)

marker.on('click', () => {
    // 可在点击标记后发起请求,请求成功后弹出框显示请求内容
    // 创建弹出框:弹出框默认从经纬度位置弹出,会遮盖图标,可使用offset设置偏移量:[x轴偏移量, y轴偏移量]
    L.popup({ offset: [0, -50] })
      .setLatLng(marker.getLatLng()) //设置弹出框弹出位置
      .setContent('请求内容')
      .openOn(map);
})
  1. 清除标记
if(featureGroup) featureGroup.clearLayers();
  1. 添加连线
// 再添加一个要素组,要素组可存在多个
let lineFeatureGroup: any = {}
lineFeatureGroup = L.featureGroup().addTo(map)
const locations = [
  [30.745922638363268, 104.00415658374735],
  [30.725309888823382, 104.03297424316408]
]

var polyline = L.polyline(locations, {color: 'red'}).addTo(map);
lineFeatureGroup.addLayer(polyline)
  1. 清除连线
if(lineFeatureGroup) lineFeatureGroup.clearLayers();

完整demo代码(代码已上传gitee)

<template>
  <div class="hello">
    <div id="map"></div>
    <div class="controls">
      <div class="fc">
        地图点击:
        <input type="radio" name="mapclick" :value="1" v-model="mapClick">开
        <input class="ml15" type="radio" name="mapclick" :value="0" v-model="mapClick">关
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import L from 'leaflet'
import { onMounted, ref } from 'vue';

import _ICON from 'leaflet/dist/images/marker-icon.png';
import _ICONSHADOW from 'leaflet/dist/images/marker-shadow.png';
/*
 * 测试过几组数据,当使用自定义icon时,若不配置iconSize、iconAnchor,图标会在放大地图时位置发送偏移
 * iconAnchor:图标 "tip" 的坐标(相对于其左上角),该值大致为:[iconSize宽的一半,iconSize高]
 * iconAnchor需要在配置iconSize之后才会生效
 * popupAnchor:标记的弹出框的位置(使用默认弹出框时需要
 * popupAnchor若不配置,则默认为经纬度位置,会遮盖标记图标,-50表示将弹出框相对于经纬度位置向上移动50px
 */
let _L_DEFAULT_ICON = L.icon({
    iconUrl: _ICON,
    shadowUrl: _ICONSHADOW,
    iconSize: [25, 41],
    iconAnchor: [12, 40],
    popupAnchor: [0, -50]
});
L.Marker.prototype.options.icon = _L_DEFAULT_ICON

const locations = [[30.745922638363268, 104.00415658374735], [30.725309888823382, 104.03297424316408]]
const layer = L.tileLayer('http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}')
const mapClick = ref(1)

let map: any = {}
let featureGroup: any = {}
let lineFeatureGroup: any = {}

onMounted(() => {
  // 初始化地图
  map = L.map('map', {
    center: [30.745922638363268, 104.00415658374735],//中心坐标
    zoom: 10,//缩放级别
    zoomControl: true, //缩放组件
    attributionControl: false, //去掉右下角logol
    layers: [layer],//图层
  })
  // 将视图点位到指定点,并放大16倍
  map.setView([30.745922638363268, 104.00415658374735], 16)
  // 地图点击
  map.on('click', (e: any) => {
    if(mapClick.value) {
      const latlng = e.latlng
      locations.push([latlng.lat, latlng.lng])
      // 清除要素
      if(featureGroup) featureGroup.clearLayers();
      locations.forEach(item => {
        point(item)
      })
    }
  })
  // 添加地图要素组
  featureGroup = L.featureGroup().addTo(map)
  lineFeatureGroup = L.featureGroup().addTo(map)
  // 设置初始打点
  locations.forEach(item => {
    point(item)
  })

  setPolyLine()
})

const point = (arr: number[]) => {
  // 设置点标记:[纬度, 经度]
  const marker = L.marker(arr)
  // 给标记添加事件
  marker.on('click', () => {
    // 创建弹出框:弹出框默认从经纬度位置弹出,会遮盖图标,可使用offset设置偏移量:[x轴偏移量, y轴偏移量]
    L.popup({ offset: [0, -50] })
      .setLatLng(marker.getLatLng())
      .setContent(arr[0] + ': ' + arr[1])
      .openOn(map);
  })
  // 将标记添加到要素组
  featureGroup.addLayer(marker)
}

const setPolyLine = () => {
  var polyline = L.polyline([locations[0], locations[1]], {color: 'red'}).addTo(map);
  lineFeatureGroup.addLayer(polyline)
}
</script>

<style scoped>
.hello, #map {
  height: 100%;
  width: 100%;
}

.hello {
  position: relative;
}

.controls {
  position: absolute;
  right: 0;
  top: 0;
  padding: 15px;
  z-index: 1000;

  font-size: 14px;
  background-color: #fff;
}

.fc {
  display: flex;
  align-items: center;
}

.ml15 {
  margin-left: 15px;
}

.mr15 {
  margin-right: 15px;
}
</style>

标签:基本,map,标记,地图,leaflet,添加,featureGroup,marker
From: https://www.cnblogs.com/my-wl/p/17276480.html

相关文章

  • 外汇基本面是什么,如何进行外汇基本面分析?
    外汇基本面是什么?外汇交易中,行情分析可分为外汇技术分析和外汇基本面分析。外汇基本面分析就是研究能影响一个国家整体经济的本质因素,在分析了诸如经济指标、政府政策、社会发展等因素后,投资者可以有效判断外汇市场价格的动向及市场趋势,以此来决定交易计划,提高交易的盈利率。那么,外......
  • Less.html基本使用
    背景:做一件代发业务的时候,订单中的产品描述含有大量广告,公司业务需要动态添加/删除指定的数据参考文档:Less.Html1.找出描述中含有多个的数据Dictionary<string,string>keyValues=newDictionary<string,string>();foreach(DataRowdataRowindataRowCollection){......
  • MyBatis框架的基本CRUD命令
    1、局部SQL配置文件重要标签说明:作用:把sql语句保存在Mybatis的局部配置文件中,给某个数据访问类使用;根节点为<mapper>…</mapper>;namespace:命名空间,其值为某一个dao层实现类的具体路径,表示这个类要使用相应的SQL语句。这个具体路径不要自己写,可以选中该类,右键,选择“copy......
  • MyBatis 框架基本使用流程
    1、编写Mybatis主配置文件: mybatis.xml中重要标签说明:<!--配置数据库连接环境:driver、url、username、password--><environmentsdefault="mysql">//设置当前要使用的数据库<!--开始配置mysql--><environmentid="mysql">//给当前要使用的数据库环境命名,要唯一<......
  • Elasticsearch.Net+Nest基本用法
    基本用法安装Nest(安装后默认会装上Elasticsearch.Net),注意:版本尽量选择跟ES版本一致的批量初始化数据到ESusingNest;try{//测试环境配置SSL证书需要的设置ServicePointManager.SecurityProtocol=SecurityProtocolType.Tls12|SecurityProtocolType.Tls11......
  • 【C#学习】01--基本概念
    1.1关于C#C#只是一种简单安全的新型面向对象语言,继承了C的语法风格和C++的面向对象特性,不再提供对指针类型的支持(因此程序不可随便访问内存地址空间)、不再支持多重继承;C#的诞生意义是生成面向.NETFramework环境的代码,身为编程语言的一种,它作为开发工具而存在,本身并不......
  • 天地图多边形工具
     http://lbs.tianditu.gov.cn/api/js4.0/examples.html 1<!DOCTYPEhtml>2<html>3<head>4<metahttp-equiv="content-type"content="text/html;charset=utf-8"/>5<title>天地图-地图API-范例-工具集合<......
  • 3/30每日总结:地图下钻功能的实现
    在main中新建 然后导入html文件其中代码如下:<!DOCTYPEhtml><html><head><metacharset="UTF-8"><!--重要meta,必须!--><metaname="viewport"content="width=320,initial-scale=1.0,maximum-scale=1.0,mi......
  • 基本背包问题复习(01背包,完全背包,多重背包,分组背包)
    背包问题,本质上就是给几种物品,每个物品有体积有价值,可能有个数限制有一个容量有限的背包,在背包能装下的前提下,能装的最大价值是多少 背包问题一般分为这几种:01背包:每件物品只有一个完全背包:每件物品有无限个多重背包:每件物品有Si个(有限个)分组背包:所有物品被分为多个组,每一组......
  • 2023-03-30-栈的基本操作
    1//栈stack234#include<stdio.h>5#include<stdbool.h>67#defineMAXSIZE10089typedefstruct10{11intdata[MAXSIZE];//数据12inttop;//栈顶指针,初始为-113}*SqStack;1415voidinitStack(SqStackS)//初始化栈16{17......