高德地图——态势标绘,创建点、移动位置、缩放、旋转、保存、删除

avatar
作者
猴君
阅读量:0

image.png

  • 拖动左侧图标到地图上某个位置,在地图上创建该类型的点,存储在list
  • 拖拽点移动,重新更新其坐标
  • 编辑点的大小及角度,清除之前的重新创建新的点
  • 删除点,清除点,但数据不能清除,更改show
  • 最后保存list数据并截图保存
  • 下次进来渲染点重新编辑
<template>   <div class="index5 w100 h100 white relative">     <canvas       id="myCanvas"       style="display: none; width: 100vw; height: 100vh"     ></canvas>     <img       src="./components/img/home.png"       alt=""       class="home pointer"       @click="$router.back()"     />     <!-- 地图区域 -->     <div id="containerMap" class="w100 h100" ref="htmlImg"></div>     <!-- 左侧菜单 -->     <div       v-show="showMenu"       class="left h80 absolute animate__animated animate__slideInLeft animate__fast"     >       <div class="w100 pdRem-20 h100">         <dv-border-box-8           :color="['rgba(2, 208, 249,.5)', '#0dcff2']"           backgroundColor="rgba(4, 33, 66,.8)"         >           <div class="plrRem-20 ptbRem-10 flex flex-column w100 h100">             <div class="title flex_l mtb-20">               <img src="./components/img/index1-title.png" alt="" />               作战标绘             </div>             <div class="flex flex-wrap w100">               <div                 class="item plr-20 text-center mb-20 pointer"                 style="width: 50%"                 v-for="(item, index) in tab"                 :key="index"               >                 <!-- ☆☆☆☆☆ 拖拽图片默认会打开窗口预览,换成背景图即可 -->                 <!-- <img :src="item.icon" alt="" style="width: 50px" /> -->                 <div                   draggable="true"                   @dragstart="onDragStart"                   @dragend="onDragEnd"                   :data-index="index"                   class="img-bg"                   :style="{                     backgroundImage: `url(${item.icon})`,                     backgroundRepeat: 'no-repeat',                     backgroundPosition: 'center',                     backgroundSize: 'cover',                     backgroundAttachment: 'local',                   }"                 ></div>                  <div class="mt-4">{{ item.text }}</div>               </div>             </div>             <img               src="./components/img/index5-btn4.png"               alt=""               style="width: 140px; margin: 60px auto 20px"               @click="issueImg"               class="pointer"             />           </div>         </dv-border-box-8>       </div>     </div>     <!-- 右下控制 -->     <div       v-show="showMenu && showEdit"       class="right absolute animate__animated animate__slideInLeft animate__fast pdRem-20"     >       <div class="w100 h100 editBox ptRem-14 pbRem-10 plRem-10 prRem-20">         <div class="plrRem-20 ptbRem-10 flex flex-column w100 h100 editContent">           <div class="title flex_l mtb-10">             <img src="./components/img/index1-title.png" alt="" />             标绘属性           </div>           <div class="plrRem-20 mbRem-20 flex flex-column">             <div class="flex1">               <div style="width: 60px; font-size: 0.2rem">缩放:</div>               <div class="flex-1">                 <el-slider                   :max="10"                   :min="0.5"                   :step="0.5"                   v-model="scale"                   @change="editMarker"                 ></el-slider>               </div>             </div>             <div class="flex1">               <div style="width: 60px; font-size: 0.2rem">角度:</div>               <div class="flex-1">                 <el-slider                   :max="360"                   :step="5"                   v-model="rotate"                   @change="editMarker"                 ></el-slider>               </div>             </div>           </div>           <div class="w100 center mb-20">             <!-- <img               src="./components/img/index5-btn1.png"               alt=""               style="width: 140px"               @click="saveImg"               class="pointer"               v-if="isSave"             /> -->             <img               src="./components/img/index5-btn3.png"               alt=""               style="width: 120px"               @click="removeMarker"               class="pointer"             />           </div>         </div>       </div>     </div>   </div> </template>  <script> import html2canvas from "html2canvas";  import "./components/js/flexible.js"; import {   getPoliceDetailApi,   uploadHtmlImg,   dispatchHtmlImg, } from "./components/js/api";  import AMapLoader from "@amap/amap-jsapi-loader"; import icon1 from "./components/img/index5-1.png"; import icon2 from "./components/img/index5-2.png"; import icon3 from "./components/img/index5-3.png"; import icon4 from "./components/img/index5-4.png"; import icon5 from "./components/img/index5-5.png"; import icon6 from "./components/img/index5-6.png"; import icon7 from "./components/img/index5-7.png"; import icon8 from "./components/img/index5-8.png"; import icon9 from "./components/img/index5-9.png";  //秘钥 window._AMapSecurityConfig = {   securityJsCode: "3e9a9aeb435372339552fc215f8d0918", }; export default {   data() {     return {       position: [],       policeId: "",       map: null,       showMenu: true,       tab: [         {           id: 1,           icon: icon1,           text: "消防车",         },         {           id: 2,           icon: icon2,           text: "消防员",         },         {           id: 3,           icon: icon3,           text: "水管",         },         {           id: 4,           icon: icon4,           text: "进攻方向",         },         {           id: 5,           icon: icon5,           text: "消防栓",         },         {           id: 6,           icon: icon6,           text: "危化品",         },         {           id: 7,           icon: icon7,           text: "风向",         },         {           id: 8,           icon: icon8,           text: "指北矢标",         },       ],       list: [], //地图上所有的marker       draggingEnded: false,       index: null, //当前拖动的索引-对应左侧菜单       showEdit: false, //是否显示编辑       item: {}, //当前编辑的marker       // 编辑       scale: 1, //缩放       rotate: 0, //旋转角度        //保存       baseUrl: process.env.VUE_APP_BASE_API,       isSave: false,           };   },   mounted() {     this.position = this.$route.query.position.split(",");     this.policeId = this.$route.query.id;     this.initAMap();   },   beforeDestroy() {     this.map.destroy();   },   methods: {     // -----------地图--------------     initAMap() {       AMapLoader.load({         key: "130cca3be68a2ff0fd5ebb6de25e4eac", // 申请好的Web端开发者Key,首次调用 load 时必填         version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15         plugins: [           //   "AMap.ControlBar",           //   "AMap.ToolBar",           //   "AMap.Weather",           //   "AMap.CitySearch",           //   "AMap.Marker",            //   "AMap.MouseTool",           //   "AMap.PolyEditor",           //   "AMap.Polyline",           //   "AMap.Geolocation",           //   "AMap.GraspRoad",           //   "AMap.Geocoder",           //   "AMap.GeometryUtil.ringArea",           //   "AMap.DistrictSearch",           //   "AMap.MoveAnimation",           "AMap.Driving", // 驾车路线路径规划         ], // 需要使用的的插件列表,如比例尺'AMap.Scale'等       })         .then((AMap) => {           this.map = new AMap.Map("containerMap", {             // 设置地图容器id             // rotateEnable: true, // 旋转             // pitchEnable: true, // 倾斜             zoom: 13, // 初始化地图层级             // pitch: 50, // 倾斜角度             // rotation: -15, // 地图旋转角度             // viewMode: "3D", //开启3D视图,默认为关闭             zooms: [2, 20], // 设置地图显示范围             center: [119.419251, 32.400703], // 设置地图中心点             mapStyle: "amap://styles/blue", //设置地图的显示样式             WebGLParams: {               preserveDrawingBuffer: true, // 使用html2canvas截取需要设置该属性,否则截取不到地图             },           });            this.map.on("complete", () => {             console.log("地图加载完成");             this.isSave = true;             this.createFireMarker();             //可以监听到拖动到地图             this.map.on("mouseover", this.onMouseOver);             getPoliceDetailApi(this.policeId).then((res) => {               if (res.data.screenshotParam) {                 this.list = JSON.parse(res.data.screenshotParam);                 this.showMarker();               }             });           });           this.map.on("click", (e) => {             // e 是事件对象,包含了点击的位置等信息             var lnglat = e.lnglat; // 获取经纬度坐标             console.log("地图被点击,坐标:" + lnglat.lng + ", " + lnglat.lat);             this.showEdit = false;             // 在此处可以进行进一步的操作,如弹出信息窗口、绘制标记等           });         })         .catch((e) => {           console.log(e);         });     },     //----------添加警情中心点标记 -------     createFireMarker() {       var marker = new AMap.Marker({         position: new AMap.LngLat(...this.position),         icon: new AMap.Icon({           image: fireIcon,           imageSize: new AMap.Size(32, 42),         }),         // zIndex: 200,       });       this.map.add(marker);       // 设置地图中心点       this.map.setCenter(new AMap.LngLat(...this.position));     },     onDragStart(event) {       // console.log("Drag start", event, event.target.dataset.index);       //event.dataTransfer.setData(       //  "application/index",       //  event.target.dataset.index       //);       // 你还可以在这里做其他事情,比如改变元素的样式或状态       this.draggingEnded = false;       this.index = event.target.dataset.index * 1;     },     onDragEnd(event) {       // console.log(       //   "Drag end",       //   event,       //   event.dataTransfer.getData("application/index")       // );       //const data = event.dataTransfer.getData("application/index"); // 获取拖动时设置的数据       // console.log("接收到的数据:", data);       // 拖拽结束时,你可以做一些清理工作,例如重置元素样式或状态       this.draggingEnded = true;     },     onMouseOver(event) {       // console.log("mouseover", event.lnglat);       if (this.draggingEnded) {         // 转换鼠标位置为地理坐标         this.draggingEnded = false;         this.createMarker([event.lnglat.lng, event.lnglat.lat]);       }     },     // 页面一进来拿到上次的list渲染出来     showMarker() {       this.list.forEach((item, index) => {         item.show = true;         item.marker = null;         item.icon = [icon1, icon2, icon3, icon4, icon5, icon6, icon7, icon8][           item.id * 1         ];         var markerContent =           '<div class="custom-content-marker" >' +           '<img style="transform:rotate(' +           item.rotate +           "deg) scale(" +           item.scale +           ');width:60px;height:60px" src=" ' +           item.icon +           '">' +           "</div>";         item.marker = new AMap.Marker({           position: new AMap.LngLat(...item.lnglat),           content: markerContent,           // 以 icon 的 [center bottom] 为原点           offset: new AMap.Pixel(-25, -50),           // zIndex: 200,           cursor: "move",           draggable: true,         });         this.map.add(item.marker);          // 监听点点击事件         this.list[index].marker.on("click", (e) => {           this.item = this.list[index];           this.scale = this.item.scale;           this.rotate = this.item.rotate;           this.showEdit = true;           //拖动坐标获取新坐标           console.log("点击:", this.item.id);         });          // 监听点拖动更新坐标         this.list[index].marker.on("dragend", (e) => {           this.list[index].lnglat = [             this.list[index].marker.getPosition().lng,             this.list[index].marker.getPosition().lat,           ];           this.item = this.list[index];           this.scale = this.item.scale;           this.rotate = this.item.rotate;           this.showEdit = true;           //拖动坐标获取新坐标           console.log(             "最新坐标:",             [               this.list[index].marker.getPosition().lng,               this.list[index].marker.getPosition().lat,             ],             this.list,             this.item           );         });       });        console.log("createMarker", this.list);     },     // 从左侧拖动过来新建点     createMarker(lnglat) {       let length = this.list.length;       this.list.push({         id: this.index,         lnglat: lnglat,         icon: this.tab[this.index].icon,         marker: null,         scale: 1,         rotate: 0,         show: true,       });       this.item = this.list[length];       console.log("createMarker", this.index);       var markerContent =         '<div class="custom-content-marker" >' +         '<img style="transform:rotate(' +         this.item.rotate +         "deg) scale(" +         this.item.scale +         ');width:60px;height:60px" src=" ' +         this.item.icon +         '">' +         "</div>";       this.item.marker = new AMap.Marker({         position: new AMap.LngLat(...this.item.lnglat),         content: markerContent,         // 以 icon 的 [center bottom] 为原点         offset: new AMap.Pixel(-25, -50),         // zIndex: 200,         cursor: "move",         draggable: true,       });       this.map.add(this.item.marker);       this.showEdit = true;       this.scale = this.item.scale;       this.rotate = this.item.rotate;       console.log("createMarker", this.list, this.item);        // 监听点点击事件       this.list[length].marker.on("click", (e) => {         this.item = this.list[length];         this.scale = this.item.scale;         this.rotate = this.item.rotate;         this.showEdit = true;         //拖动坐标获取新坐标         console.log("点击:", this.item.id);       });        // 监听点拖动更新坐标       this.list[length].marker.on("dragend", (e) => {         this.list[length].lnglat = [           this.list[length].marker.getPosition().lng,           this.list[length].marker.getPosition().lat,         ];         this.item = this.list[length];         this.scale = this.item.scale;         this.rotate = this.item.rotate;         this.showEdit = true;         //拖动坐标获取新坐标         console.log(           "最新坐标:",           [             this.list[length].marker.getPosition().lng,             this.list[length].marker.getPosition().lat,           ],           this.list,           this.item         );       });     },          // 编辑点重新渲染     editMarker() {       var index = this.list.indexOf(this.item);       console.log("编辑", this.rotate, this.scale, this.list[index]);       this.list[index].scale = this.scale;       this.list[index].rotate = this.rotate;       this.map.remove(this.list[index].marker);       this.list[index].marker = null;       var markerContent =         '<div class="custom-content-marker"  >' +         '<img style="transform:rotate(' +         this.list[index].rotate +         "deg) scale(" +         this.list[index].scale +         ');width:60px;height:60px" src=" ' +         this.list[index].icon +         '">' +         "</div>";       console.log("编辑", markerContent);       this.list[index].marker = new AMap.Marker({         position: new AMap.LngLat(...this.list[index].lnglat),         content: markerContent,         // 以 icon 的 [center bottom] 为原点         offset: new AMap.Pixel(-25, -50),         // zIndex: 200,         cursor: "move",         draggable: true,       });       this.map.add(this.list[index].marker);       // 监听点点击事件       this.list[index].marker.on("click", (e) => {         this.item = this.list[index];         this.scale = this.list[index].scale;         this.rotate = this.list[index].rotate;         this.showEdit = true;         //拖动坐标获取新坐标         console.log("点击11:", this.item.id);       });        // 监听点拖动更新坐标       this.list[index].marker.on("dragend", (e) => {         this.item = this.list[index];         this.item.lnglat = [           this.list[index].marker.getPosition().lng,           this.list[index].marker.getPosition().lat,         ];         this.scale = this.list[index].scale;         this.rotate = this.list[index].rotate;         this.showEdit = true;       });     },     // 删除点     removeMarker() {       var index = this.list.indexOf(this.item);       this.list[index].show = false;       this.map.remove(this.list[index].marker);       this.item = {};       this.showEdit = false;       console.log("删除", this.list, this.item, index);     },      /* -----------------------------下发作战--------------------- */     issueImg() {       this.showMenu = false;       let arr = this.list.filter((item) => item.show);       let arr1 = arr.map((item) => {         return {           id: item.id,           lnglat: item.lnglat,           scale: item.scale,           rotate: item.rotate,         };       });        html2canvas(this.$refs.htmlImg, {         useCORS: true, //保证跨域图片的显示,如果为不添加改属性,或者值为false,地图底图不显示         x: window.pageXOffset, //页面在水平方向的滚动距离         y: window.pageYOffset, //页面在垂直方向的滚动距离       }).then((canvas) => {         var img = new Image();         var canvas2 = document.getElementById("myCanvas");         var ctx = canvas2.getContext("2d");         ctx.fillStyle = "#FFFFFF"; //画布填充色         ctx.lineWidth = "1";         ctx.rect(20, 30, canvas2.width - 40, canvas2.height - 60); //矩形距离画布左上角水平和垂直距离,矩形的宽高         ctx.stroke();         img.src = canvas.toDataURL();          var url = canvas.toDataURL("image/png");         const blobImage = this.dataURLtoBlob(url);         let fileName = `htmlImg_${new Date().getTime()}.jpg`;         const fileOfBlob = new File([blobImage], fileName);         let formData = new FormData();         formData.append("file", fileOfBlob, fileName);         this.isSave = false;         uploadHtmlImg(formData).then((res) => {           this.showMenu = true;           this.isSave = true;           // this.$modal.msgSuccess("上传成功");            let saveObj = {             policeId: this.$route.query.id,             // policeId: 196,             fileName: res.fileName,             url: res.url,             screenshotParam: JSON.stringify(arr1),           };           dispatchHtmlImg(saveObj).then((res) => {             this.$modal.msgSuccess("标绘下发成功,可在小程序对应警情中查看");           });           console.log("http://192.168.0.19:12020" + res.url);           // console.log(this.baseUrl + res.url);         });       });     },     // 转成bolb对象     dataURLtoBlob(dataUrl) {       let arr = dataUrl.split(","),         mime = arr[0].match(/:(.*?);/)[1],         bstr = atob(arr[1]),         n = bstr.length,         u8arr = new Uint8Array(n);       while (n--) {         u8arr[n] = bstr.charCodeAt(n);       }       return new Blob([u8arr], {         type: mime,       });     },            }, }; </script>  <style scoped lang="scss"> @import "./components/css/rem.scss"; .index5 {   .home {     width: 50px;     position: fixed;     right: 20px;     top: 20px;     z-index: 9999;   }   .left {     width: 280px;     left: 0;     top: 10%;     .img-bg {       width: 50px;       height: 50px;       margin: auto;     }   }   .right {     width: 360px;     // height: 280px;     right: 50px;     bottom: 50px;      .editBox {       background: #0005495d;       background-image: url("./components/img/index5-bg-1.png");       background-repeat: no-repeat; /* 防止重复平铺 */       background-position: center; /* 居中对齐 */       background-size: 100% 100%; /* 根据容器大小等比例缩放至最大尺寸 */       background-attachment: local;       .editContent {         // background-image: url("./components/img/index5-bg-2.png");         // background-repeat: no-repeat; /* 防止重复平铺 */         // background-position: center; /* 居中对齐 */         // background-size: 100% 100%; /* 根据容器大小等比例缩放至最大尺寸 */         // background-attachment: local;       }     }   }   ::v-deep .el-slider__runway {     background-color: rgba(0, 255, 255, 0.253);   }   ::v-deep .el-slider__bar {     background-color: aqua;   }   ::v-deep .el-slider__button {     border: 2px solid aqua;   }    ::v-deep .amap-marker-label {     background: rgba(0, 0, 0, 0);     color: aqua;     border: none;   }   ::v-deep .amap-icon {     width: 50px !important;     height: 50px !important;   }   .title {     font-size: 0.2rem;     font-weight: 700;     text-shadow: 0px 3px 7px #006cbf;     img {       width: 0.4rem;       height: 0.4rem;     }   }    .carInfo {     position: absolute;     border-radius: 10px;     border: 1px solid cyan;     background: rgba(0, 50, 73, 0.8);     // left: 120px;     // top: 230px;     // background: url("./components/img/car-bg.png") no-repeat center center;     background-size: 100% 100%;     padding: 16px 10px 14px 20px;     ::v-deep .dv-water-pond-level text {       font-size: 15px;       font-weight: normal !important;       color: #fff !important;     }   } } .main {   height: 1600px;   width: 100%;   background: #d4edff; } .svg {   border: 1px solid red;   width: 100px;   height: 100px; } </style>  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!