uniapp 之 将marker 渲染在地图上 点击弹层文字时显示当前信息

news2025/1/18 4:45:14

目录

效果图

总代码

分析

1.template 页面

地图显示代码

2. onload

①经纬度

②取值

③注意

 3.methods

① 先发送 getStationList 请求 获取 数组列表信息

② regionChange 视野发生变化时 触发 分页逻辑

③ callouttap 点击气泡时触发 查找 当前 marker  id 等于 stationId 的数组 

(4)style样式

 使用样式穿透 可以改变输入框输入的字体颜色


效果图

 这个效果是 进入当前页面显示自己的经纬度 并 根据 pageSize,pageNum 显示当前pageSize条数据,在地图视野发生改变时 进行  this.pageNum * this.pageSize >= this.total  判断,让this.pageNum++ ,让所有的数据显示在地图上

总代码

<template>
  <view>
    <view class="map-container">
      <map style="width: 100%; height: 100vh;" :show-location='true' ref="map" id="map" :latitude="latitude"
        :longitude="longitude" :markers="marker" :scale="scale" @callouttap='callouttap' @regionchange="regionChange"
        v-if="mapShow">
        <view class="cover-view">
          <view style="margin-top: 20rpx;" @click="onControltap">
            <image class="cover-image" src="/static/images/location.png"></image>
            <view>定位</view>
          </view>
        </view>
      </map>
    </view>
    <view class="search" :style="{top:topHeight+'px'}">
      <searchBar @click="search" :city="city"></searchBar>
    </view>
    <cardList :stationList="markerIdClick" v-if="tag" style="position: fixed;top: 70%;"></cardList>
    <tabbar :current="current"></tabbar>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        mapShow: false,
        topHeight: 20,
        tag: false,
        latitude: '', //纬度
        longitude: '', //经度
        scale: 12, //缩放级别
        current: 1,
        marker: [],
        pageSize: 10,
        pageNum: 1,
        total: 0, // 总数据量
        markerIdClick: [],
        mapList: [],
      }
    },
    async onLoad() {
      let userLocation = uni.getStorage({
        key: 'userLocation'
      })
      await userLocation.then(data => {
        let arr = data[1].data.split(',')
        this.longitude = arr[0]
        this.latitude = arr[1]
        console.log(arr);
      })
      this.getStationList()
      const {
        height,
        top
      } = uni.getMenuButtonBoundingClientRect();
      this.topHeight = height + top + 13
    },
    methods: {
     search(searchInp) {
        console.log('search页面子向父传值', searchInp);
      },
      regionChange() {
        this.tag = false
        if (this.pageNum * this.pageSize >= this.total) return
        this.pageNum++
        this.getStationList()
      },
      //定位
      onControltap() {
        uni.createMapContext("map", this).moveToLocation({ //moveToLocation将地图中心移动到当前定位点,需要配合map组件的show-location使用
          latitude: this.latitude,
          longitude: this.longitude,
        });
        console.log('定位');
      },
      //气泡点击事件
      callouttap(e) {
        let id = String(e.detail.markerId)
        let arr = this.mapList.find(item => {
          return item.stationId === id
        })
        this.markerIdClick = [arr]
        this.tag = true
      },
      async getStationList() {
        console.log('发送请求前 打印用户经纬度', this.latitude, this.longitude);
        const {
          data: {
            obj,
            msg,
            resCode
          }
        } = await uni.$http.post('/uniapp/pile/queryStationInfos', {
          pageSize: this.pageSize,
          pageNum: this.pageNum,
          stationLng: this.longitude,
          stationLat: this.latitude
        })
        console.log('queryStationInfos,信息列表显示总数据', obj, msg, resCode);
        if (resCode !== "00100000") return uni.$showMsg()
        this.total = obj.total
        obj.list.forEach(item => {
          this.marker.push({
            id: Number(item.stationId),
            iconPath: '/static/images/mapStation.png', //显示的图标
            title: item.stationName,
            latitude: Number(item.stationLat),
            longitude: Number(item.stationLng),
            width: 30, 
            height: 30, 
            callout: { //气泡窗口 
              content: '空闲' + item.totalFree, //文本
              color: '#ffffff',
              fontSize: 15, 
              borderRadius: 15, 
              padding: '10',
              bgColor: '#406390', 
              display: 'ALWAYS', //常显
            }
          })
        })
        this.mapShow = true
        this.mapList = this.mapList.concat(obj.list)
        console.log(this.marker);
        // for (let index in obj.list) {
        //   let stationMarker = {
        //     iconPath: '/static/images/mapStation.png', //显示的图标 
        //     id: Number(index) || 0,
        //     title: this.mapList[index].stationName || '',
        //     latitude: Number(this.mapList[index].stationLat),
        //     longitude: Number(this.mapList[index].stationLng),
        //     width: 30, 
        //     height: 30, 
        //     callout: { //气泡窗口 
        //       content: '空闲' + this.mapList[index].totalFree, //文本
        //       color: '#ffffff', //文字颜色
        //       fontSize: 15, //文本大小
        //       borderRadius: 15, //边框圆角
        //       padding: '10',
        //       bgColor: '#406390', //背景颜色
        //       display: 'ALWAYS', //常显
        //     }
        //   }
        //   // console.log(stationMarker, 'stationMarker');
        //   this.marker.push(stationMarker)
        // }
      }
    }
  }
</script>

<style scoped lang="scss">
  /deep/ .uni-searchbar__box-search-input {
    color: #fff !important;
  }

  .search {
    position: fixed;
    width: 80%;
  }

  .map-container {
    margin-top: -40rpx;
    position: relative;
    overflow: hidden;
    border-radius: 50rpx 50rpx 0 0;

    .cover-view {
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      /* width: 80rpx;
			height: 160rpx; */
      padding: 42rpx 22rpx;
      color: #4F575F;
      font-weight: 400;
      background-color: #fff;
      background-size: 120rpx 120rpx;
      background-position: center center;
      position: absolute;
      top: 150rpx;
      right: 32rpx;
      border-radius: 15rpx;


    }

    .cover-image {
      display: inline-block;
      width: 50rpx;
      height: 50rpx;

    }
  }
</style>

分析

1.template 页面

(1)

 <tabbar :current="current"></tabbar>   current:1  此页面是自定义tab栏

(2)

 <view class="search" :style="{top:topHeight+'px'}">
      <searchBar @click="search" :city="city"></searchBar>
    </view>

动态style  就是为了 让输入框 在 胶囊下侧的位置,searchBar是我封装的组件

效果图     

 (3)

<cardList :stationList="markerIdClick" v-if="tag" style="position: fixed;top: 70%;"></cardList>

是我封装的组件, v-if=“tag” 默认不显示,当我点击气泡时出现的 卡片信息

(4)

地图显示代码

<view class="map-container">
      <map style="width: 100%; height: 100vh;" :show-location='true' ref="map" id="map" :latitude="latitude"
        :longitude="longitude" :markers="marker" :scale="scale" @callouttap='callouttap' @regionchange="regionChange"
        v-if="mapShow">
        <view class="cover-view">
          <view style="margin-top: 20rpx;" @click="onControltap">
            <image class="cover-image" src="/static/images/location.png"></image>
            <view>定位</view>
          </view>
        </view>
      </map>
    </view>

在  map组件 中,我只使用到了 下面那两种方法

①@regionchange

当视野发生改变时,里面进行分页处理,

②@callouttap

点击标记点时 出现卡片内容

2. onload

此页面一进来

首先就是要 获取经纬度  使用这种方法获取 是因为 前面使用高德 amap-wx.130.js,这个文件帮我们把用户的经纬度存储起来了,我们只需 取就行  (注意在 amap-wx.130.js 文件中 将里面所以的 wx,替换为 uni )

①经纬度

let userLocation = uni.getStorage({
        key: 'userLocation'
      })

②取值

打印 userLocation 它的结果为 promise

 因此我们要 使用promise。then的方法取值 并赋值

③注意

最开始在onload 里 下面的

this.getStationList() 这个请求先执行,后打印经纬度,这时请求里的经纬度 就为空,

因此 加  async  await,可以先获取经纬度 然后在拿经纬度发送请求

 this.topHeight = height + top + 13

这个 13 可加可不加 根据你们原型图高度来定

  async onLoad() {
      let userLocation = uni.getStorage({
        key: 'userLocation'
      })
      await userLocation.then(data => {
        let arr = data[1].data.split(',')
        this.longitude = arr[0]
        this.latitude = arr[1]
        console.log(arr);
      })
      this.getStationList()
      const {
        height,
        top
      } = uni.getMenuButtonBoundingClientRect();
      this.topHeight = height + top + 13
      // console.log(this.topHeight, '高度');
    },

 3.methods

① 先发送 getStationList 请求 获取 数组列表信息

先获取到 obj.list (列表数组)创建一个新的 marker数组

这里要注意 先获取到 obj.list (列表数组)创建一个新的 marker数组 后 要先 forEach,push (或 for  ,push)返回一个 marker数组

这里的id 不能使用 index 代替 ,还有 id 、latitude 、longitude 必须是 Number类型 因为我这数据是用分页处理 若是 使用index,会有重复的id,会导致在缩放地图时 有些 marker 消失,

  obj.list.forEach(item => {
          // console.log(item, 'foreach');
          this.marker.push({
            id: Number(item.stationId),
            iconPath: '/static/images/mapStation.png', //显示的图标
            title: item.stationName,
            latitude: Number(item.stationLat),
            longitude: Number(item.stationLng),
            width: 30, //宽
            height: 30, //高
            callout: { //自定义标记点上方的气泡窗口 点击有效
              content: '空闲' + item.totalFree, //文本
              color: '#ffffff', //文字颜色
              fontSize: 15, //文本大小
              borderRadius: 15, //边框圆角
              padding: '10',
              bgColor: '#406390', //背景颜色
              display: 'ALWAYS', //常显
            }
          })
        })

后合并obj.list 数组 并赋值 

this.mapList = this.mapList.concat(obj.list)  (视野范围方法里需要使用 )

 async getStationList() {
        console.log('发送请求前 打印用户经纬度', this.latitude, this.longitude);
        const {
          data: {
            obj,
            msg,
            resCode
          }
        } = await uni.$http.post('/uniapp/pile/queryStationInfos', {
          pageSize: this.pageSize,
          pageNum: this.pageNum,
          stationLng: this.longitude,
          stationLat: this.latitude
        })
        console.log('queryStationInfos,查询充电站信息列表显示总数据', obj, msg, resCode);
        if (resCode !== "00100000") return uni.$showMsg()
        this.total = obj.total
        // console.log('充电站信息列表 mapList', obj.list);
        obj.list.forEach(item => {
          // console.log(item, 'foreach');
          this.marker.push({
            id: Number(item.stationId),
            iconPath: '/static/images/mapStation.png', //显示的图标
            title: item.stationName,
            latitude: Number(item.stationLat),
            longitude: Number(item.stationLng),
            width: 30, //宽
            height: 30, //高
            callout: { //自定义标记点上方的气泡窗口 点击有效
              content: '空闲' + item.totalFree, //文本
              color: '#ffffff', //文字颜色
              fontSize: 15, //文本大小
              borderRadius: 15, //边框圆角
              padding: '10',
              bgColor: '#406390', //背景颜色
              display: 'ALWAYS', //常显
            }
          })
        })
        this.mapShow = true
        this.mapList = this.mapList.concat(obj.list)
        console.log(this.marker);
        // for (let index in this.mapList) {
        //   let stationMarker = {
        //     iconPath: '/static/images/mapStation.png', //显示的图标 
        //     id: Number(index) || 0,
        //     title: this.mapList[index].stationName || '',
        //     latitude: Number(this.mapList[index].stationLat),
        //     longitude: Number(this.mapList[index].stationLng),
        //     width: 30, //宽
        //     height: 30, //高
        //     callout: { //自定义标记点上方的气泡窗口 点击有效
        //       content: '空闲' + this.mapList[index].totalFree, //文本
        //       color: '#ffffff', //文字颜色
        //       fontSize: 15, //文本大小
        //       borderRadius: 15, //边框圆角
        //       padding: '10',
        //       bgColor: '#406390', //背景颜色
        //       display: 'ALWAYS', //常显
        //     }
        //   }
        //   // console.log(stationMarker, 'stationMarker');
        //   this.marker.push(stationMarker)
        // }
      }

② regionChange 视野发生变化时 触发 分页逻辑

 regionChange() {
        this.tag = false
        if (this.pageNum * this.pageSize >= this.total) return
        this.pageNum++
        this.getStationList()
      },

③ callouttap 点击气泡时触发 查找 当前 marker  id 等于 stationId 的数组 

这里要注意下类型的一个转换 e.detail.markerId -->  是 marker id 它是数字类型

而 mapList 里面的  stationId 为 字符串 类型 ,因此这要做个类型转换,若不转换的话,点击所有的 气泡,卡片上面的内容 是显示一样的

  callouttap(e) {
        let id = String(e.detail.markerId)
        // console.log(this.mapList, id);
        let arr = this.mapList.find(item => {
          return item.stationId === id
        })
        this.markerIdClick = [arr]
        // console.log('点击id', id, '数组', this.markerIdClick);
        this.tag = true
      },

(4)style样式

 /deep/ .uni-searchbar__box-search-input {
    color: #fff !important;
  }

输入框默认 黑色

 使用样式穿透 可以改变输入框 输入字体颜色

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/435205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于第一性原理DFT密度泛函理论的计算项目

随着计算机技术的不断发展&#xff0c;计算材料科学的方法也日益成熟。其中&#xff0c;基于第一性原理的密度泛函理论&#xff08;DFT&#xff09;计算方法&#xff0c;因其准确性、可靠性和高效性而广受欢迎。本文将介绍基于DFT的密度泛函理论的计算项目&#xff0c;包括电子…

云内基于 SRv6 的 SFC 方案

1. 基于 SRv6 的 SFC 服务链 为满足用户的业务数据安全、稳定等需求&#xff0c;提供各种基础保障或增值优化服务&#xff0c;在传统网络中&#xff0c;经常使用业务功能节点&#xff08;如负载均衡、防火墙等&#xff09;实现服务供应。但这些业务功能节点往往与网络拓扑和硬件…

Fortinet Accelerate 2023全球网安大会成功举办 加速推进网络安全行业融合与整合

近日&#xff0c;Fortinet全球网络安全大会——Fortinet Accelerate 2023 在美国奥兰多成功举办。在对企业数字化转型挑战及网络威胁趋势等行业热点进行深入探讨的同时&#xff0c;Fortinet全新发布了以融合与整合为核心设计理念的增强型产品和服务&#xff0c;帮助企业从容应对…

第2章 时间空间复杂度计算

1时间复杂度计算 时间复杂度是什么&#xff1f; 一个函数&#xff0c;用大O表示&#xff0c;例如&#xff1a;O(1), O(N), O(logN). 定性描述算法的运行时间。 时间复杂度常见图&#xff1a; 案例&#xff1a; O(1) let i 0 i 1 解释&#xff1a;每次执行这段代码&#…

【Paper Note】Video Swin Transformer

Video Swin Transformer 介绍架构3.2 3D Shifted Window based MSA Module3.2.1 在不重叠的三维窗口上的MSA3.2.2 3D Shifted Windows3.2.3. 3D Relative Position Bias 3.3 Architecture Variants3.4 Initialization from Pre-trained Model 总结 文章链接&#xff1a;https:/…

zabbix自动发现和自动注册部署

目录 zabbix自动发现 确保客户端上的zabbix-agent2服务状态正常 在web页面删除原有的客户端主机 在服务端和客户端上配置 hosts 解析 在 Web 页面配置自动发现 zabbix自动注册 环境准备 修改 zabbix-agent2 配置文件 在 Web 页面配置自动注册 zabbix自动发现 对于agen…

如何使用Git将本地代码上传GitHub仓库?

如何使用Git将本地代码上传GitHub仓库呢&#xff1f; 前提 要上传本地代码到GitHub仓库&#xff0c;那必然要先在GitHub上建立一个存储代码的仓库&#xff0c;这里我在仓库新建了一个名为5blog的仓库。 备注&#xff1a;本文章将以默认分支main为例来讲解上传步骤 接着我们打…

学习经验分享【26】论文写作画图方法(持续更新)

写作前面&#xff1a;论文投稿能否成功&#xff0c;图表作为比较直观的展现&#xff0c;起着关键的作用&#xff0c;图表丰富规范好看&#xff0c;一定程度上能够吸引编辑和审稿人的眼球&#xff0c;提升录用概率。就跟人的形象一样&#xff0c;形象好第一印象就会好&#xff0…

简单的重装系统教程

郁闷&#xff0c;最近电脑一直蓝屏重启&#xff0c;用 2 分钟就蓝屏一次&#xff0c;遂产生重装系统的想法。 准备 U盘(8G或以上) PE 工具&#xff1a; 微PE工具箱快速指引 | 微PE优盘使用说明书 (wepe.com.cn) 系统镜像&#xff1a; 官网 Windows 10 官网 Windows 11 M…

送给程序员的一份养生指南

本文是 Joe Kutner 的《程序员健康指南》的干货记录。时刻提醒自己要有一个健康的工作和生活方式。身体是革命的本钱&#xff0c;年轻的时候拿身体换钱&#xff0c;老了可能就要拿钱换身体。当你有被程序员职业困扰的健康问题时&#xff0c;希望这篇干货记录可以给予你一定的帮…

mybatis代码生成器模板配置

1.mybatis代码生成器的介绍 代码生成器的目标就是简化单表的增删改查操作&#xff0c;这些标准化的流程工作&#xff0c;交给机器来实现&#xff0c;不需要程序员自己去完成。一般对一张表的操作有&#xff0c;根据主键查询&#xff0c;根据map集合查询&#xff0c;单条数据插…

追踪行人和车辆,并使用deep-person-reid训练自定义追踪模型(行人和车辆两类)

deep-person-reid训练自定义模型 1. 准备代码2. market1501格式3 转换格式代码4. 训练5 追踪测试 仅供参考&#xff0c;目前实现的格式转化还是存在一定的问题&#xff0c;导致训练后的模型精度很高&#xff0c;分配上还是没有完全符合market1501的格式。依照这样训练的模型&am…

UG NX二次开发(C#)-建模-求解两条样条曲线的最大距离

文章目录 1、前言2、最大距离示例3、NXOpen代码实现1、前言 在UG NX中计算两条样条曲线的最小距离是我们常用的,但是计算最大距离却很少用,但是UG NX二次开发为我们提供了这个计算方法,我们只需要调用即可。本小节是用于计算两条样条曲线的最大距离的二次开发讲解。 2、最…

封装通用el-form表单(2种方式)

1、序言 项目地址&#xff1a;git clone form-demo: 封装通用el-form 一个后台管理系统最常见的是表单&#xff0c;表单最常见的是输入框、下拉选择、日期选择、单选、复选框等等&#xff0c; 系统添加若干模块&#xff0c;就复制粘贴若干个el-form、el-form-item&#xff0c;有…

Ubuntu下好用的截图工具flameshot

在Linux环境下截图也是十分重要的东西&#xff0c;flameshot则是一款十分好用的工具 sudo apt-get install flameshot 即可安装 安装完成后打开设置(settings) -> 设备(Devices) -> 键盘快捷键(keyboard Shortcuts),滑到最底下&#xff0c;找到一个加号 点击加号填入以…

300块买什么蓝牙耳机好?无线蓝牙耳机300左右推荐

不管你的手机是否被保留3.5mm的音频接口&#xff0c;蓝牙耳机必定是可以入手的&#xff0c;无束缚的听歌方式对我们中的大多数人都有着很强的吸引力。大多数都定价在几十几百几千不等&#xff0c;但是在300左右的价位更受大众欢迎&#xff0c;说明了中端市场是该类产品竞争最激…

如何把Ai绘画工具放到我们的App中

Scribble Diffusion 是一个简单的在线服务&#xff0c;它使用 AI 将粗略的草图转换为精致的图像&#xff0c;每一张图像都是不同的&#xff08;而且没有版权困扰&#xff09;。简单来说&#xff0c;我们只需要「用画笔描绘一张草图&#xff0c;在输入描述后稍等片刻」&#xff…

【Linux】1、操作系统、计算机硬件和软件、Linux 介绍

目录 一、计算机的硬件和软件(1) 硬件(2) 软件 二、操作系统(1) OS 作用(2) OS 举例 三、Linux 内核(1) 介绍(2) Linux 发行版 四、虚拟机 一、计算机的硬件和软件 (1) 硬件 &#x1f5a5;️ 计算机由硬件和软件组成 &#x1f5a5;️ 硬件&#xff1a;计算机中由电子、机械和…

pandas汇总和描述性统计

本文介绍pandas中汇总和描述性统计中的基本内容&#xff0c;仅供参考。 目录 1描述和汇总统计 1.1sum方法 1.2idxmin和idxmax方法 1.3describe方法 1.4描述和汇总统计的常用方法 2相关系数和协方差 3唯一值、值计数以及成员资格 3.1唯一值 3.2值计数 3.3成员资格 1…

【区块链】走进web3的世界-获取Token价格

1、通过预言机获取Token价格&#xff08;需要部署合约&#xff09; 在以太坊区块链上&#xff0c;由于智能合约本身无法获取外部数据&#xff0c;因此需要使用预言机 (Oracle) 来获取外部数据。 以下是一个获取代币价格的示例&#xff1a; 选择预言机&#xff1a;首先需要选…