首页 前端知识 基于“vue leaflet 地图瓦片”实现离线地图服务

基于“vue leaflet 地图瓦片”实现离线地图服务

2024-05-07 13:05:52 前端知识 前端哥 820 37 我要收藏
by:垃圾程序员

I. 离线地图服务介绍

近期跟进几个客户需求,发现其对于gis地图都存在或多或少的需求,但是又担心数据安全性问题,希望部署到内网中,得,过一遍实现路径吧。

A. 什么是离线地图服务

离线地图服务是指在没有网络连接的情况下,能够提供地图数据和相关功能的服务。传统的在线地图服务需要实时的网络连接才能加载地图数据,而离线地图服务则将地图数据预先下载到本地设备或服务器中,用户可以在没有网络的环境下使用这些离线地图数据。

离线地图服务的主要特点包括:

  1. 离线访问:用户可以在没有网络连接的情况下使用地图数据,不受网络信号的限制。

  2. 快速响应:由于地图数据已经存储在本地设备或服务器中,离线地图服务可以更快速地响应用户的请求,提供流畅的地图浏览体验。

  3. 节省流量:使用离线地图服务可以避免频繁下载地图数据,减少网络流量消耗。

  4. 定制性:离线地图服务通常提供一定的地图数据编辑和定制功能,用户可以根据自己的需求进行标注、绘制路径等操作。

B. 离线地图服务的应用场景

离线地图服务具有广泛的应用场景,以下是一些常见的应用场景:

  1. 旅行导航:在旅行中,尤其是在国外或偏远地区,网络连接可能不稳定或昂贵。使用离线地图服务,用户可以提前下载所需的地图数据,随时查看和导航到目的地,无需依赖实时的网络连接。

  2. 偏远地区和山区探险:在偏远地区或山区进行探险活动时,网络信号可能非常弱或根本没有网络覆盖。通过离线地图服务,探险者可以预先下载相关地图数据,并在没有网络连接的情况下准确定位自己的位置、规划路线和探索未知地区。

  3. 线下导览:离线地图服务可用于博物馆、展览馆、公园等场所的线下导览。用户可以下载相应的地图数据,通过离线地图服务在场馆内部快速定位、获取展品信息以及导航到感兴趣的地点。

  4. 无网络环境下的移动工作:在一些特殊场景下,如海上作业、野外勘测和建筑施工等,网络连接可能不可用。离线地图服务可以帮助工作人员在没有网络的环境下查看地理位置、绘制标记、规划路线等,提高工作效率。

  5. 教育和研究:离线地图服务在教育和研究领域也有广泛应用。学生和研究人员可以使用离线地图服务进行地理教学、地理信息系统分析、地质勘探等活动,无需依赖实时的网络连接。

总之,离线地图服务在需要无网络或弱网络环境下仍然能够使用地图数据和导航功能的场景中非常有用,为用户提供了更加方便和可靠的地图体验。

II. 离线地图数据的准备

A. 下载瓦片地图数据

这里的瓦片地图是通过开源工具实现的,感谢同志-Crimson。下面的地址是其项目的开源地址,大家可以去捧场。

地图下载器: 使用Java开发的地图瓦片图下载工具,支持OpenStreetMap、天地图、谷歌地图、高德地图、腾讯地图、必应地图的XYZ瓦片图下载与合并。icon-default.png?t=N7T8https://gitee.com/CrimsonHu/java_map_download 打开后如下图所示,有不同的图层可以进行选择。本次技术实现我选取的是“高德地图普通图带注释”的图层。

之后选择要下载的区域,定位到区域,点击下载

自主配置层级、图片格式、命名风格、错误处理、保存路径等参数,程序会先评估下载量,然后开始下载。

这里要讲的有几点:

1.层级等级从第0级到第21级,级别越大,要下载的图片越多,相对的下载时长也会越长,如果你仅仅是做测试,不建议勾选大层级。

2.预设的命名风格,选择时要记录好,因为下载文件会以选择的格式进行层级包裹,如果你在leaflet引入地图的时候对应不上,可能会出现瓦片错乱的问题。这里个人建议直接选择第四种。

3.保存路径选择的文件夹一定不要选择中文文件夹,否则会下载失败。

接下来,就让它慢慢下载吧,我们继续其他工作。

III. 前置条件

A. Vue项目环境搭建

这里不做详细讲解了,如果你作为初学者,这里仅提供思路。

1.安装Node.js和npm:Vue需要依赖Node.js和npm才能运行,可以在官网下载并安装。

2.安装Vue CLI:Vue CLI是Vue的脚手架工具,可以快速搭建Vue项目,安装方法为在命令行中输入npm install -g @vue/cli。

3.创建Vue项目:在命令行中运行vue create <project-name>创建一个Vue项目,其中<project-name>为项目名称。

4.运行项目:进入项目目录后,在命令行中运行npm run serve即可启动项目,然后在浏览器中打开http://localhost:8080/即可访问项目。

5.其他依赖:根据项目需求安装其他需要的依赖,可以使用npm install <package-name>命令安装。

B. Leaflet插件安装

Leaflet - a JavaScript library for interactive mapsicon-default.png?t=N7T8https://leafletjs.com/上述地址是Leaflet的官方网站,如果想查看详细的资料,可以细品。

npm安装库

npm install leaflet --save

IV. 构建离线地图

A. 在Vue项目中引入Leaflet

可以分为全局及局部两种方式引入,按需使用

import L from "leaflet";
import 'leaflet/dist/leaflet.css'

B. 创建地图容器

仅需要创建一个Div容器,确定唯一id。

<template>
  <!-- 地图容器 -->
  <div id="map" class="main_map"></div>
</template>

C. 加载离线地图数据

      initMap() {
        // 创建地图实例,将其绑定到 id 参数为 "map" 的 DOM 元素上※
        this.map = L.map("map");
        // 使用 setView() 方法设置地图中心点坐标(维度,经度)和初始缩放级别※
        this.map.setView([37.56018, 121.18340899999998], 13);
        // 创建 Stamen 图层,并添加到地图上※
        var stamenLayer = L.tileLayer('http://127.0.0.1:8044/{z}/{y}/{x}.png', {
          attribution: '垃圾程序员', // 图层属性信息※
          minZoom: 1, // 最小缩放级别※
          maxZoom: 18 // 最大缩放级别※
        }).addTo(this.map)
      }

看到代码是不是蒙了一下,复制粘贴上去之前你需要先干这几件事。

1.获取中心点的经纬度

中心点是地图的初始显示位置,也就是地图加载完成后第一眼看到的位置。

高德开放平台 | 高德地图API高德开放平台|高德开放平台官网|高德开放平台控制台|官网控制台|控制台|应用管理|应用分析|账号信息|开发者信息|账号权限|KEY管理icon-default.png?t=N7T8https://lbs.amap.com/打开高德开放平台,选择坐标拾取器,尽情操作吧。

2.把下载好的瓦片地图映射出来

在这里你有两条路,一是把瓦图文件复制到项目中,然后配置地址。这种方式适应于小规模测试。二就是把瓦图映射出来,不管以何种方式,常用的一般就是使用Web服务器或者在线存储服务。

因为我是windows下,所以我直接开了个IIS将图片映射出去。如果你也想用IIS做映射,可以按照以下教程。

2.1安装IIS

打开“控制面板”->“程序和功能”->“打开或关闭Windows功能”,勾选Internet Information Services,点击确定即可安装。

2.2添加网站

打开IIS管理器,右键单击“网站”->“添加网站”,设置网站名称和物理路径(选择保存瓦片图片的那个文件夹),选择IP地址以及端口号(端口尽量选择冷门的,防止出现端口冲突)等相关信息,完成网站创建。

2.3开启目录预览

右键打开“目录预览”功能,然后点击启用,否则访问不到文件

2.4测试访问

现在打开浏览器,输入你配置的地址,如果和我一样那就是http://localhost:8044,打开如果和下图一样那就代表可以了。

这样你就得到一个映射出来可以浏览器访问的瓦图地址,配置到代码里即可。

这是最终效果:

D. leaflet基本功能

上述已经完成了离线地图的加载,现在要进行一些简单的操作了。

0.先添加监听事件

        //监听事件
        this.map.on('click', e => {
          let latlng = e.latlng;
          // 将当前点击的经纬度添加到坐标数组中
          this.coordinates.push(latlng);
          //添加图标
          this.addIcon(latlng)
          //添加圆形区域
          this.addCircularArea(latlng)
          //添加弹窗
          this.addPopUps(latlng)
          //添加连线
          this.addConnection()
        })

1.点击地图后,在地图上钉上一个图标

      //添加图标
      addIcon(latlng) {
        // 点击获取地图上的经纬度
        L.marker([latlng.lat, latlng.lng], {
          icon: new L.Icon({
            className: "lmap-icon",
            iconUrl: require('@/assets/icons/flag.png'),
            iconSize: [24, 24],
            iconAnchor: [12, 12],
          })
        }).addTo(this.map);
      },

2.同步生成一个圆形区域

 // 添加圆形区域
      addCircularArea(latlng) {
        L.circle([latlng.lat, latlng.lng], {
          color: '#e2e2e2', //边框颜色
          fillColor: '#ffffff', //内部填充颜色
          fillOpacity: 0.1, //内部的填充透明度
          radius: 500 //圆形的半径
        }).addTo(this.map);
      },

3.同步出现一个弹窗

// 添加弹窗
      addPopUps(latlng) {
        //添加弹框
        L.popup()
          .setLatLng(latlng)
          .setContent('我没有那么想你')
          .openOn(this.map);
      },

4.点击两个点后自动连接一条直线

      // 添加连线
      addConnection() {
        // 创建折线对象并添加到地图上
        L.polyline(this.coordinates, {
          color: '#aaaa00'
        }).addTo(this.map)
      }

效果如下:

完整代码如下:

<!-- 添加人:cxd -->
<!-- 添加日期:2023-12-16 -->
<!-- 描述:离线地图,通过地图瓦片,地图瓦片请自行下载-->
<!-- 注释中表注※的代码为关键点,请自行核对-->
<!-- 不同的框架,不同的样式表均有可能导致在你项目上的实际效果和演示效果不同-->
<!-- 尽信书则不如无书 我认为你要明白其中原理而不是复制粘贴,百变不离其中-->
<template>
  <!-- 地图容器 -->
  <div id="map" class="main_map"></div>
</template>

<script>
  // 引入 Leaflet 库
  import L from 'leaflet'
  export default {
    name: "leafletLoadMapsStamen",
    data() {
      return {
        //坐标数组
        coordinates: []
      };
    },
    mounted() {
      // 初始化地图
      this.initMap();
    },
    methods: {
      initMap() {
        // 创建地图实例,将其绑定到 id 参数为 "map" 的 DOM 元素上※
        this.map = L.map("map");
        // 使用 setView() 方法设置地图中心点坐标(维度,经度)和初始缩放级别※
        this.map.setView([37.56018, 121.18340899999998], 13);
        // 创建 Stamen 图层,并添加到地图上※
        var stamenLayer = L.tileLayer('http://127.0.0.1:8044/{z}/{y}/{x}.png', {
          attribution: '垃圾程序员', // 图层属性信息※
          minZoom: 1, // 最小缩放级别※
          maxZoom: 18 // 最大缩放级别※
        }).addTo(this.map)
        //监听事件
        this.map.on('click', e => {
          let latlng = e.latlng;
          // 将当前点击的经纬度添加到坐标数组中
          this.coordinates.push(latlng);
          //添加图标
          this.addIcon(latlng)
          //添加圆形区域
          this.addCircularArea(latlng)
          //添加弹窗
          this.addPopUps(latlng)
          //添加连线
          this.addConnection()
        })
      },
      //添加图标
      addIcon(latlng) {
        // 点击获取地图上的经纬度
        L.marker([latlng.lat, latlng.lng], {
          icon: new L.Icon({
            className: "lmap-icon",
            iconUrl: require('@/assets/icons/flag.png'),
            iconSize: [24, 24],
            iconAnchor: [12, 12],
          })
        }).addTo(this.map);
      },
      // 添加圆形区域
      addCircularArea(latlng) {
        L.circle([latlng.lat, latlng.lng], {
          color: '#e2e2e2', //边框颜色
          fillColor: '#ffffff', //内部填充颜色
          fillOpacity: 0.1, //内部的填充透明度
          radius: 500 //圆形的半径
        }).addTo(this.map);
      },
      // 添加弹窗
      addPopUps(latlng) {
        //添加弹框
        L.popup()
          .setLatLng(latlng)
          .setContent('我没有那么想你')
          .openOn(this.map);
      },
      // 添加连线
      addConnection() {
        // 创建折线对象并添加到地图上
        L.polyline(this.coordinates, {
          color: '#aaaa00'
        }).addTo(this.map)
      }
    },
  }
</script>

<style>
  /* 设置地图容器的高度和宽度 */
  .main_map {
    height: calc(100vh - 50px) !important;
    width: 100%;
  }
</style>

就这样了,还有很多功能没探索,这就要看你了,加油。

V. 合法使用地图数据

在这里需要提醒大家,请合法使用地图数据。共建文明和谐社会。

你有没有动心,请看着我的眼睛

转载请注明出处或者链接地址:https://www.qianduange.cn//article/7274.html
标签
评论
发布的文章

exceljs

2024-05-11 10:05:00

Java研学-JSON与AJAX

2024-05-10 22:05:37

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!