• 【vue2高德地图api】03-完善展示页,并且调用poi搜索接口


    系列文章目录



    前言

    实现样式效果如图,比较复杂,内容较多。会在api文件夹创建接口,会在components写一个组件,阅读大概10分钟
    在这里插入图片描述


    一、编写页面内容+样式

    1.1 html内容

    复制这块,放在 地图的div下面

    <div class="main">
      
      <h4 class="title">
        <van-icon name="location-o" />
        {{ locationInfo.formattedAddress }}
      h4>
      
      <van-search v-model="input" placeholder="请输入搜索关键词" readonly @focus="onJumpSearch" />
      
      <van-dropdown-menu>
        <van-dropdown-item title="位置距离" v-model="radius" :options="radiusList" @change="getParkList" />
        <van-dropdown-item title="推荐排序" v-model="type" :options="typeList" />
      van-dropdown-menu>
      
      <section class="park-list">
        <map-item v-for="item in showParkList" :key="item.id" :item="item">
          <p>
            评分{{ item.biz_ext.rating }}分 距离
            {{
              getDistances(position[1], position[0], item.location.split(',')[1], item.location.split(',')[0]).km
            }}千米
          p>
        map-item>
      section>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    1.2 css内容

    复制放在 .map 后面

    .main {
      background-color: #fff;
      padding: 20px;
      > h4 {
        /*第一步: 溢出隐藏 */
        overflow: hidden;
        /* 第二步:让文本不会换行, 在同一行继续 */
        white-space: nowrap;
        /* 第三步:用省略号来代表未显示完的文本 */
        text-overflow: ellipsis;
      }
      .park-list {
        padding: 10px;
        height: calc(100vh - 680px);
        overflow-y: auto;
        box-sizing: border-box;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    在这里插入图片描述


    解决报错

    可以看到缺少了很多东西,一个一个来
    在这里插入图片描述

    二、完善api接口+变量+方法

    1.data变量

    代码如下(示例):

    input: '', // 输入框绑定值
    radius: '', // 范围选择
    type: 'a', // 类型选择
    radiusList: [
      { text: '全部', value: '' },
      { text: '500米', value: 500 },
      { text: '1000米', value: 1000 },
      { text: '2000米', value: 2000 },
      { text: '5000米', value: 5000 },
    ],
    typeList: [
      { text: '距离优先', value: 'a' },
      { text: '好评优先', value: 'b' },
    ],
    parkList: [], 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    2. methods

    代码如下(示例):

        onJumpSearch() {
          this.$router.push('/park/search');
        },
        onJumpDetail(id) {
          this.$router.push('/park/detail/' + id);
        },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3. computed

    这个showParkList是我用于渲染页面的parkList,由于高德地图没有条件查询,它只有按照距离来,所以我只能,按距离查询到之后,自己用里面的参数进行一遍过滤。

    computed: {
        showParkList() {
          let array = [...this.parkList];
          if (this.type === 'a') {
            return array;
          } else if (this.type === 'b') {
            return array.sort((a, b) => {
              // 使用parseFloat将rating属性的值解析为数字
              const ratingA = parseFloat(a.biz_ext.rating);
              const ratingB = parseFloat(b.biz_ext.rating);
              // 根据rating属性从大到小排序
              return ratingB - ratingA;
            });
          }
        },
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4. api接口方法

    还剩下最后一个报错,缺少列表请求方法
    在这里插入图片描述

    三、配置api接口方法

    由于东西太多,开一个新标题、

    创建map.js

    在src下的api文件夹里面
    在这里插入图片描述


    看不懂没关系,高德地图文档传送门
    在这里插入图片描述

    // 我使用的poi是1.0,不是2.0, 2.0的话后缀是v5
    import axios from 'axios';
    import Vue from 'vue';
    
    const baseUrl = 'https://restapi.amap.com/v3';
    axios.defaults.headers.common['key'] = Vue.prototype.mapServiceKey;
    
    // 周边搜索
    export function mapPlaceAround(params) {
      return new Promise((resolve, reject) => {
        axios({
          method: 'get',
          url: baseUrl + '/place/around',
          params,
        })
          .then((res) => {
            resolve(res.data);
          })
          .catch((err) => {
            reject(err);
          });
      });
    }
    // 关键字搜索
    export function mapPlaceText(params) {
      return new Promise((resolve, reject) => {
        axios({
          method: 'get',
          url: baseUrl + '/place/text',
          params,
        })
          .then((res) => {
            resolve(res.data);
          })
          .catch((err) => {
            reject(err);
          });
      });
    }
    // 查询地点详情
    export function mapPlaceDetail(params) {
      return new Promise((resolve, reject) => {
        axios({
          method: 'get',
          url: baseUrl + '/place/detail',
          params,
        })
          .then((res) => {
            resolve(res.data);
          })
          .catch((err) => {
            reject(err);
          });
      });
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    我已经都封装好了,直接复制粘贴

    getParkList方法

    复制放到export default上面

    import { mapPlaceAround } from '@/api/map';
    
    • 1

    复制粘贴放到methods里面

    getParkList() {
      console.log('查询');
      mapPlaceAround({
        location: this.position.join(','), // 当前经纬度拼接, 需要格式为 '113.110748,28.246296'
        keywords: '公园',
        types: '080000|110000', // 体育休闲服务|风景名胜
        radius: this.radius, // 距离
        page: 1,
        offset: 20,
        extensions: 'all', // all全部信息, base基础信息
      }).then((res) => {
        this.parkList = res.pois;
        console.log(JSON.parse(JSON.stringify(res.pois)));
      });
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在获取到定位的时候去调用this.getParkList()方法
    在这里插入图片描述

    移动端控制台插件

    把这段代码放在public下的index.html中,你的项目就会有一个控制台了,在手机端测试的时候就可以看见网络请求和控制台打印了

    
    <script src="https://cdn.bootcss.com/vConsole/3.2.0/vconsole.min.js">script>
    <script>
      // 初始化 引入的调试组件
      var vConsole = new VConsole();
      console.log('控制台打印信息 最新');
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    发现手机端好像没啥反应, 其实是组件还没开始写

    四、编写components组件

    这里直接复制粘贴我的了,懒得说明了,样式拿去用就随便改改吧。

    在components中创建文件夹 MapItem,再创建index.vue
    在这里插入图片描述

    <template>
      <div class="com-map-item" v-if="item">
        <div class="img">
          <van-image v-if="item.photos.length > 0" width="50" height="50" :src="item.photos[0].url" />
          <van-image v-else width="50" height="50" fit="cover" :src="require('@/assets/images/park.png')" />
          <slot name="top">slot>
        div>
        <div class="park-name" @click="onJumpDetail(item.id)">
          <h4>{{ item.name }}h4>
          <slot>slot>
        div>
        <div class="park-right" @click="onJumpView">
          <van-image width="30" height="30" :src="require('@/assets/images/icons/toRight.png')" />
          <span>去这里span>
        div>
      div>
    template>
    
    <script>
    export default {
      name: 'vinit',
      props: {
        item: {
          type: Object,
          default: () => {},
        },
        position: {
          type: Array,
          default: () => [],
        },
      },
      data() {
        return {};
      },
      computed: {},
      watch: {},
      filters: {},
      created() {},
      methods: {
        onJumpDetail(id) {
          this.$router.push('/park/detail/' + id);
        },
        onJumpView() {
          this.$router.push('/park/view/' + this.item.id);
        },
      },
    };
    script>
    
    <style scoped lang="scss">
    .com-map-item {
      position: relative;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 20px 10px;
      border-bottom: 1px solid #eee;
      .img {
        position: relative;
      }
    
      ::v-deep .van-image__img {
        border-radius: 5px;
      }
      .park-name {
        width: 70%;
        p {
          color: #666;
          font-size: 28px;
          margin-top: 10px;
          /*第一步: 溢出隐藏 */
          overflow: hidden;
          /* 第二步:让文本不会换行, 在同一行继续 */
          white-space: nowrap;
          /* 第三步:用省略号来代表未显示完的文本 */
          text-overflow: ellipsis;
        }
      }
      .park-right {
        display: flex;
        flex-direction: column;
        align-items: center;
      }
    }
    style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    MapItem挂载全局,你要按需引入也可以

    代码中需要用到图片,缺少图片请看下一步

    在main.js中引入全局组件

    // 地图列表item
    import MapItem from '@/components/MapItem';
    Vue.component('MapItem', MapItem);
    
    • 1
    • 2
    • 3

    发现报错
    在这里插入图片描述
    由于我的组件调用了一个图片,所以这里继续引入图片

    这里你可以自己修改,如果怕出错,那就用我的,不过这个也简单

    在这里插入图片描述
    图片随便找一个图标叫 toRight.png
    一个叫park.png
    图标网站传送门iconfont-阿里巴巴矢量图标库
    在这里插入图片描述
    图标在icons里面,图片在images里面,或者你自己改也行。反正是组件。

    在main.js中挂载计算距离js方法

    还是报错,因为没有计算距离方法
    在这里插入图片描述
    在utils中创建 distances.js

    // 根据经纬度计算距离,参数分别为第一点的纬度,经度;第二点的纬度,经度
    function getDistances(lat1, lng1, lat2, lng2) {
      let EARTH_RADIUS = 6378.137; // 地球半径
      let radLat1 = (lat1 * Math.PI) / 180.0; //lat1 * Math.PI / 180.0=>弧度计算
      let radLat2 = (lat2 * Math.PI) / 180.0;
      let a = radLat1 - radLat2;
      let b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0;
      let s =
        2 *
        Math.asin(
          Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))
        );
      s = s * EARTH_RADIUS;
      s = Math.round(s * 10000) / 10000; // 输出为公里
      return { m: Math.round(s * 1000), km: Number(s.toFixed(2)) };
    }
    export default getDistances;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在main.js中

    // 传入经纬度,计算出m || km
    import getDistances from '@/utils/distances';
    Vue.prototype.getDistances = getDistances; // 计算距离
    
    • 1
    • 2
    • 3

    在这里插入图片描述


    总结

    提示:这里对文章进行总结:
    挂载了计算距离方法后,发现页面不报错了,正常运行了

    • 为什么不用webJs的poi查询?那个查询可以直接在地图上标点出来。

    因为没有我所需要的评分,我需要根据评分来排序,如果需要地图显示点,可以用mark批量添加,看到这里相信你已经会基本操作了。mark加标记点我在后面会有一片教程,不过不是批量,不过都差不多,反正都是给经纬度然后整个循环。

    例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

    如果看到这里还是没有正常运行。
    请检查

    1. data变量
    2. computed计算属性
    3. methods方法
    4. import引入js请求方法
    5. main.js挂载计算距离方法
    6. api文件夹下创建map.js方法
    7. components组件,挂载到main.js全局,并且需要2张图片
    8. 在获取定位后,执行getParkList方法

    如果都正常,看看你手机是不是禁用了位置授权。
    记得用手机端控制台查看报错,禁用控制台直接注释就好了
    在这里插入图片描述

  • 相关阅读:
    C#学习笔记-委托和事件
    如何配置Outlook的SMTP信息?
    类加载器与反射
    conda操作总结,pip操作总结,python包安装
    git进阶
    美国各流域边界下载,并利用arcgis提取与处理
    Android驱动框架整理之device框架
    Spring Boot中Tomcat服务器参数解析及高并发控制
    Webpack面试题总结
    ctfshow萌新计划web1-5(正则匹配绕过)
  • 原文地址:https://blog.csdn.net/qq_51055690/article/details/133896323