leaflet基本使用_leaflet中文文档-程序员宅基地

技术标签: 前端  leaflet  javascript  开发语言  

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
项目预览:http://116.204.74.170/leaflet/

地图组成与名词解释

建议在学习之前先了解一些相关名词,以便理解:
高德官网的名词解释: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>

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43519131/article/details/129881737

智能推荐

数据录入界面的设计!!-程序员宅基地

文章浏览阅读1.3k次。最近设计了一个数据录入界面。在ACCESS中用VBA实现了,不知道在ASP.NET中应该如何实现?思路如下:1.根据相应的单据选择省份、商业单位,单击“开始录入”,激活下面的录入表格。2.在录入表格中选择地区、类别、商业名称、品名、规格后输入数量和发货日期。其中年份和月份、录入时间由系统自动生成。具体要求:1.省份、商业单位、地区等字段可以在组合框中选择,也可以直接输入,若输入的值在列表中存在,则..._收入预算基准数据录入功能界面

A2M人工智能与机器学习创新峰会参会感悟 by江舟_a2m峰会-程序员宅基地

文章浏览阅读937次。AI 研习社再前几周的时候,发文说能提供5张2018年A2M人工智能与机器学习创新峰会的门票,机缘巧合下,作为一个小小普通译者,我得到了门票一张,非常开心,于是在上周末(8月25-26日)就去听了下。 门票长下面这样(背后有两张午餐券) 现场是有3个会议厅,每个会议厅在当天上午或下午是进行同一个大主题下的不同的分享。门票上写着所有的会议题目,所以可以根据自己喜欢的自由搭配~ ..._a2m峰会

《通信工程》专业术语及其缩写大全_通信工程术语-程序员宅基地

文章浏览阅读1.5w次,点赞26次,收藏118次。此博客使用方法:点击“阅读更多”加载全文内容,ctrl键+F键,可呼出定位查找。缩写及其专业术语缩写 全称 释义 参考文献 6LoWPAN IPv6 over low-power wirelwss area networks 面向低功耗无线局域网的IPv6 AAL ATM adaptation layer ATM适配层 ..._通信工程术语

如何在前端页面中使用AJAX发送请求到后端PHP接口获取数据_html 通过ajax发送关键字从后台查询数据-程序员宅基地

文章浏览阅读394次,点赞10次,收藏9次。这样,当前端页面中通过 AJAX 发起 GET 请求到 `backend.php` 后,可以通过回调函数中的 `xhr.responseText` 获取到后端返回的数据,并进行处理。注意,如果要发送 POST 请求,可以将 `open` 方法的第一个参数改为 'POST',并在 `send` 方法中添加需要发送的数据。在 PHP 后端接口中,可以通过 `$_GET` 或 `$_POST` 超全局变量来获取前端发送的数据,然后根据处理逻辑返回相应的数据。// 处理后端返回的数据。// 处理 GET 请求。_html 通过ajax发送关键字从后台查询数据

轻松搞懂递归算法-程序员宅基地

文章浏览阅读1.1k次,点赞40次,收藏45次。函数内部调用自己的函数称为递归函数,这点大家应该早有了解。那什么是递归?递归这个词需要拆分成递和归来理解。递是传参,归则是返回,一切函数在调用时必然经过这两个步骤。在递归函数中,由于调用自身的属性,传参过程和返回过程都是连续的。

javaweb请求转发和重定向的区别_javaweb请求重定向和请求转发的区别-程序员宅基地

文章浏览阅读229次。javaweb请求转发和重定向的区别区别重定向请求准发第二次请求谁请求浏览器服务器浏览器发送了几次请求两次以上一次servlet可以共享request不可以可以地址栏发生改变了是否浏览器地址栏显示的是第几次请求最后一次第一次可以跳转到什么资源任意资源项目内部第二次请求的路径是绝对路径内部路径转载..._javaweb请求重定向和请求转发的区别

随便推点

Android——android:gravity 和 android:layout_Gravity-程序员宅基地

文章浏览阅读45次。LinearLayout有两个非常相似的属性:android:gravity与android:layout_gravity。他们的区别在于:android:gravity 属性是对该view中内容的限定.比如一个button 上面的text. 你可以设置该text 相对于view的靠左,靠右等位置.android:layout_gravity是用来设置该view相对与父view 的位置...

Python仿真优化与遗传算法_算法仿真实验可以使用python吗?-程序员宅基地

文章浏览阅读124次。Python提供了很多数值优化工具和算法,如scipy库、numpy库等,其中scipy库是一个强大的科学计算库,包括最优化、线性代数、统计分析等多个领域的功能,其中最优化模块提供了多种求解优化问题的算法,如Nelder-Mead、Powell、CG等,这些算法可以帮助用户求解各种优化问题,如非线性规划、函数拟合、曲线拟合等。在上述代码中,模拟了一个银行排队情景,有多个顾客到达银行,然后等待柜员服务,每个顾客的服务时间是1-3分钟,顾客的到达时间服从参数为5的指数分布。一、Python仿真优化。_算法仿真实验可以使用python吗?

SpringBoot Quartz 定时任务详解_springboot quartz standby shutdown-程序员宅基地

文章浏览阅读4.9k次。Quartz 简介在 JavaEE系统中,我们会经常用到定时任务,比如每天凌晨生成前天报表,每一小时生成汇总数据等等。我们可以使用java.util.Timer结合java.util.TimerTask来完成这项工作,但时调度控制非常不方便,并且我们需要大量的代码。使用Quartz框架无疑是非常好的选择,并且与Spring可以非常方便的集成,下面介绍它们集成方法和Cron表达式的详细介..._springboot quartz standby shutdown

hive函数之~reflect函数-程序员宅基地

文章浏览阅读1.6k次。reflect函数可以支持在sql中调用java中的自带函数,秒杀一切udf函数。使用java.lang.Math当中的Max求两列中最大值创建hive表create table test_udf(col1 int,col2 int) row format delimited fields terminated by ',';准备数据并加载数据cd /export/ser..._hive reflect

vue 线上环境 开启 vue-devtools_线上打开vuetools-程序员宅基地

文章浏览阅读2.6k次,点赞7次,收藏4次。vue 项目打包正式环境时,是没有 vue-devtools 选项卡的,没法看 vue 内部的数据使用以下几步可以实现在不改代码的情况下开启 vue-devtools选中 Source 选项卡,找到打包好的 app.js,并格式化ctrl + f 搜索$mount并在new那里打断点,new后面的对象就是 Vue 对象,需要记住该变量名,下一步要用到F5 刷新页面就就会进入断点,并在控制台输入d["default"].config.devtools = true(.config之前的_线上打开vuetools

Java给JPanel添加彩虹边框_给jpanel加边框-程序员宅基地

文章浏览阅读685次。使用多线程RGB变换为JPanel添加五彩斑斓的特效_给jpanel加边框

推荐文章

热门文章

相关标签