高德地图实现-自定义信息窗+窗体点击事件

简介: 高德地图实现-自定义信息窗+窗体点击事件

1. 什么是自定义信息窗

自定义信息窗是一种在地图上点击标记点后弹出的窗口,用于显示与该标记点相关的更多信息。与默认信息窗相比,自定义信息窗可以根据开发者的需要定制外观、内容和交互,从而更好地满足应用的要求。

2自定义信息窗的实现步骤

2.1 创建信息窗内容

通过HTML和CSS,您可以定义信息窗的内容和样式。您可以在信息窗中添加文本、图片、链接等元素,以展示相关信息。

<div class="custom-info-window">
  <h3>${point.title}</h3>
  <p>${point.description}</p>
  <img src="${point.image}" alt="Point Image">
</div>
2.2 添加信息窗交互 窗体点击事件

利用JavaScript,您可以为信息窗添加交互行为,例如点击事件。当用户点击标记点时,信息窗将显示并展示定制的内容。

这里的content可以写一个方法把参数传递进去并返回html 后面有完整代码可以参考

marker.on("click", function(e) {
// 在这里可以执行相应的操作,例如添加标记或弹出信息窗
  var infoWindow = new AMap.InfoWindow({
    content: createPopupContent(point),
    offset: new AMap.Pixel(0, -30),
    closeWhenClickMap: true
  });

  infoWindow.open(map, marker.getPosition());
});

2.3. 窗体点击事件

主要代码:

 <span  onclick='handleBreak()'  style=" color:red; font-size: 15px;">断油电</span> 
   createPopupContent(point) {
        return `
         <div class="popup-container">
           <div class="popup-header"></div>
           <div class="popup-content">
             <p>车牌号码:<spen id="licenseName"> ${point.extra.licenseName}</spen></p>
             <p >设备编号:<spen id="Id"> ${point.extra.id}</spen></p>
             <p>行驶里程: ${point.baipaoGpsInfoBean.gpsMil}公里</p>
             <p>今日里程: ${point.baipaoGpsInfoBean.todayMil}公里</p>
             <p>最近定位位置: ${point.baipaoGpsInfoBean.location}</p>
             <p>是否在线: ${point.baipaoGpsInfoBean.online ? '在线' : '不在线'}</p>
             <span  onclick='handleBreak()'  style=" color:red; font-size: 15px;">断油电</span> 
              <span onclick='handleRestore()'style="color:blue; font-size: 15px;">恢复油电</span> 
           </div>
         </div>
       `;
      },

3 .实际应用示例

4.代码解释

createPopupContent(point) 方法

这个方法用于生成自定义信息窗的内容,根据传入的point对象,将相关信息以HTML的形式呈现。其中还包括可以点击的操作:

通过全局定义的window.handleBreak和window.handleRestore,分别绑定了两个事件处理函数,这两个函数会调用组件内部的方法this.handleBreak()和this.handleRestore()。

5.完整代码

<template>
  <div id="container">
    <slot></slot>
    <a-modal v-model="modalBreak" title="断油电" @ok="handleBreakOk">

      <div style="font-size: 16px; font-weight: bolder;"><img src="../../assets/jingao.png" width="40px"
          height="40px"></img>您确定要下发<span style="font-size: 18px; color: red;"> 断油电</span> 指令吗?</div>
      <a-radio-group v-model="triggerType" style="margin-top: 30px;">
        <a-radio :value="1">合同未交款断油电</a-radio>
        <a-radio :value="2">违竟断油电</a-radio>
        <a-radio :value="3">其他:</a-radio>
      </a-radio-group>
      <a-input v-model="optRemark" style="margin-top: 30px;">
      </a-input>
    </a-modal>
    <a-modal v-model="modalRestore" title="恢复油电" @ok="handleRestoreOk">

      <div style="font-size: 16px; font-weight: bolder;"><img src="../../assets/jingao.png" width="40px"
          height="40px"></img>您确定要执行<span style="font-size: 18px; color: red;"> 恢复油电</span> 指令吗?</div>

    </a-modal>
  </div>
</template>

<script>
  import Vue from 'vue'
  import {
    getAction,
    httpAction,
    postAction
  } from '../../api/manage'
  export default {
    props: {
      licence: {
        type: String, // 参数的数据类型
        required: true // 参数是否必需
      }
    },
    data() {
      return {
        modalBreak: false, // 模态框可见状态
        modalRestore: false,
        triggerType: 1,
        manageId: null, //断油点的设备
        numberplate:null,//断油电车牌号
        optRemark: "", //其他原因
        url: {
          gps: '/jeecg-customers/car/carBaipaoGpsController/gps',
          //断油电
          executeCmd: '/jeecg-customers/car/carBaipaoGpsController/executeCmd',
          //恢复油电
          executeRestoreCmd: '/jeecg-customers/car/carBaipaoGpsController/executeRestoreCmd',
        },
        map: '',
        // pointList: [
        //   {
        //     weight: 8,
        //     "lat": 22.736123564564537,
        //     "lng": 114.12164859841218,
        //     "dir": 196,
        //     "vehDeviceType": 10,
        //     "isWireless": "no",
        //     "deviceCode": "868035047710447",
        //     "id": "745535770052698112",
        //     "vehNum": "粤BDV1915_1",
        //     "online": 1
        //   },
        //   // ... rest of the points
        // ],
        pointList: [],
        popup: null,
        // licence:"粤BAZ2508",
        G: {
          pi: 3.141592653589793,
          a: 6378245,
          ee: .006693421622965943,
          x_pi: 52.35987755982988
        },
        // arr: [{ lat: 116.405285, long: 39.905989 }, { lat: 116.405285, long: 39.909689 }, { lat: 116.405285, long: 39.915989 }, { lat: 116.405285, long: 39.908989 }]
      }
    },
    provide: function() {
      return {
        removeOlver: this.removeOlver,
        addOverlay: this.addOverlay,
        markers: [],
      }
    },

    components: {},
    created() {
      //初始化窗口点击事件
      window.handleBreak = () => {
        this.handleBreak();
      }
      window.handleRestore = () => {
        this.handleRestore();
      }
    },
    mounted() {
      console.log('Received licence:', this.licence);
      //测试读取精准位置
      //  var a =this.transfor2Mars(22.663673, 114.126843)
      // console.log("读取位置", a);
      Vue.prototype.$map = new AMap.Map('container', {
        zoom: 10, //级别
        center: [114.16129136801659, 22.64461948509109], //默认中心点坐标
        resizeEnable: true,
        averageCenter: true
        // mapStyle: 'amap://styles/1938caab0264493fa2a847243b88e511',
      });
      this.map = Vue.prototype.$map
      this.gps().then((gpsData) => {
        this.createMarkerClusterer();
      }).catch((error) => {
        console.error(error);
      });
      // this.createMarkerClusterer();
    },
    methods: {
      gps() {
        return new Promise((resolve, reject) => {
          // 根据车牌号查询Gps定位数据
          getAction(this.url.gps, {
            licence: this.licence
          }).then((res) => {
            console.log(res);
            if (res.success) {
              //如果为List列表在改
              var t = res.result;
              // t.forEach(function(e) {
              //     // e.online = e.online ? 1 : 0;
              //     var a = D.transfor2Mars(e.lat, e.lng);
              //     e.lng = a.Lng,
              //     e.lat = a.Lat
              // });
              // console.log(t.gps.lat)
              var a = this.transfor2Mars(parseFloat(t.baipaoGpsInfoBean.gps.lat), parseFloat(t.baipaoGpsInfoBean
                .gps.lng));
              t.baipaoGpsInfoBean.gps.lng = a.Lng,
                t.baipaoGpsInfoBean.gps.lat = a.Lat
              // this.pointList=t
              this.pointList.push(t);
              // this.map.setCenter([this.pointList[0].lng, this.pointList[0].lat]);
              this.setCenter(this.pointList[0].baipaoGpsInfoBean.gps.lng, this.pointList[0].baipaoGpsInfoBean
                .gps.lat); // 设置新的中心点经纬度
              resolve(res.result); // 返回参数
            } else {
              reject(new Error('Failed to get GPS data.')); // 返回错误
              this.$message.info(res.message)
            }
          });
        });
      },
      /**
       * 动态更改中心点位
       */
      setCenter(lng, lat) {
        console.log('New center:', lng, lat);
        this.map.setCenter(new AMap.LngLat(lng, lat));
      },
      removeOlver(overlay) {
        this.$nextTick(() => {
          if (overlay) {
            this.map.remove(overlay)
          }
        })
      },
      addOverlay(overlay) {
        this.$nextTick(() => {
          // console.log(this.map);
          this.map && this.map.add(overlay)
        })
      },
      delOne() {
        // 删除了数组的元素,但是没用,需要调用地图的清除标记的方法
        // this.arr.pop()
      },
      // 海量点聚合,10w数量以下
      createMarkerClusterer() {
        let _this = this
        let markers = []
        // 利用styles属性修改点聚合的图标样式,这个是聚合之后的显示效果,在这里定义
        var styles = [{
          url: "https://a.amap.com/jsapi_demos/static/images/blue.png",
          size: new AMap.Size(32, 32),
          offset: new AMap.Pixel(-16, -16)
        }, {
          url: "https://a.amap.com/jsapi_demos/static/images/green.png",
          size: new AMap.Size(32, 32),
          offset: new AMap.Pixel(-16, -16)
        }, {
          url: "https://a.amap.com/jsapi_demos/static/images/orange.png",
          size: new AMap.Size(36, 36),
          offset: new AMap.Pixel(-18, -18)
        }, {
          url: "https://a.amap.com/jsapi_demos/static/images/red.png",
          size: new AMap.Size(48, 48),
          offset: new AMap.Pixel(-24, -24)
        }, {
          url: "https://a.amap.com/jsapi_demos/static/images/darkRed.png",
          size: new AMap.Size(48, 48),
          offset: new AMap.Pixel(-24, -24)
        }];
        _this.pointList.forEach(point => {
          // 这里是点击到无法聚合,到单个点的时候展示的效果
          var marker = new AMap.Marker({
            position: new AMap.LngLat(point.baipaoGpsInfoBean.gps.lng, point.baipaoGpsInfoBean.gps.lat),
            title: point.extra.licenseName,
            content: `<div><img style="height:35px;width:30px; -moz-transform:rotate(0deg);-webkit-transform:rotate(0deg);"src="${require("@/assets/car.png")}" alt="Car Icon" ></div><div style="width:100px;padding-left:3px;font-size:14px;margin-left:5px;height:20px;background:#fff;border:1px solid #000;text-align:canter;line-height:20px;font-size: 14px;">${ point.extra.licenseName}</div>`,
          });
          //给marker增加click事件
          marker.on("click", function(e) {
            // Create a popup instance
            var popup = new AMap.InfoWindow({
              content: _this.createPopupContent(point),
              offset: new AMap.Pixel(0, -30),
              closeWhenClickMap: true // Close the popup when the map is clicked
            });

            popup.open(_this.map, marker.getPosition());
            _this.popup = popup; // Store reference to the active popup window
          });

          markers.push(marker);
        });
        //添加聚合组件
        _this.map.plugin(["AMap.MarkerClusterer"], function() {
          new AMap.MarkerClusterer(
            _this.map, // 地图实例
            markers, // 海量点组成的数组
            {
              styles: styles,
              gridSize: 80
            }
          );
        });

      },
      // clickMarker (e) {
      //   console.log(e);
      //   this.$message.success('你点击我了')
      // },
      createPopupContent(point) {
        return `
         <div class="popup-container">
           <div class="popup-header"></div>
           <div class="popup-content">
             <p>车牌号码:<spen id="licenseName"> ${point.extra.licenseName}</spen></p>
             <p >设备编号:<spen id="Id"> ${point.extra.id}</spen></p>
             <p>行驶里程: ${point.baipaoGpsInfoBean.gpsMil}公里</p>
             <p>今日里程: ${point.baipaoGpsInfoBean.todayMil}公里</p>
             <p>最近定位位置: ${point.baipaoGpsInfoBean.location}</p>
             <p>是否在线: ${point.baipaoGpsInfoBean.online ? '在线' : '不在线'}</p>
             <span  onclick='handleBreak()'  style=" color:red; font-size: 15px;">断油电</span> 
              <span onclick='handleRestore()'style="color:blue; font-size: 15px;">恢复油电</span> 
           </div>
         </div>
       `;
      },
      handleBreakOk() {
        if (this.manageId == null) {
          this.$message.info("设备id为空")
          return
        }
        if (this.triggerType == null) {
          this.$message.info("类型选择为空")
          return
        }
        httpAction(this.url.executeCmd, {
          "manageId": this.manageId,
          "triggerType": this.triggerType,
          "optRemark": this.optRemark,
          "numberplate":this.numberplate
        }, 'post').then((res) => {
          if (res) {
            console.log(res)
            this.$message.info(res.result)
          }
        })
        this.modalBreak = false; // 关闭模态框
      },

      handleRestoreOk() {
        if (this.manageId == null) {
          this.$message.info("设备id为空")
          return
        }
        httpAction(this.url.executeRestoreCmd, {
          "manageId": this.manageId,
          "numberplate":this.numberplate
        }, 'post').then((res) => {
          if (res) {
            console.log(res)
             this.$message.info(res.result)
          }
        })
        this.modalRestore = false; // 关闭模态框
      },
      handleBreak() {
        this.modalBreak = true; // 打开模态框
        let id = document.getElementById("Id").innerText;
        let licenseName = document.getElementById("licenseName").innerText;
        this.manageId = id;
        this.numberplate=licenseName
        // this.currentRecord = record.id; // 保存当前记录
      },
      handleRestore() {
       this.modalRestore = true; // 打开模态框
        let id = document.getElementById("Id").innerText;
         let licenseName = document.getElementById("licenseName").innerText;
        this.manageId = id;
       this.numberplate=licenseName
      },

      isOutOfChina(e, a) {
        return a < 72.004 || a > 137.8347 || (e < .8293 || e > 55.8271)
      },
      transforLat(e, a) {
        var t = 2 * e - 100 + 3 * a + .2 * a * a + .1 * e * a + .2 * Math.sqrt(Math.abs(e));
        return t += 2 * (20 * Math.sin(6 * e * this.G.pi) + 20 * Math.sin(2 * e * this.G.pi)) / 3,
          t += 2 * (20 * Math.sin(a * this.G.pi) + 40 * Math.sin(a / 3 * this.G.pi)) / 3,
          t += 2 * (160 * Math.sin(a / 12 * this.G.pi) + 320 * Math.sin(a * this.G.pi / 30)) / 3
      },
      transforLng(e, a) {
        var t = 300 + e + 2 * a + .1 * e * e + .1 * e * a + .1 * Math.sqrt(Math.abs(e));
        return t += 2 * (20 * Math.sin(6 * e * this.G.pi) + 20 * Math.sin(2 * e * this.G.pi)) / 3,
          t += 2 * (20 * Math.sin(e * this.G.pi) + 40 * Math.sin(e / 3 * this.G.pi)) / 3,
          t += 2 * (150 * Math.sin(e / 12 * this.G.pi) + 300 * Math.sin(e / 30 * this.G.pi)) / 3
      },

      transfor2Mars(e, a) {
        if (this.isOutOfChina(e, a))
          return {
            Lat: e,
            Lng: a
          };
        var t = this.transforLat(a - 105, e - 35),
          r = this.transforLng(a - 105, e - 35),
          n = e / 180 * this.G.pi,
          o = Math.sin(n);
        o = 1 - this.G.ee * o * o;
        var s = Math.sqrt(o);
        return {
          Lat: e + (t = 180 * t / (this.G.a * (1 - this.G.ee) / (o * s) * this.G.pi)),
          Lng: a + (r = 180 * r / (this.G.a / s * Math.cos(n) * this.G.pi))
        }

      },
    }
  }
</script>

<style lang="less" scoped>
  #container {
    width: 100%;
    height: 800px;
  }

  ::v-deep .marker-route {
    width: 60px;
    height: 30px;
    text-align: center;
    line-height: 30px;
    background-color: red;
  }

  .button {
    color: blue;
    font-size: 18px;
  }
</style>

"喜欢这篇文章吗?别忘了给个点赞哦!您的支持是我创作的动力。

相关文章
|
定位技术
百度地图:监听地图缩放自动显示和隐藏的富文本标签
百度地图:监听地图缩放自动显示和隐藏的富文本标签
196 0
|
JavaScript 定位技术 API
高德地图自定义定位 按钮
高德地图自定义定位 按钮
775 0
|
C# Windows 容器
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
NotifyIcon控件表示系统右下角任务栏上的托盘图标,其ShowBalloonTip方法用于显示气球状提示框(Win10只有为本地Toast通知),ToolTip\oolTipText可以...
1961 0
C#或Winform中的消息通知之系统托盘的气泡提示窗口(系统toast通知)、ToolTip控件和ToolTipText属性
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
Qml实用技巧:在可视元素之前半透明覆盖一个可视元素,阻止鼠标透(界面)传(防止点击到被遮挡的按钮)
|
6月前
自定义滑动工具栏
自定义滑动工具栏
38 0
|
6月前
|
Shell 开发工具 git
聊天功能演示系统发布后出现有些页面滚动与鼠标点击问题解决
聊天功能演示系统发布后出现有些页面滚动与鼠标点击问题解决
43 0
|
6月前
uniapp popup弹出窗详解以及相关属性
uniapp popup弹出窗详解以及相关属性
668 3
|
开发者
jeDate日期控件的使用以及选中后点确定按钮关闭功能
jeDate日期控件的使用以及选中后点确定按钮关闭功能
158 0
【分享】宜搭抽屉内嵌入表单,表单提交后自动隐藏抽屉
抽屉内嵌入表单,表单提交后自动隐藏抽屉
556 1
|
小程序 前端开发 JavaScript
微信小程序分类菜单激活状态跟随列表滚动自动切换
微信小程序分类菜单激活状态跟随列表滚动自动切换
164 0
微信小程序分类菜单激活状态跟随列表滚动自动切换