Vue3对接高德地图流程

注:如果刚着手的话可以先去体验一下高德地图 JS API

一、前期准备

  1. 就是登录高德官网注册并登录账号,完成个人开发者认证,然后就是进入控制台,应用管理-我的应用。我的应用点击创建新应用,输入应用名称和选择应用类型。
    在这里插入图片描述
  2. 应用新建成功之后,为当前应用添加key,在后续调用高德定位API的时候将此key作为参数传递,服务平台根据自己所需要的类型选择即可,输入完必输项点击提交即可完成创建。
    在这里插入图片描述
  3. 提交之后就能看到你的key和安全密钥了。
    在这里插入图片描述

二、在vue中的使用

  1. 先安装 @amap/amap-jsapi-loader
cnpm i @amap/amap-jsapi-loader -S
 
npm i @amap/amap-jsapi-loader -S
  1. 在项目中新建文件,用作地图组件。文件内容如下:
<template>
  <div ref="mapRef" class="map"></div>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import iconPoint from "../assets/position.png";
import iconPointActive from "../assets/positionActive.png";
import { onMounted, ref, watch } from 'vue'
import { updata } from "rxp-core"
export default {
  props:{
    industryType:String
  },
  setup(props,{ emit }) {
    const mapRef = ref(null)
    const mapPortrait = ref(null)
    const initMap = ()=>{
      AMapLoader.load({
        key:"41fff47119413ee329ca3f26c00cb595",             // 申请好的Web端开发者Key,首次调用 load 时必填
        plugins:['AMap.Scale'],       // 需要使用的的插件列表,如比例尺'AMap.Scale'等
        AMapUI: {
          version: '1.1',
          plugins:['overlay/SimpleMarker','geo/DistrictExplorer']
        },
      }).then((AMap)=>{
        const mapData = new AMap.Map(mapRef.value, {
          mapStyle: 'amap://styles/98b26d04358dd80ee479ca1dfe9edd06', // 配置的地图样式
          zoom: 12,
          zooms:[8,20],
          center: [118.317325, 29.709239],
          features: ['bg'], // 支持'bg'(地图背景)、'point'(POI点)、'road'(道路)、'building'(建筑物)
          resizeEnable: true, // 监控地图容器尺寸变化,默认值为false
          expandZoomRange: true // 支持可以扩展最大缩放级别,和zooms属性配合使用,设置为true的时候,zooms的最大级别在PC上可以扩大到20级
        });
        mapPortrait.value = mapData
        var style = [{
          url: iconPoint,
          anchor: new AMap.Pixel(28, 28),
          size: new AMap.Size(28, 28),
        },{
          url: iconPointActive,
          anchor: new AMap.Pixel(28, 28),
          size: new AMap.Size(28, 28),
        }]
        var mass = new AMap.MassMarks(companyPositionData.value, {
          opacity: 1,
          cursor: 'pointer',
          zooms:[8,20],
          style: style,
          zIndex: 111,
        });
        mass.on('mouseover', function (e) {
          let content = `<div class="infoWindow mrgb" οnclick=selectCompany("${e.data.companyId}")>`+
            '<div class="value"><span>'+e.data.name+'</span></div>' +
            '</div>';
          openInfoWindow(e.data.lnglat,content)
          e.data.style = 1;
        });
        mass.on('mouseout', function (e) {
          mapData.clearInfoWindow()
          e.data.style = 0;
        });
        mass.setMap(mapData)
        drawAreaNode()
        // companyPositionData.value.forEach(item => {
        //   setMarker([item.locLng, item.locLat],item.companyName)
        // });
        return mapData
      }).catch(e=>{
          console.log(e,1111);
      })
    }
    const drawAreaNode = ()=>{
      // console.log(mapPortrait.value,window.AMapUI.load)
      window.AMapUI.load(['ui/geo/DistrictExplorer', 'lib/$'], function(DistrictExplorer, $) {
        var districtExplorer = window.districtExplorer = new DistrictExplorer({
          map:mapPortrait.value,
        });
        //设置当前使用的定位用节点
        var currentAreaNode = 341000;   //这里是黄山的区域码
        districtExplorer.setAreaNodesForLocating([currentAreaNode]);
        //文档上说 areaNode 只能通过  loadAreaNode方法和 loadMutiuAreaNode
        districtExplorer.loadAreaNode(currentAreaNode, function(error, areaNode) {
          if(error){
            return;
          }
          //更新地图视野  它会根据浏览器自动更新
          mapPortrait.value.setBounds(areaNode.getBounds(), null, null, true);
          //清除已有的绘制内容
          districtExplorer.clearFeaturePolygons();

          //绘制子区域
          // 这个方法内部应该有一个 foreach 的循环的过程, 不需要使用者去显示的 循环每一个子节点
          districtExplorer.renderSubFeatures(areaNode, function(feature, i) {
            //这里是随便设置了几个不同的 填充色  和 边框色
            var fillColor = ["#E6F6FF", "#C0DDFF", "#EFF7FF", "#FFC55B", "#B7D4FF", "#5F8DE7", "#80B1FC"];
            var strokeColor = ["#C0DDFF", "#69BCFF", "#E6F6FF", "#C5E0FF", "#E6F6FF", "#E6F6FF", "#E6F6FF"];
            //--------------------------这里是在画文本标记-------------------------------------
            //这里通过  feature 的属性, 得到行政区域的中心点, 准备把 文标标记放在这个位置上
            let name = feature.properties.name
            let center = feature.properties.center;
            let text = new AMap.Text({
              text:name,
              anchor:'center', // 设置文本标记锚点
              draggable:false,
              cursor:'pointer',
              zIndex: 0,
              style:{
                'display':"inline",
                'background-color': '#ffffff50',
                'width': '15rem',
                'text-align': 'center',
                'font-size': '9px',
                'color': '#203251'
              },
              position:center
            })
            text.setMap(mapPortrait.value);
            
            text.on('mouseover',()=>{
              mapPortrait.value.clearInfoWindow()
                  let content = '<div class="infoWindow">' +
                      `<div class="areaName">${name}</div>`+
                      '<div class="value">企业数量:<span>'+getNum(name).companyNum+'</span> 家</div>' +
                      '<div class="value">重点企业:<span>'+getNum(name).importantCompanyNum+'</span> 家</div>' +
                      '</div>';
                  openInfoWindow(center,content)
            })
            text.on('mouseout',()=>{
              mapPortrait.value.clearInfoWindow()
            })
            //------------------------------这里是在画文本标记------------------------------------
            return {
              cursor: 'default',
              bubble: true,
              strokeColor: strokeColor[i+1], //线颜色
              strokeOpacity: 1, //线透明度
              strokeWeight: 1, //线宽
              fillColor: fillColor[i], //填充色
              fillOpacity: 1, //填充透明度
            };
          });

          //绘制父区域
          districtExplorer.renderParentFeature(areaNode, {
            cursor: 'default',
            bubble: true,
            strokeColor: '#4980EB', //线颜色
            strokeOpacity: 1, //线透明度
            strokeWeight: 1, //线宽
            fillColor: "#4980EB",
            fillOpacity: 0.05, //填充透明度
          });
        });
      });
    }
    //构建自定义窗体并打开
    const openInfoWindow = (position,content) => {
      let infoWindow = new AMap.InfoWindow({
          isCustom: true, //使用自定义窗体
          content: content,
          offset: new AMap.Pixel(0, 0),
      })
      infoWindow.open(mapPortrait.value, position)
    }
    const setMarker = (center,companyName) => {
      var marker = new AMap.Marker({
        position: new AMap.LngLat(center[0], center[1]),
        offset: new AMap.Pixel(-10, -10),
        icon: new AMap.Icon({            
          image: iconPoint,
          size: new AMap.Size(32, 32),  //图标大小
          imageSize: new AMap.Size(32,32),
        }),
        zIndex:10,
        title: '黄山市'
      });
      mapPortrait.value.add(marker)
      marker.on('click', (e)=>{
        let content = '<div class="infoWindow">'+
          '<div class="value"><span>'+companyName+'</span></div>' +
          '</div>';
        openInfoWindow(center,content)
      })
      marker.on('mouseout',(e)=>{
        mapPortrait.value.clearInfoWindow()
      });
    }
    const areaList = ref([])
    const companyPositionData = ref([])
    const getData = ()=>{
      updata.getAreaCompanyStatistics(props.industryType).then(res=>{
        if(res){
          areaList.value = res.data
        }
      })
      updata.getAllCompanyLocation(props.industryType).then(res=>{
        if(res){
          companyPositionData.value = res.data.map(item => {
            return{
              lnglat:[item.locLng, item.locLat],
              name:item.companyName,
              companyId:item.companyId
            }
          });
          initMap()
        }
      })
    }
    const getNum = (area)=>{
      let obj = areaList.value.find(item => {
        return item.area == area
      });
      return obj
    }
    const selectCompany=(id)=>{
      emit("selectCompany", id);
    }
    watch(()=>props.industryType,(newValue,oldValue)=>{
      getData()
      // initMap()
    })
    onMounted(()=>{
      window.selectCompany = selectCompany;
      getData()
      // mapPortrait.value = initMap()
      // initMap()
    })
    return{
      mapRef,
      mapPortrait,
      initMap,
      drawAreaNode,
      openInfoWindow,
      setMarker,
      areaList,
      companyPositionData,
      getData,
      getNum,
      selectCompany
    }
  },
}
</script>
<style lang="less">
.amap-logo{
  display: none !important;
}
.map{
  height: 100%;
}
.infoWindow{
  background: rgba(255,255,255,0.7);
  box-shadow: 0px 4px 7px 4px rgba(54,65,96,0.02);
  border-radius: 4px;
  border: 1px solid #EBEFF5;
  padding: 4px 10px;
  &.mrgb{
    margin-bottom: 14px;
    cursor: pointer;
  }
  .areaName{
    font-size: 16px;
    background: #fff;
    line-height: 35px;
    padding-left: 20px;
    color: #203251;
    font-weight: bold;
  }
  .value{
    font-size: 14px;
    color:#203251;
    margin-top: 5px;
    span{
      font-weight: bold;
    }
  }
}
</style>
  1. 效果如下图所示:
    在这里插入图片描述

三、如何自定义底图样式

  1. 点进高德控制台找到首页 --> 特色产品平台使用概况–>我的自定义地图 --> 管理自定义地图 进去使用某一模板创建
    在这里插入图片描述
  2. 模板创建成功,点击分享
    在这里插入图片描述
  3. 修改mapStyle即可更换底图样式
    在这里插入图片描述
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值