入门级教学!vue2使用天地图实现地图选点+Bounds搜索

lxf2023-05-18 00:56:35

前言

此篇文章灵感来自于最近在工作中所遇到的地图上的需求。
由于好奇心的驱使,我在4月参与了部门的地图专业化团队,此团队负责对有地图功能的项目遇见的地图问题进行问题排查以及功能实现。最近在这个团队中,我遇到了这样的一个需求,秉着对知识渴望的原则,并且通过查阅文章并没有查到准确的解决方案,所以写下此篇文章,希望给遇到这种问题的大佬们提供一个"避风港"。

需求分析

整体的需求大概是这样:

  1. 用户需要提交一个表单,表单项有一项为类似所选地址字段
  2. 点击地址选择跳转地图页面,可以进行地图选点以及搜索地点
  3. 将选择的点位信息返回给表单页

那么笔者想对第二点功能进行重点的介绍并实现这个功能,地图所选种类为天地图,所以在项目中使用天地图的大佬们可以仔细地看一下噢~

前期准备

在实现这个功能之前,我们要到天地图->控制台,注册账号并申请自己的key,想必熟悉地图开发的你们都很熟悉这个步骤,这里就不多说了,贴上一张图叭~

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 然后我来说下实现这个功能我的大致思路叭:

  • 首先我们要了解在vue中如何初始化一个天地图
  • 既然有选择点位,那么就要了解地图的点击事件以及如何在地图添加和删除点标记的方法
  • 根据bounds搜索点位,emm暂且不知道如何实现,看看文档怎么说的

由于文档都是用html形式呈现的例子,而且阅读文档还需要花费一些时间,功能还是要转换到vue中使用,所以我就为大佬们写好在vue中功能的代码,方便大家查阅吧~

功能实现

初始化地图

查阅一番,天地图的引入方式需要我们到vue项目中的index.html通过script标签引入外部链接,key值换成申请的key即可。

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 新建Map.vue文件,给定一个container容器并赋予宽高,按照如下方式即可初始化一个天地图

<template>
  <div id="container"></div>
</template>

<script>
    export default {
      name: 'MapComponent',
      mounted() {
        this.initMap()
      },
      data() {
        return {
          map: null,
        }
      },
      methods: {
        // 初始化地图
        initMap() {
          this.map = new T.Map('container', {
            projection: 'EPSG:4326',
          })
          this.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 12)
        },
      },
    }
</script>

<style scoped>
    #container {
      width: 100%;
      height: 400px;
    }
</style>

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 这样,一个天地图就初始化成功了!

地图选点获取地址

我们要注册地图点击事件,点击后在所选的经纬度添加点位,获取地址我们要借助天地图的引擎接口工具中逆地理编码api进行经纬度转换。


当我们注册好地图点击事件后,所获取的信息如图展示

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 当我们获取到地图返回的经纬度之后就可以进行点位添加 入门级教学!vue2使用天地图实现地图选点+Bounds搜索

那么我们在选点时还要清空上一次选择的点位,选点功能就实现了

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 当我们获取到点位后可通过天地图提供的Geocoder逆地理编码进行地址转换 入门级教学!vue2使用天地图实现地图选点+Bounds搜索 这样,地图选点并获取点位信息的功能就完成了,下面贴上代码,供大佬们 "食用" !
<template>
  <div id="container"></div>
</template>

<script>
export default {
  name: 'MapComponent',
  mounted() {
    this.initMap()
  },
  data() {
    return {
      map: null,
      marker: null,
      geocode: null,
    }
  },
  methods: {
    // 初始化地图
    initMap() {
      this.map = new T.Map('container', {
        projection: 'EPSG:4326',
      })
      this.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 14)
      //创建对象
      this.geocode = new T.Geocoder()
      this.handleClick()
    },

    // 地图选点
    handleClick() {
      let self = this
      self.map.on('click', function (ev) {
        // 逆地理编码解析点位
        self.geocode.getLocation(ev.lnglat, function (res) {
          if (res.status == 0) console.log(res.formatted_address)
        })
        if (self.marker) {
          self.map.clearOverLays()
        }
        const { lng, lat } = ev.lnglat
        //创建标注对象
        self.marker = new T.Marker(new T.LngLat(lng, lat))
        //向地图上添加标注
        self.map.addOverLay(self.marker)
      })
    },
  },
}
</script>

<style scoped>
#container {
  width: 100%;
  height: 600px;
}
</style>

Bounds搜索点位获取信息

首先我们要知道所选城市的四角点坐标,也是天地图提供的根据城市名称获取行政区划信息方法

入门级教学!vue2使用天地图实现地图选点+Bounds搜索 有了这组数据我们就可以使用bounds搜索的方法了,实现效果如图

入门级教学!vue2使用天地图实现地图选点+Bounds搜索

这样,地图搜索点位信息的功能就完成了,下面贴上代码,供大佬们 "食用" !

<template>
  <div>
    <div id="container"></div>
    <input type="text" v-model="searchValue" />
    <button @click="handleSearch">搜索</button>
  </div>
</template>

<script>
export default {
  name: 'MapComponent',
  mounted() {
    this.initMap()
  },
  data() {
    return {
      map: null,
      marker: null,
      geocode: null,
      searchValue: '',
      localsearch: null,
      addressArr: [],
      bounds: null,
    }
  },
  methods: {
    // 初始化地图
    initMap() {
      this.map = new T.Map('container', {
        projection: 'EPSG:4326',
      })
      this.map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 11)
      //创建对象
      this.geocode = new T.Geocoder()
      this.handleClick()
    },

    // 地图选点
    handleClick() {
      let self = this
      self.map.on('click', function (ev) {
        // 逆地理编码解析点位
        self.geocode.getLocation(ev.lnglat, function (res) {
          if (res.status == 0) console.log(res.formatted_address)
        })
        if (self.marker) {
          self.map.clearOverLays()
        }
        const { lng, lat } = ev.lnglat
        //创建标注对象
        self.marker = new T.Marker(new T.LngLat(lng, lat))
        //向地图上添加标注
        self.map.addOverLay(self.marker)
      })
    },

    // 点位搜索
    handleSearch() {
      let config = {
        pageCapacity: 10, //每页显示的数量
        onSearchComplete: this.localSearchResult, //接收数据的回调函数
      }

      this.localsearch = new T.LocalSearch(this.map, config)

      this.bounds = new T.LngLatBounds(
        new T.LngLat(115.422051, 40.978643),
        new T.LngLat(117.383319, 39.455766)
      )

      this.localsearch.searchInBounds(this.searchValue, this.bounds)
    },

    localSearchResult(res) {
      const { pois } = res

      console.log(pois)
      if (pois === false) {
        this.addressArr === []
      } else {
        this.addressArr = pois
        for (let i = 0; i < pois.length; i++) {
          let lnglatArr = pois[i].lonlat.split(' ')
          let lnglat = new T.LngLat(lnglatArr[0], lnglatArr[1])
          let marker = new T.Marker(lnglat)
          this.map.addOverLay(marker)
        }
      }
    },
  },
}
</script>

<style scoped>
#container {
  width: 100%;
  height: 400px;
}
</style>

总结一下

其实功能实现的难度不大,就是调用文档给出的一些api方法,但是查阅文档阅读起来想实现两种功能确实耗费一些时间,而且对于新手来讲,功能的关联性有时候会摸不到头脑;当然感兴趣的小伙伴可以阅读下官方文档(提倡阅读文档哦!)

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!