使用 Mapbox 在 Vue 中开发一个地理信息定位应用

2023-10-26

⭐️ 本文首发自 前端修罗场(点击加入),是一个由 资深开发者 独立运行 的专业技术社区,我专注 Web 技术、Web3、区块链、答疑解惑、面试辅导以及职业发展博主创作的 《前端面试复习笔记》(点击订阅),广受好评,已帮助多人提升实力、拿到 offer。现在订阅,私聊博主即可获取一次 免费的模拟面试/简历指导服务,帮你评估知识点的掌握程度,获得更全面的学习指导意见!

在本文中,我们将大致了解正向地理编码和反向地理编码的概念。 我们将使用 Mapbox 和 Vue.js 2.6.11 构建一个应用这些概念来显示特定位置的应用程序。

什么是地理编码?

地理编码是将基于文本的位置转换为世界位置的地理坐标(通常为经度和纬度)。

地理编码有两种类型:正向和反向。 正向地理编码将位置文本转换为地理坐标,而反向地理编码将坐标转换为位置文本。

我们的应用程序将具有以下基本功能:

  • 允许用户访问带有标记的交互式地图显示;
  • 允许用户随意移动标记,同时显示坐标;
  • 根据用户请求返回基于文本的位置或位置坐标。

使用 Vue CLI 开启项目

我们将使用此存储库中的样板代码进行开发。 它包含一个带有 Vue CLI 和 yarn 作为包管理器的新项目。 你需要克隆该仓库,并确保你使用的是 geocoder/boilerplate 分支。

设置应用程序的文件结构

接下来,我们需要设置项目的文件结构。 将组件文件夹中的 Helloworld.vue 文件重命名为 Index.vue。 并将以下内容复制到 App.vue 文件中:

<template>
  <div id="app">
    <!--Navbar Here -->
    <div>
      <nav>
        <div class="header">
          <h3>Geocoder</h3>
        </div>
      </nav>
    </div>
    <!--Index Page Here -->
    <index />
  </div>
</template>
<script>
import index from "./components/index.vue";
export default {
  name: "App",
  components: {
    index,
  },
};
</script>

在这里,我们已经导入并在本地注册了最近重命名的组件。 我们还添加了一个导航栏来提升我们应用的美感。

我们需要一个 .env 文件来加载环境变量。 继续在项目文件夹的根目录中添加一个。

安装所需的包和库

接下来,我们需要安装所需的库。 这是我们将用于此项目的列表:

  • Mapbox GL JS
  • Mapbox-gl-geocoder
  • Dotenv
  • Axios

根据你首选的包管理器在 CLI 中安装包。 如果你使用 Yarn,请运行以下命令:

cd geocoder && yarn add mapbox-gl @mapbox/mapbox-gl-geocoder axios

or

cd geocoder && npm i mapbox-gl @mapbox/mapbox-gl-geocoder axios --save

在运行安装命令之前,我们首先必须进入 geocoder 文件夹。

使用 Vue 搭建前端

让我们继续为我们的应用程序创建一个布局。 我们需要一个元素来容纳我们的地图,一个区域来显示坐标,同时监听标记在地图上的移动,以及在我们调用反向地理编码 API 时显示位置的东西。 我们可以将所有这些都包含在一个卡片组件中。

将以下内容复制到你的 Index.vue 文件中:

<template>
  <div class="main">
    <div class="flex">
      <!-- Map Display here -->
      <div class="map-holder">
        <div id="map"></div>
      </div>
      <!-- Coordinates Display here -->
      <div class="dislpay-arena">
        <div class="coordinates-header">
          <h3>Current Coordinates</h3>
          <p>Latitude:</p>
          <p>Longitude:</p>
        </div>
        <div class="coordinates-header">
          <h3>Current Location</h3>
          <div class="form-group">
            <input
              type="text"
              class="location-control"
              :value="location"
              readonly
            />
            <button type="button" class="copy-btn">Copy</button>
          </div>
          <button type="button" class="location-btn">Get Location</button>
        </div>
      </div>
    </div>
  </div>
</template>

启动开发服务器,查看我们目前拥有的内容:

yarn serve

or

npm run serve

我们的应用程序现在应该是这样的:

在这里插入图片描述
左边的空白点看起来不对。 它应该容纳我们的地图显示。 接下来,让我们继续补充一下。

使用 Mapbox 进行交互式地图显示

我们需要做的第一件事是访问 Mapbox GL 和 Geocoder 库。 我们将首先在 Index.vue 文件中导入 Mapbox GL 和 Geocoder 库

import axios from "axios";
import mapboxgl from "mapbox-gl";
import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder";
import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";

Mapbox 需要一个唯一的访问令牌来计算地图矢量。 获取你的 token,并将其作为环境变量添加到你的 .env 文件中。

VUE_APP_MAP_ACCESS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

我们还需要定义有助于将地图图块放在数据实例中的属性。 在我们导入库的位置下方添加以下内容:

export default {
  data() {
    return {
      loading: false,
      location: "",
      access_token: process.env.VUE_APP_MAP_ACCESS_TOKEN,
      center: [0, 0],
      map: {},
    };
  },
}
  • location 属性将被建模为我们在脚手架中的输入。 我们将使用它来处理反向地理编码(即显示坐标中的位置)。
  • center 属性包含我们的坐标(经度和纬度)。 正如我们稍后将看到的,这对于将我们的地图图块放在一起至关重要。
  • access_token 属性指的是我们之前添加的环境变量。
  • map 属性充当我们地图组件的构造函数。

让我们继续创建一个方法来绘制我们的交互式地图,其中嵌入了我们的正向地理编码器。 这个方法是我们的基础函数,充当我们的组件和 Mapbox GL 之间的中介; 我们将调用这个方法 createMap。 在数据对象下面添加:

mounted() {
  this.createMap()
},

methods: {
  async createMap() {
    try {
      mapboxgl.accessToken = this.access_token;
      this.map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        center: this.center,
        zoom: 11,
      });

    } catch (err) {
      console.log("map error", err);
    }
  },
},

为了创建我们的地图,我们指定了一个容纳地图的容器、一个用于地图显示格式的 style 属性以及一个用于容纳坐标的 center 属性。 center 属性是一个数组类型,保存经度和纬度。

Mapbox GL JS 根据页面上的这些参数初始化我们的地图,并返回一个 Map 对象给我们。 Map 对象引用我们页面上的地图,同时公开使我们能够与地图交互的方法和属性。 我们已将此返回的对象存储在我们的数据实例 this.map 中。

使用 Mapbox 地理编码器进行前向地理编码

现在,我们将添加地理编码器和自定义标记。 地理编码器通过将基于文本的位置转换为坐标来处理正向地理编码。 这将以附加到我们地图的搜索输入框的形式出现。

在我们上面的 this.map 初始化下面添加以下内容:

let geocoder =  new MapboxGeocoder({
    accessToken: this.access_token,
    mapboxgl: mapboxgl,
    marker: false,
  });

this.map.addControl(geocoder);

geocoder.on("result", (e) => {
  const marker = new mapboxgl.Marker({
    draggable: true,
    color: "#D80739",
  })
    .setLngLat(e.result.center)
    .addTo(this.map);
  this.center = e.result.center;
  marker.on("dragend", (e) => {
    this.center = Object.values(e.target.getLngLat());
  });
});

在这里,我们首先使用 MapboxGeocoder 构造函数创建了一个新的地理编码器实例。 这会根据提供的参数初始化地理编码器,并返回一个对象,暴露给方法和事件。 accessToken 属性指的是我们的 Mapbox 访问令牌,mapboxgl 指的是当前使用的地图库

我们应用的核心是自定义标记;地理编码器默认带有一个。然而,这并不能为我们提供所需的所有定制。因此,我们禁用了它。

继续前进,我们将新创建的地理编码器作为参数传递给 addControl 方法,由我们的地图对象公开给我们。 addControl 接受一个控件作为参数。

为了创建我们的自定义标记,我们使用了地理编码器对象向我们公开的事件。 on 事件侦听器使我们能够订阅地理编码器中发生的事件。它接受各种事件作为参数。我们正在监听 result 事件,该事件在设置输入时触发。

简而言之,在结果上,我们的标记构造函数根据我们提供的参数(在本例中为可拖动属性和颜色)创建一个标记。它返回一个对象,我们使用 setLngLat 方法来获取我们的坐标。我们使用 addTo 方法将自定义标记附加到现有地图。最后,我们用新坐标更新实例中的 center 属性。

我们还必须跟踪自定义标记的移动。 我们通过使用 dragend 事件监听器实现了这一点,并且我们用当前坐标更新了我们的 center 属性。

让我们更新模板以显示我们的交互式地图和转发地理编码器。 使用以下内容更新我们模板中的坐标显示部分:

<div class="coordinates-header">
  <h3>Current Coordinates</h3>
  <p>Latitude: {{ center[0] }}</p>
  <p>Longitude: {{ center[1] }}</p>
</div>

还记得我们如何总是在事件发生后更新我们的中心属性吗? 我们在这里根据当前值显示坐标。

为了提升我们应用的美感,在 index.html 文件的 head 部分添加以下 CSS 文件。 将此文件放在公用文件夹中。

<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v0.53.0/mapbox-gl.css" rel="stylesheet" />

在这里插入图片描述

使用 Mapbox API 反向地理编码位置

现在,我们将处理反向地理编码我们的坐标到基于文本的位置。 让我们编写一个方法来处理它并使用模板中的 Get Location 按钮触发它。

Mapbox 中的反向地理编码由反向地理编码 API 处理。 这接受经度、纬度和访问令牌作为请求参数。 此调用返回响应负载——通常带有各种详细信息。 我们关注的是特征数组中的第一个对象,即反向地理编码位置所在的位置。

我们需要创建一个函数,将我们想要到达的位置的经度、纬度和 access_token 发送到 Mapbox API。 我们需要发送它们以获取该位置的详细信息。

最后,我们需要使用对象中 place_name 键的值更新实例中的 location 属性。

在 createMap() 函数下面,让我们添加一个新函数来处理我们想要的。 它应该是这样的:

async getLocation() {
  try {
    this.loading = true;
    const response = await axios.get(
      `https://api.mapbox.com/geocoding/v5/mapbox.places/${this.center[0]},${this.center[1]}.json?access_token=${this.access_token}`
    );
    this.loading = false;
    this.location = response.data.features[0].place_name;
  } catch (err) {
    this.loading = false;
    console.log(err);
  }
},

该函数向 Mapbox API 发出 GET 请求。 响应包含 place_name — 所选位置的名称。 我们从响应中获取它,然后将其设置为 this.location 的值。

完成后,我们需要编辑和设置将调用我们创建的这个函数的按钮。 我们将使用一个点击事件监听器——当用户点击它时它会调用 getLocation 方法。 继续并将按钮组件编辑为此。

<button
  type="button"
  :disabled="loading"
  :class="{ disabled: loading }"
  class="location-btn"
  @click="getLocation"
>
  Get Location
</button>

接着,让我们附加一个将显示的位置复制到剪贴板的功能。 在 getLocation 函数下方添加:

copyLocation() {
  if (this.location) {
    navigator.clipboard.writeText(this.location);
    alert("Location Copied")
  }
  return;
},

更新 Copy 按钮组件以触发此操作:

<button type="button" class="copy-btn" @click="copyLocation">

结尾

在本文中,我们研究了使用 Mapbox 进行地理编码。 我们构建了一个地理编码应用程序,它将基于文本的位置转换为坐标,在交互式地图上显示位置,并根据用户的请求将坐标转换为基于文本的位置。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Mapbox 在 Vue 中开发一个地理信息定位应用 的相关文章

随机推荐

  • Prometheus详解(四)——Prometheus简单使用

    今天继续给大家介绍Linux运维相关知识 本文主要内容是Prometheus简单使用 在上文Prometheus详解 三 Prometheus安装部署中 我们介绍了Prometheus的安装和部署 今天 我们就来介绍一下Prometheus
  • fork()父子进程变量之间的关系与信号的响应

    1 变量关系 根据 unix 高级环境编程 中的一句话 子进程和父进程继续执行fork调用之后的指令 子进程是父进程的副本 例如 子进程获取父进程数据空间 堆和栈的副本 注意 这是子进程所拥有的副本 父子进程并不共享这些存储空间部分 父子进
  • 尚品汇细节分析-Vue项目中如何实现自定义校验规则

    需求 当用户登录时 会输入用户名和密码 用户名不能为空 密码的长度不能小于6位 需要在用户在点击登录按钮前 进行验证是否通过我们设定的规则 如果通过则放行 如果不通过则会进行提示 效果图 结合Element UI来实现校验规则 1 页面元素
  • SQL SERVER 2000 遍历父子关系数据的表(二叉树)获得所有子节点 所有父节点及节点层数函数

    SQL SERVER 2000 遍历父子关系數據表 二叉树 获得所有子节点 所有父节点及节点层数函数 Geovin Du 涂聚文 建立測試環境 Create Table GeovinDu ID Int fatherID Int Name V
  • 课程设计-基于Java web的网吧管理系统

    项目编号 B01 项目名称 基于Java jsp Servlet的网吧管理系统 源码编号 BK05 项目类型 Java web项目 JavaEE 当前版本 V1 0 0版本 用户类型 只有管理员 单角色 项目架构 B S架构 设计思想 MV
  • IDEA快捷键(WIN10,持续更新)

    IDEA快捷键 以下所说的都是windows下的默认快捷键 可以通过File gt Settings gt Keymap 对快捷键进行修改 查看源码 ctrl 鼠标左键 重写父类方法 ctrl o 快速写for循环 20 for或fori
  • python给图片加雾

    调用的是cv2的addWeighted函数 增雾结果来看效果还蛮不错的 import numpy as np import cv2 as cv import os import random file C Users Ilearn Desk
  • C++图书管理系统(简单版)

    1 系统需求 图书管理系统是一个可以记录图书借记和存储的工具 本教程主要利用C 来实现一个图书管理系统 系统中需要实现的功能如下 添加书籍 向图书管理系统中添加新书 信息包括 书名 书的价格 书的编号 最多记录1000本 显示书籍 显示图书
  • STC15单片机实战项目 - 硬件调试

    硬件调试 一 调试工具 1 直流电源 测试5 28V供电 2 手机充电线 测试USB供电 程序烧录 3 万用表 测量电压 4 示波器 测量开关波形 纹波等 二 焊接样机 焊接好的样机如下图 说明 作为硬件工程师 平时要多练焊接 练就一流的焊
  • 第二课 什么是norm game?(An Evolutionary Approach to Norms)

    文章目录 前置课程 An Evolutionary Approach to Norms Simulation of the Norms Game first step second step third step fourth step f
  • 【论文笔记】Darts-可微神经架构搜索(一)

    是什么 darts是什么 全称 Differentiable ARchiTecture Search 它是一种新 2018 的NAS 神经架构搜索 方法 NAS是什么 全称 neural architecture search 神经架构搜索
  • JS逆向时碰到了恶心的死代码怎么办?手把手教你解决!

    文章作者 夜幕团队 NightTeam 蔡老板 Loco 润色 校对 夜幕团队 NightTeam Loco 你是否也曾有过 在逆向时看到一大坨代码 但自己却无从下手 的遭遇 你是否也曾有过 跟着代码跳了很久之后 才发现那一大坨代码其实没有
  • MySQL的运行机制是什么?它有哪些引擎?

    目录 整个 SQL 的执行流程 1 查询缓存的利弊 2 如何选择数据库引 3 InnoDB 自增主键 整个 SQL 的执行流程 首先客户端端先要发送用户信息去服务端进行授权认证 如果使用的是命令行工具 通常需要输入如下信息 mysql h
  • 《Flutter入门疑难杂症》 Flutter的UI适配方案

    本文后面已经被我用新的extension大法替代咯 有兴趣的可以看我写的这篇文章 https blog csdn net WZAHD article details 111404843 spm 1001 2014 3001 5501 话不多
  • TimeLine 的使用说明

    一 关于 TimeLine Timeline是一套基于时间轴的多轨道动画系统 它支持可视化编辑 实时预览 这一个技术相对于其他动画系统 最大的区别就是 Timeline可以针对多个游戏物体做出的一系列动画 主要用于过场动画的制作 实现电影级
  • 如何记录键盘SIGQUIT次数

    Unix信号 在计算机科学中 信号 英语 Signals 是Unix 类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式 它是一种异步的通知机制 用来提醒进程一个事件已经发生 当一个信号发送给一个进程 操作系统中断了进
  • EOS与以太坊有哪些区别?

    以太坊是一个专门为开发和运行去中心化应用 DAPP 搭建的智能合约平台 EOS与以太坊类似 同样是基于智能合约和区块链而搭建 但是 从技术和设计理念等方面来看 这两者之间实际上存在明显的区别 那么EOS和以太坊到底有什么区别呢 这个问题要从
  • 深入了解接口测试:Postman 接口测试指南

    在现代软件开发生命周期中 接口测试是一个至关重要的部分 使用 Postman 这一工具 可以轻松地进行 接口测试 以下是一份简单的使用教程 帮助你快速上手 安装 Postman 首先 你需要在电脑上安装 Postman 你可以从官网上下载并
  • python如何取0到无穷大_python如何表示无穷大

    float inf 表示正无穷 float inf 或 float inf 表示负无穷 其中 inf 均可以写成 Inf 起步 python中整型不用担心溢出 因为python理论上可以表示无限大的整数 直到把内存挤爆 而无穷大在编程中常常
  • 使用 Mapbox 在 Vue 中开发一个地理信息定位应用

    本文首发自 前端修罗场 点击加入 是一个由 资深开发者 独立运行 的专业技术社区 我专注 Web 技术 Web3 区块链 答疑解惑 面试辅导以及职业发展 博主创作的 前端面试复习笔记 点击订阅 广受好评 已帮助多人提升实力 拿到 offer