高德地图绘制自定义点

<template>
  <div style="position: relative">
    <div
      id="container_we"
      class="gaude-map"
    />
    <div class="all-points">
      <div
        v-for="(item, index) in allPoints"
        :key="index"
        @click="handlePoint(index, item.type, item.becomeBig)"
      >
        <div v-if="item.title !== '推荐站点地址'" class="point-site">
          <img
            v-if="item.show"
            class="point-site-img"
            :src="item.imgPoint"
            alt=""
          >
          <img
            v-else
            class="point-site-img"
            :src="item.imgCurrentPoint"
            alt=""
          >
          <span class="point-site-title" :class="!item.show ? 'current' : ''">
            <!-- 详情界面且title为:系统站点地址 -->
            <span v-if="disabled && item.title === '系统站点地址'">修改前站点地址</span>
            <span v-else-if="disabled && item.title !== '系统站点地址'">{{ item.title }}</span>
            <span v-else>{{ item.title }}</span>
          </span>
        </div>
      </div>
    </div>
    <img
      src="@/assets/pointImg/reposition.png"
      alt="重新定位"
      class="reposition"
      @mousemove="handleMouseMove"
      @mouseout="handleMouseOut"
      @click="handleReposition"
    >
    <div v-if="showReposition" class="reposition-box">
      重新定位
    </div>
  </div>
</template>
<script>
// 新的定点
import AMapLoader from '@amap/amap-jsapi-loader';
import driverShangBao from '@/assets/pointImg/driver_shang_bao.png';
import driverShangBaoOn from '@/assets/pointImg/driver_shang_bao_on.png';
import driverDingwei from '@/assets/pointImg/driver_dingwei.png';
import driverDingweiOn from '@/assets/pointImg/driver_dingwei_on.png';
import driverRecommend from '@/assets/pointImg/driver_recommend.png';
import driverRecommendOn from '@/assets/pointImg/driver_recommend_on.png';
import systemPoint from '@/assets/pointImg/system_point.png';
import systemPointOn from '@/assets/pointImg/system_point_on.png';
import modify from '@/assets/pointImg/modify.png';
import modifyOn from '@/assets/pointImg/modify_on.png';
import { ElMessage } from 'element-plus';
import { getAddressPoi } from '@/api/base';
import { nextTick } from 'vue';

export default {
  props: {
    mapData: {
      type: Object,
      default: () => {},
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    disabledetail: {
      type: Boolean,
      default: false,
    },
    historyPoint: {
      // 修改前站点地址
      type: Array,
      default: () => [],
    },
    driverDingWeiPoint: {
      // 司机定位地址
      type: Array,
      default: () => [],
    },
    driverPoint: {
      // 司机上报地址
      type: Array,
      default: () => [],
    },
    currentPoint: {
      // 系统站点地址
      type: Array,
      default: () => [],
    },
    recommendPoint: {
      // 大数据推荐
      type: Array,
      default: () => [],
    },
    addressInfo: {
      type: String,
      default: '',
    },
    addressValue: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      driverShangBao,
      driverShangBaoOn,
      driverDingwei,
      driverDingweiOn,
      driverRecommend,
      driverRecommendOn,
      systemPoint,
      systemPointOn,
      modify,
      modifyOn,
      allPoints: [
        {
          imgPoint: driverShangBao,
          imgCurrentPoint: driverShangBaoOn,
          title: '司机上报地址',
          show: true,
          type: 'driverPoint',
          becomeBig: 'driverShangBao',
        },
        {
          imgPoint: driverDingwei,
          imgCurrentPoint: driverDingweiOn,
          title: '司机当前定位',
          show: true,
          type: 'driverDingWeiPoint',
          becomeBig: 'driverDingwei',
        },
        {
          imgPoint: driverRecommend,
          imgCurrentPoint: driverRecommendOn,
          title: '推荐站点地址',
          show: false,
          type: 'recommendPoint',
          becomeBig: 'driverRecommend',
        },
        {
          imgPoint: systemPoint,
          imgCurrentPoint: systemPointOn,
          title: '系统站点地址',
          show: true,
          type: 'currentPoint',
          becomeBig: 'systemPoint',
        },
      ],
      longitude: 104.08153,
      latitude: 30.655823,
      map: null,
      canClickMap: false,
      driverShangBaoOnMarker: {},
      driverShangBaoOnAddress: [],
      driverDingweiOnMarker: {},
      driverDingweiOnAddress: [],
      modifyOnMarker: {},
      modifyOnAddress: [],
      driverRecommendOnMarker: {},
      driverRecommendOnAddress: [],
      systemPointOnMarker: {},
      systemPointOnAddress: [],
      modifyMarker: {},
      modifyAddress: [],

      match: 0,
      showReposition: false, // 显示重新定位
      repositionPoint: [], // 重新定位数据
      modifyPoint: [], // 点击地图改变的标记点
    };
  },
  watch: {
    mapData: {
      handler(n) {
        if (!n.lng) return;
        // this.clearAllMarkers();
        const adress = [n.lng, n.lat];
        this.changeMapCenter(adress);
        this.addMarker(adress, 'modifyOn');
      },
      immediate: true,
      deep: true,
    },
    disabledetail: {
      handler(n) {
        this.mapInit();
      },
    },
  },
  mounted() {
    this.mapInit();
  },
  methods: {
    // 初始化数据
    initData() {
      this.initNoHightLightPoint();
      this.modifyPoint = [];
    },
    // 初始化右上角数据置为非高亮状态
    initNoHightLightPoint() {
      this.deletePoints();
      this.allPoints.forEach((item) => {
        item.show = true;
      });
    },
    // 删除多余右上角数据
    deletePoints() {
      const len = this.allPoints.length;
      if (len === 5) {
        this.allPoints.splice(len - 1, 1);
      }
    },
    handleAllPoints() {
      const len = this.allPoints.length;
      // 详情
      if (len < 5 && this.disabled) {
        this.allPoints.push({
          imgPoint: this.modify,
          imgCurrentPoint: this.modifyOn,
          title: '修改后站点地址',
          show: true,
          type: 'modify',
          becomeBig: 'modify',
        });
      }
    },
    // 点击右上角的标记点
    handlePoint(currentIndex, type, becomeBig) {
      this.changePoingHightLight(currentIndex);
      if (this.disabled) {
        // 详情
        this.detailBecomeBig(type, becomeBig);
      } else {
        // 审核
        this.verifyBecomeBig(type, becomeBig);
      }
    },
    // 审核界面 - 点击地图标记点变大
    verifyBecomeBig(type, becomeBig) {
      if (type === 'modify') {
        this.changeMapCenter(this.modifyPoint);
      } else {
        if (this[type].length <= 0) {
          this.$message('当前站点无数据');
          return;
        }
        console.log(this[type], '点击坐标');
        // 回显坐标
        this.regeoCode({ lng: this[type][0], lat: this[type][1] });
        this.changeMapCenter(this[type]);
        this.addMarker(this[type], `${becomeBig}`);
      }
      const clickAreaRight = 'clickAreaRight'; // 是从右上角点击让地图变大
      this.becomeBig(becomeBig, clickAreaRight);
    },
    // 详情界面 - 点击地图标记点变大
    detailBecomeBig(type, becomeBig) {
      this.map.remove(this.driverShangBaoOnMarker);
      this.map.remove(this.driverDingweiOnMarker);
      this.map.remove(this.driverRecommendOnMarker);
      this.map.remove(this.systemPointOnMarker);
      this.map.remove(this.modifyOnMarker);
      const address = this[`${type}`];
      if (address.length <= 0) {
        this.$message('当前站点无数据');
        return;
      }
      if (becomeBig === 'systemPoint') {
        // 点击修改前站点地址
        if (this.historyPoint.length > 0) {
          this.changeMapCenter(this.historyPoint);
          this.addMarker(this.historyPoint, `${becomeBig}On`);
        } else {
          this.$message('当前站点无数据');
        }
      } else if (becomeBig === 'modify') {
        this.changeMapCenter(this.currentPoint);
        this.addMarker(this.currentPoint, `${becomeBig}On`);
      } else {
        this.changeMapCenter(this[type]);
        this.addMarker(address, `${becomeBig}On`);
      }
    },
    // 重新定位
    handleReposition() {
      if (this.disabled) {
        // 详情界面,不可以重新定位
        return;
      }
      this.repositionPoint = this.currentPoint;
      this.clearPointMarker();
      this.changeMapCenter(this.repositionPoint);
      if (this.allPoints.length === 5) {
        const len = this.allPoints.length - 1;
        this.allPoints.splice(len, 1);
      }
      const params = {
        addressInfo: this.addressInfo,
        addressValue: this.addressValue,
      };
      console.log(params);
      this.$emit('reposition', params);
    },
    // 鼠标移入显示重新定位
    handleMouseMove() {
      this.showReposition = true;
    },
    // 鼠标移出不显示重新定位
    handleMouseOut() {
      this.showReposition = false;
    },
    // 地图点击事件
    showInfoClick(e) {
      this.clearPointMarker();
      const { lng, lat } = e.lnglat;
      this.map.remove(this.modifyOnMarker);
      this.addMarker([lng, lat], 'modifyOn');
      this.modifyPoint = [lng, lat];
      // if (this.allPoints.length !== 5) {
      //   this.allPoints.push({
      //     imgPoint: this.modify,
      //     imgCurrentPoint: this.modifyOn,
      //     title: '修改后站点地址',
      //     show: true,
      //     type: 'modify',
      //     becomeBig: 'modify',
      //   });
      // }
      // 清除所有大图标

      this.changePoingHightLight(4);
      this.regeoCode({ lat, lng });
      // this.$emit('changPoint', [lng, lat]);
    },
    // 正向查询
    getGaoDelatitu(adress) {
      let geocoder;
      this.map.plugin('AMap.Geocoder', () => {
        geocoder = new AMap.Geocoder({
          city: '010', // 城市设为北京,默认:“全国”
          radius: 1000,
        });
        geocoder.getLocation(adress, (status, result) => {
          if (status === 'complete' && result.info === 'OK') {
            // result中对应详细地理坐标信息
            console.log(result, '正向编码');
          }
        });
      });
    },
    // 根据经纬度查询地址
    regeoCode(state) {
      let geocoder;
      const lnglat = [state.lng, state.lat];
      this.map.plugin(['AMap.Geocoder'], () => {
        geocoder = new AMap.Geocoder({
          radius: 1000,
          city: '010',
        });
        // 逆地理编码
        geocoder.getAddress(lnglat, (status, result) => {
          if (status === 'complete' && result.regeocode) {
            const address = result.regeocode.formattedAddress;
            const data = result.regeocode.addressComponent;
            const obj = {};
            obj.province = `${data.adcode.substring(0, 2)}0000`;
            obj.cityCode = data.adcode.substring(0, 3) + data.citycode;
            this.$emit('select', { ...data, ...obj, a: result.regeocode, lnglat });
            // this.remoteAddressMethod(address);
          } else {
            // ElMessage('根据经纬度查询地址失败');
          }
        });
      });
    },
    // async remoteAddressMethod(query) {
    //   const res = await getAddressPoi({ keywords: query });
    //   const { pois = [] } = res;
    //   const list = pois.map((item) => ({ ...item, cityCodeNew: `${item.adcode.slice(0, 4)}00` }));
    //   // state.form.name = list && list.length ? list[0].name : '';
    //   this.$emit('select', list[0], list);
    // },

    showAllMarker() {
      if (this.map) {
        this.map.setFitView(null, false, [100, 100, 100, 100]);
      }
    },
    changeClickMap(type) {
      this.canClickMap = type;
    },
    mapInit(address) {
      this.repositionPoint = address;
      if (address && address[0] && address[1]) {
        [this.longitude, this.latitude] = address;
      }
      // 全局地图变量 AMap
      this.map = new AMap.Map('container_we', {
        zoom: 15,
        center: [this.longitude, this.latitude],
      });
      if (this.disabledetail) {
        this.map.off('click', this.showInfoClick);
      } else if (this.disabled) {
        this.map.on('click', this.showInfoClick);
      } else {
        // 审核
        this.deletePoints();
        this.map.on('click', this.showInfoClick); // 添加地图点击事件
      }
    },
    mapInitMarker() {
    },
    changeMapCenter(center) {
      if (this.map === null) {
        this.mapInit();
      }
      console.log(this.map, '地图切换');
      this.map.panTo(center);
    },
    getContent(type) {
      let content = '';
      if (type === 'driverDingwei') {
        content = '司机当前定位';
      } else if (type === 'systemPoint') {
        content = '系统站点地址';
      } else if (type === 'driverShangBao') {
        content = '司机上报地址';
      } else {
        content = '';
      }
      return content;
    },
    addMarker(address, type, match) {
      // match 匹配度
      const icon = new AMap.Icon({
        // 图标尺寸
        size: new AMap.Size(32, 32),
        // 图标的取图地址
        image: this[type],
        // 图标所用图片大小
        imageSize: new AMap.Size(32, 32),
        // 图标取图偏移量
        imageOffset: new AMap.Pixel(0, 0),
      });
      const [lng, lat] = address;
      const marker = new AMap.Marker({
        position: new AMap.LngLat(lng, lat),
        icon,
      });
      const content = this.getContent(type);
      if (content) {
        marker.setLabel({
          offset: new AMap.Pixel(-60, -35), // 设置文本标注偏移量
          content: `<div class='info-content'>${content}</div>`, // 设置文本标注内容
          direction: 'right', // 设置文本标注方位
        });
      }
      this[`${type}Marker`] = marker;
      if (type !== 'systemPointOn' && this.canClickMap) {
        this[`${type}Address`] = address;
        marker.on('click', this[`${type}BecomeBig`]);
        if (type === 'modifyOn') {
          this.modifyPoint = address;
          this.modifyMarker = marker;
          this.modifyAddress = address;
        }
      }
      if (!this.canClickMap && type === 'driverRecommend') {
        this.driverRecommendOnAddress = address;
      }
      if (match) {
        this.match = match;
        marker.on('click', this.clickBlue);
        this.clickBlue(lng, lat, icon);
      }
      if (address.length > 0 && this.map) {
        // 判断是否有地图标记点坐标以及地图是否已经渲染完成
        this.map.add(marker);
      }
    },
    driverDingweiBecomeBig() {
      this.becomeBig('driverDingwei', 'test');
      this.changePoingHightLight(1);
    },
    systemPointBecomeBig() {
      this.becomeBig('systemPoint', 'test');
      this.changePoingHightLight(3);
    },
    driverShangBaoBecomeBig() {
      this.becomeBig('driverShangBao', 'test');
      this.changePoingHightLight(0);
    },
    driverRecommendBecomeBig() {
      this.becomeBig('driverRecommend', 'test');
      this.changePoingHightLight(2);
    },
    modifyBecomeBig() {
      this.becomeBig('modify', 'test');
      this.changePoingHightLight(4);
    },
    // 点击地图标记点,右上角框框内容对应高亮
    changePoingHightLight(currentIndex) {
      this.allPoints.forEach((item, index) => {
        if (currentIndex !== index) {
          item.show = true;
        } else {
          item.show = false;
        }
      });
    },
    // 点击坐标点  addMarker
    becomeBig(type, clickAreaRight) {
      console.log(type, clickAreaRight);
      this.clearPointMarker(clickAreaRight);
      let address = [];
      if (!this.disabled) {
        // 审核界面
        address = this[`${type}Address`];
        this.$emit('changPoint', this[`${type}Address`], true);
      } else {
        // 详情界面
        address = this.judgePointType(type);
      }
      if (address && address.length > 0) {
        if (this.modifyPoint.length > 0 && clickAreaRight === 'clickAreaRight' && type !== 'modify') {
          this.addMarker(this.modifyPoint, 'modifyOn');
          this.addMarker(address, `${type}On`);
        } else if (this.modifyPoint.length > 0 && clickAreaRight === 'clickAreaRight' && type === 'modify') {
          this.addMarker(address, `${type}On`);
        } else {
          this.addMarker(address, `${type}On`);
        }
      } else {
        // this.$message('当前无坐标数据');
      }
    },
    judgePointType(type) {
      let address = [];
      if (type === 'driverShangBao') {
        address = this.driverPoint;
      } else if (type === 'systemPoint') {
        address = !this.disabled ? this.currentPoint : this.historyPoint;
      } else if (type === 'driverRecommend') {
        address = this.recommendPoint;
      } else if (type === 'driverDingwei') {
        address = this.driverDingWeiPoint;
      } else {
        address = [];
      }
      return address;
    },
    clickBlue(lng, lat, icon) {
      const marker = new AMap.Marker({
        position: new AMap.LngLat(lng, lat),
        icon,
      });
      marker.setLabel({
        offset: new AMap.Pixel(-80, -45), // 设置文本标注偏移量
        content: `<div class="info-content">大数据推荐站点地址<div class="text" >匹配度${
          this.match * 100
        }%</div></div>`, // 设置文本标注内容
        direction: 'right', // 设置文本标注方位
      });
      this.map.add(marker);
    },
    // 清除站点
    clearPointMarker() {
      this.map.remove(this.driverShangBaoOnMarker);
      this.map.remove(this.driverDingweiOnMarker);
      this.map.remove(this.driverRecommendOnMarker);
      this.map.remove(this.systemPointOnMarker);
      this.map.remove(this.modifyMarker);
      this.map.remove(this.modifyOnMarker);
      console.log('清除完毕');
    },
    clearAllMarkers() {
      [this.longitude, this.latitude] = [104.08153, 30.655823];
      this.mapInit();
    },
  },
};
</script>

<style>
.gaude-map {
  z-index: 100;
  height: 360px;
  width: 100%;
  overflow-x: hidden;
  overflow-y: scroll;
}

.gaude-map .amap-ui-control-zoom {
  width: 24px !important;
  position: absolute;
  bottom: 12px;
  right: -18px;
  border: none;
}

.gaude-map .amap-ui-control-zoom a {
  margin-bottom: 4px;
}

.gaude-map .amap-ui-control-zoom a,
.gaude-map .amap-ui-control-zoom-num {
  width: 24px !important;
  height: 24px !important;
  line-height: 24px !important;
  border-bottom: none !important;
  color: #323233 !important;
  font-size: 16px !important;
  font-weight: bold !important;
}

.all-points {
  z-index: 120;
  position: absolute;
  right: 30px;
  top: 20px;
  width: 138px;
  height: 192px;
}

.point-site {
  width: 138px;
  height: 32px;
  background-color: rgba(255, 255, 255, 0.9);
  border-radius: 2px;
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  box-sizing: border-box;
  padding: 0 8px;
  cursor: pointer;
}

.point-site-img {
  width: 20px;
  height: 20px;
  margin-right: 4px;
}

.point-site-title {
  color: #969799;
  font-size: 14px;
}

.current {
  color: var(--el-text-color-primary);
}

.reposition {
  width: 32px;
  height: 32px;
  z-index: 99993;
  position: absolute;
  right: 25px;
  bottom: 14px;
}

.reposition-box {
  z-index: 120;
  position: absolute;
  right: 60px;
  bottom: 18px;
  background: #646566;
  color: var(--el-text-color-primary);
  width: 70px;
  height: 24px;
  font-size: 12px;
  text-align: center;
  line-height: 24px;
  border-radius: 2px;
}

.reposition-box::after {
  position: absolute;
  right: -8px;
  margin-left: -8px;
  transform: rotate(90deg);
  bottom: 8px;
  content: '';
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 6px solid #646566;
}

.amap-sug-result {
  z-index: 10000;
}

.amap-marker-label {
  border: none;
  background-color: transparent;
}

.info-content {
  box-sizing: border-box;
  padding: 4px 8px;
  font-size: 12px;
  border-radius: 2px;
  color: var(--el-text-color-primary);
  background: #646566;
  box-shadow: 0px 2px 8px 0px rgba(200, 201, 204, 0.5);
  position: relative;
}

.text {
  text-align: center;
}

.info-content::after {
  position: absolute;
  left: 50%;
  margin-left: -6px;
  transform: rotate(-180deg);
  bottom: -6px;
  content: '';
  width: 0;
  height: 0;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 6px solid #646566;
}
</style>
        <gandeMap
          disabledetail={f.checkIn}
          ref={gandeMapRef}
          driverPoint={[form.driverUpdatelo, form.driverUpdatela]}
          driverDingWeiPoint={[form.driverLongitude, form.driverLatitude]}
          currentPoint={[form.stationlo, form.stationla]}
          onSelect={handleSelect}
          onChangPoint={getChangePoint}
          mapData={mapData}
        />

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值