(geoLocation API )地图定位功能

893 阅读8分钟

实现思路

  1. 引入必要的依赖

    • 引入@amap/amap-jsapi-loader,用于按需加载高德地图API。
  2. 定义组件数据

    • map:存储地图实例。
    • userPosition:存储用户的当前位置坐标。
    • search:存储地点搜索插件实例。
    • driving:存储路线规划插件实例。
    • searchResult:存储搜索结果数组。
    • start 和 end:分别存储起点和终点的地址字符串。
    • autocompleteStart 和 autocompleteEnd:分别存储起点和终点的自动完成插件实例。
  3. 初始化地图 (initMap 方法):

    • 使用@amap/amap-jsapi-loader加载高德地图API及其所需的插件。
    • 创建并配置地图实例。
    • 创建并配置地点搜索插件实例。
    • 创建并配置路线规划插件实例。
    • 创建并配置自动完成插件实例。
    • 设置监听事件以处理地点搜索结果的变化。
  4. 获取用户当前位置 (getLocation 方法):

    • 使用浏览器的navigator.geolocation API来获取用户的当前位置。
    • 如果成功获取位置,则更新userPosition变量并调用centerOnUser方法。
    • 如果获取位置失败,则输出错误信息。
  5. 将地图中心定位到用户当前位置 (centerOnUser 方法):

    • 如果已有用户的位置信息,则设置地图的中心点和缩放级别。
  6. 搜索地点 (searchLocation 方法):

    • 调用地点搜索插件的search方法,传入起点地址进行搜索。
  7. 规划路线 (planRoute 方法):

    • 调用路线规划插件的search方法,传入起点和终点地址进行路线规划。
  8. 自动补全输入框 (autocompleteStartautocompleteEnd 方法):

    • 更新起始点和终点的地址字符串。
  9. 组件挂载完成后执行的操作 (mounted 生命周期钩子):

    • 调用initMap方法初始化地图和相关插件。

代码实现

1. 安装依赖

首先,你需要安装 @amap/amap-jsapi-loaderr 这个包,它可以帮助我们在项目中加载高德地图的 JavaScript API。

npm install a@amap/amap-jsapi-loader

2. 创建组件

接下来,我们将创建一个名为 Map.vue 的组件,这个组件包含了地图的所有功能。

模板 (template)

在这个模板中,我们定义了一个包含地图容器和控制按钮的结构。

<template>
  <div class="map-container">
    <!-- 地图容器 -->

    <div ref="mapContainer" class="map" />
    <!-- 控制面板 -->
    <div class="controls">
      <!-- 获取用户当前位置按钮 -->
      <button @click="getLocation">获取当前位置</button>
      <!-- 将地图中心定位到用户当前位置按钮 -->
      <button @click="centerOnUser">中心定位</button>
      <!-- 起点输入框 -->
      <input type="text" v-model="start" placeholder="起点" @input="autocompleteStart" />
      <!-- 终点输入框 -->
      <input type="text" v-model="end" placeholder="终点" @input="autocompleteEnd" />
      <!-- 搜索地点按钮 -->
      <button @click="searchLocation">搜索地点</button>
      <!-- 规划路线按钮 -->
      <button @click="planRoute">规划路线</button>
    </div>

  </div>
</template>

脚本 (script)

<script> 部分,我们定义了组件的数据和方法。

数据 (data)

这里定义了一些数据属性,如 map、userPosition 等,它们将在组件初始化时被使用。

data() {
    // 定义组件的数据
    return {
      // 地图实例
      map: null,
      // 用户当前位置
      userPosition: null,
      // 地点搜索插件实例
      search: null,
      // 路线规划插件实例
      driving: null,
      // 搜索结果数组
      searchResult: [],
      // 起点地址
      start: '',
      // 终点地址
      end: '',
      // 起点自动完成插件实例
      autocompleteStart: null,
      // 终点自动完成插件实例
      autocompleteEnd: null,
    };
  },
方法 (methods)

这些方法用于处理各种地图功能,例如获取用户位置、搜索地点等。


methods: {
    // 初始化地图
    initMap() {
      // 加载高德地图API
      load({
        key: '你的高德地图key', // 高德地图API密钥
        version: '2.0', // 高德地图API版本
        plugins: ['AMap.PlaceSearch', 'AMap.Driving', 'AMap.Autocomplete'], // 需要加载的插件
      }).then(AMap => {
        // 创建地图实例
        this.map = new AMap.Map(this.$refs.mapContainer, {
          zoom: 13, // 缩放级别
          center: [116.39, 39.9] // 地图初始中心点
        });

        // 创建地点搜索插件实例
        this.search = new AMap.PlaceSearch({
          city: '010', // 默认城市
          pageIndex: 1, // 分页索引
          pageSize: 10, // 单页最多返回结果数
          map: this.map, // 将结果在地图上显示
          panel: this.$refs.searchResultPanel, // 结果列表所在的容器
        });

        // 创建路线规划插件实例
        this.driving = new AMap.Driving({
          map: this.map, // 显示路线的地图实例
          panel: this.$refs.routePanel, // 路线面板容器
          policy: AMap.DrivingPolicy.LEAST_TIME, // 优先考虑时间最短的路线
          extend: 'all', // 返回所有数据
          autoFitView: true, // 自动调整视野
        });

        // 创建自动完成插件实例
        this.autocompleteStart = new AMap.Autocomplete({
          input: this.$refs.start, // 输入框引用
          city: '010', // 城市代码
          panel: this.$refs.searchResultPanel, // 自动完成结果列表所在的容器
        });

        this.autocompleteEnd = new AMap.Autocomplete({
          input: this.$refs.end, // 输入框引用
          city: '010', // 城市代码
          panel: this.$refs.searchResultPanel, // 自动完成结果列表所在的容器
        });

        // 监听地点搜索结果变化
        AMap.event.addListener(this.search, 'placessearchcomplete', (results) => {
          this.searchResult = results.poiList.pois; // 更新搜索结果
        });

        // 触发搜索
        this.search.search(this.start); // 起始位置
      });
    },

    // 获取用户当前位置
    getLocation() {
      if (navigator.geolocation) {
        // 使用浏览器Geolocation API获取位置
        navigator.geolocation.getCurrentPosition(
          position => {
            // 成功获取位置后的回调函数
            this.userPosition = {
              lat: position.coords.latitude, // 纬度
              lng: position.coords.longitude // 经度
            };
            this.centerOnUser(); // 将地图中心定位到用户位置
          },
          error => {
            // 获取位置失败的回调函数
            console.error('无法获取地理位置信息:', error);
          }
        );
      } else {
        // 浏览器不支持Geolocation API
        alert('您的浏览器不支持 Geolocation API');
      }
    },

    // 将地图中心定位到用户当前位置
    centerOnUser() {
      if (this.userPosition) {
        // 设置地图中心
        this.map.setCenter([this.userPosition.lng, this.userPosition.lat]);
        // 设置地图缩放级别
        this.map.setZoom(15);
      }
    },

    // 搜索地点
    searchLocation() {
      // 触发地点搜索
      this.search.search(this.start);
    },

    // 规划路线
    planRoute() {
      // 规划从起点到终点的路线
      this.driving.search(this.start, this.end);
    },

    // 起点输入框自动补全
    autocompleteStart(e) {
      // 更新起点地址
      this.start = e.target.value;
    },

    // 终点输入框自动补全
    autocompleteEnd(e) {
      // 更新终点地址
      this.end = e.target.value;
    },
  },
生命周期钩子 (mounted)

mounted 钩子会在组件挂载完成后执行,这里我们调用 initMap 方法初始化地图。


  // 组件挂载完成时调用的方法
  mounted() {
    this.initMap(); // 初始化地图
  },
样式 (style scoped)

<style scoped> 中,我们为组件定义了一些基本的样式。


<style scoped>
/* 地图容器样式 */
.map-container {
  position: relative;
  width: 100%;
  height: 500px;
}

/* 地图样式 */
.map {
  width: 100%;
  height: 100%;
}

/* 控制面板样式 */
.controls {
  position: absolute;
  top: 10px;
  left: 10px;
  background-color: white;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
</style>

3. 初始化地图 (initMap 方法)

initMap 方法中,我们使用 amap-jsapi-loader 加载高德地图的 JavaScript API,并创建地图实例。

 // 初始化地图
    initMap() {
      // 加载高德地图API
      load({
        key: '你的高德地图key', // 高德地图API密钥
        version: '2.0', // 高德地图API版本
        plugins: ['AMap.PlaceSearch', 'AMap.Driving', 'AMap.Autocomplete'], // 需要加载的插件
      }).then(AMap => {
        // 创建地图实例
        this.map = new AMap.Map(this.$refs.mapContainer, {
          zoom: 13, // 缩放级别
          center: [116.39, 39.9] // 地图初始中心点
        });

        // 创建地点搜索插件实例
        this.search = new AMap.PlaceSearch({
          city: '010', // 默认城市
          pageIndex: 1, // 分页索引
          pageSize: 10, // 单页最多返回结果数
          map: this.map, // 将结果在地图上显示
          panel: this.$refs.searchResultPanel, // 结果列表所在的容器
        });

        // 创建路线规划插件实例
        this.driving = new AMap.Driving({
          map: this.map, // 显示路线的地图实例
          panel: this.$refs.routePanel, // 路线面板容器
          policy: AMap.DrivingPolicy.LEAST_TIME, // 优先考虑时间最短的路线
          extend: 'all', // 返回所有数据
          autoFitView: true, // 自动调整视野
        });

        // 创建自动完成插件实例
        this.autocompleteStart = new AMap.Autocomplete({
          input: this.$refs.start, // 输入框引用
          city: '010', // 城市代码
          panel: this.$refs.searchResultPanel, // 自动完成结果列表所在的容器
        });

        this.autocompleteEnd = new AMap.Autocomplete({
          input: this.$refs.end, // 输入框引用
          city: '010', // 城市代码
          panel: this.$refs.searchResultPanel, // 自动完成结果列表所在的容器
        });

        // 监听地点搜索结果变化
        AMap.event.addListener(this.search, 'placessearchcomplete', (results) => {
          this.searchResult = results.poiList.pois; // 更新搜索结果
        });

        // 触发搜索
        this.search.search(this.start); // 起始位置
      });
    },

4. 获取用户位置 (getLocation 方法)

我们使用浏览器的 navigator.geolocation API 来获取用户的当前位置。


 // 获取用户当前位置
    getLocation() {
      if (navigator.geolocation) {
        // 使用浏览器Geolocation API获取位置
        navigator.geolocation.getCurrentPosition(
          position => {
            // 成功获取位置后的回调函数
            this.userPosition = {
              lat: position.coords.latitude, // 纬度
              lng: position.coords.longitude // 经度
            };
            this.centerOnUser(); // 将地图中心定位到用户位置
          },
          error => {
            // 获取位置失败的回调函数
            console.error('无法获取地理位置信息:', error);
          }
        );
      } else {
        // 浏览器不支持Geolocation API
        alert('您的浏览器不支持 Geolocation API');
      }
    },

5. 将地图中心定位到用户位置 (centerOnUser 方法)

当用户位置获取成功后,我们可以将地图的中心移动到用户的位置,并调整缩放级别。


// 将地图中心定位到用户当前位置
    centerOnUser() {
      if (this.userPosition) {
        // 设置地图中心
        this.map.setCenter([this.userPosition.lng, this.userPosition.lat]);
        // 设置地图缩放级别
        this.map.setZoom(15);
      }
    },

6. 搜索地点 (searchLocation 方法)

当用户输入起始地址后,我们可以调用 search 插件的方法来搜索地点。


// 搜索地点
    searchLocation() {
      // 触发地点搜索
      this.search.search(this.start);
    },

7. 规划路线 (planRoute 方法)

当用户输入了起始和终止地址后,我们可以调用 driving 插件的方法来规划路线。


// 规划路线
    planRoute() {
      // 规划从起点到终点的路线
      this.driving.search(this.start, this.end);
    },

8. 自动补全 (autocompleteStart 和 autocompleteEnd 方法)

我们还可以为输入框添加自动补全功能,使用户能够快速选择地址。


// 起点输入框自动补全
    autocompleteStart(e) {
      // 更新起点地址
      this.start = e.target.value;
    },

    // 终点输入框自动补全
    autocompleteEnd(e) {
      // 更新终点地址
      this.end = e.target.value;
    },
  },

代码解释

HTML 结构

  • 地图容器 (map-container):这是整个应用的容器,它包含了地图本身和控制面板两部分。

    • 地图容器 (map):这是实际显示地图的地方,使用ref属性将其与Vue实例中的方法关联起来,以便在JavaScript中访问这个DOM元素。

    • 控制面板 (controls):这是一个包含按钮和输入框的区域,用于控制地图的行为。

      • 获取当前位置按钮:点击后触发getLocation方法。
      • 中心定位按钮:点击后触发centerOnUser方法,将地图中心移动到用户当前位置。
      • 起点输入框:用户可以在这里输入起点地址,输入时触发autocompleteStart方法。
      • 终点输入框:用户可以在这里输入终点地址,输入时触发autocompleteEnd方法。
      • 搜索地点按钮:点击后触发searchLocation方法,搜索起点位置。
      • 规划路线按钮:点击后触发planRoute方法,规划从起点到终点的路线。

Vue 实例

数据定义 (data)

  • map: 地图实例变量。
  • userPosition: 存储用户的当前位置坐标。
  • search: 地点搜索插件实例。
  • driving: 路线规划插件实例。
  • searchResult: 存储搜索结果的数组。
  • start: 起点地址字符串。
  • end: 终点地址字符串。
  • autocompleteStart: 起点地址自动完成插件实例。
  • autocompleteEnd: 终点地址自动完成插件实例。

方法 (methods)

  • initMap: 初始化地图,加载高德地图API并创建地图实例及相关插件。

    • 加载高德地图API: 使用@amap/amap-jsapi-loader加载高德地图API和所需插件。
    • 创建地图实例: 设置地图的缩放级别和中心点。
    • 创建地点搜索插件 (PlaceSearch): 配置搜索的城市、分页索引、每页返回的结果数量,并指定地图和结果列表容器。
    • 创建路线规划插件 (Driving): 配置地图实例、路线面板容器、路线规划策略(例如最短时间)和其他选项。
    • 创建自动完成插件 (Autocomplete): 配置输入框引用、城市代码和结果列表容器。
  • getLocation: 使用浏览器的Geolocation API获取用户的当前位置。

    • 如果浏览器支持Geolocation API,则调用getCurrentPosition方法获取位置。
    • 获取成功后,设置userPosition
    • 获取失败时,在控制台输出错误信息。
  • centerOnUser: 将地图中心定位到用户当前位置。

    • 如果userPosition存在,则设置地图中心和缩放级别。
  • searchLocation: 触发地点搜索插件的搜索操作。

    • 使用当前的start值作为搜索关键词。
  • planRoute: 根据起点和终点地址规划路线。

    • 使用startend作为起止点进行路线规划。
  • autocompleteStart: 更新起点地址。

    • 当输入框内容改变时触发,更新start的值。
  • autocompleteEnd: 更新终点地址。

    • 当输入框内容改变时触发,更新end的值。

生命周期钩子 (mounted)

  • mounted: 在组件挂载完成后执行,调用initMap方法初始化地图。

CSS 样式

  • 地图容器样式 (map-container):

    • 宽度和高度设置为100%,以使地图容器占据全部空间。
    • 使用相对定位,以便绝对定位内部元素。
  • 地图样式 (map):

    • 设置宽度和高度,以确保地图完全填充容器。
  • 控制面板样式 (controls):

    • 使用绝对定位,使其固定在地图容器的左上角。
    • 设置背景色、内边距、圆角和阴影,以提高视觉效果。