如何在Vue中使用高德地图并渲染呼吸灯和飞线

一、注册并登录高德地图开放平台,申请密钥

高德开放平台 | 高德地图API高德开放平台|高德开放平台官网|高德开放平台控制台|官网控制台|控制台|应用管理|应用分析|账号信息|开发者信息|账号权限|KEY管理icon-default.png?t=N7T8https://lbs.amap.com/

 <script src="//webapi.amap.com/maps?v=1.4.15&key=自己申请的密钥&plugin=自己所需要的插件"></script>

二、引入高德地图加载器

npm i @amap/amap-jsapi-loader --save

三、封装一个自定义地图子组件并初始化地图

<template>
  <div
    ref="map"
    class="map-comp"
    id="container"
    style="width: 1710px;height: 845px;"
  ></div>
</template>

<script>
import "echarts-extension-amap";
import * as echarts from "echarts";
export default {
  name: "MapComp",
  data() {
    return {
      map: null,
      chart: null,
    };
  },

  mounted() {
    this.initMap();
  },

  methods: {
    createOption() {
      return {
        amap: {
          resizeEnable: true,
          mapStyle: "amap://styles/darkblue",  //地图颜色样式
          viewMode: "3D", //是否启用3d地图
          pitch: 30, //视角高度
          skyColor: "#021929", //天空颜色
          center: [108.94, 34.34] // 中心点坐标
        },      
      };
    },

    initMap() {
      const option = this.createOption();
      const chart = (this.chart = echarts.init(
        document.getElementById("container")
      ));
      chart.setOption(option);
    }
  }
};
</script>

<style lang="scss" scoped>
.map-comp {
  width: 100%;
  height: 100%;
}
</style>

 初始化地图的图片  注意上面提到引入自己的key和所需要用到的插件,我们这里用到的高德地图插件(plugin=AMap.CustomLayer&plugin=AMap.DistrictSearch),放入script标签src里面即可。

 四、封装定义一个父组件,并将子组件导入

<template>
    <map-comp
      :points="points"
      :to-scatters="toScatters"
    />
</template>

<script>
import MapComp from "./indexSon.vue";

export default {
  name: "App",
  components: {
    MapComp
  },

  data() {
    return {
      // 飞线的数据格式
      points: [
        {
          from: [114.298572, 30.584355],
          to: [113.665412, 34.757975]
        },
        {
          from: [114.298572, 30.584355],
          to: [114.298572, 30.584355]
        },
        {
          from: [114.298572, 30.584355],
          to: [116.405285, 39.904989]
        }
      ],
      // 点的数据格式
      toScatters: [
        [113.665412, 34.757975, "郑州市"],
        [114.298572, 30.584355, "武汉市"],
        [116.405285, 39.904989, "北京市"]
      ]
    };
  },
};
</script>

五、子组件使用props接收父组件传过来的数据,并渲染呼吸灯和飞线

export default { 

 props: {

    points: {
      type: Array,
      default: () => []
    },

    toScatters: {
      type: Array,
      default: () => []
    },
  },

 methods:{
    createOption() {
      return {
        animation: true,
        series: [
          //呼吸灯
          {
            name: "scatter",
            type: "effectScatter",
            zlevel: 2,
            // 使用高德地图坐标系
            coordinateSystem: "amap",
            data: this.toScatters, //数据格式[y,x,name]
            symbolSize: 20, // 设置点的大小
            encode: {
              //维度
              value: 2
            },
            label: {
              normal: {
                formatter: "{@[2]}", //title提示的文字@后为索引
                position: "right", //显示位置
                show: true
              },
              emphasis: {
                //重点显示
                show: true
              }
            },
            itemStyle: {
              normal: {
                color: "#00c1de" //颜色
              }
            },
            hoverAnimation: true,
            tooltip: {
              trigger: "item",
              formatter: "123"
            }
          },
          //飞线
          {
            type: "lines",
            zlevel: 1,
            coordinateSystem: "amap",
            animation: false,
            effect: {
              show: true,
              period: 2,
              symbol: "pin",
              symbolSize: 8,
              trailLength: 0.5
            },
            label: {
              normal: {
                show: false
              }
            },
            lineStyle: {
              normal: {
                width: 2, //尾迹线条宽度
                opacity: 0, //尾迹线条透明度
                curveness: 0.2 //尾迹线条曲直度
              }
            },
            //数据格式
            data: this.points.map(item => {
              return {
                coords: [item.from, item.to]
              };
            })
          }
        ]
      };
    },
  }
}

六、在每个呼吸灯设置打开弹窗显示一些数据


<script>
export default {
  data() {
    return {
      district: new window.AMap.DistrictSearch({
        extensions: "all",
        subdistrict: false
      }),
      polygons: null
    };
  },

  mounted() {
    this.initMap();
  },

  methods: {
    initMap() {
      this.map = chart
        .getModel()
        .getComponent("amap")
        .getAMap();

      // 选中一个再点击另一个让其他的弹出窗关闭
      this.map.on("click", () => {
        if (this.infoWindow) this.infoWindow.close();
        if (this.polygons) {
          this.map.remove(this.polygons);
          this.polygons = null;
        }
      });

      // 设置点击事件将数据传给createInfoWindow方法
      chart.on("click", e => {
        if (e.componentSubType === "effectScatter" && e.data[3]) {
          if (this.infoWindow) this.infoWindow.close();
          this.infoWindow = this.createInfoWindow(e.data[3]);
          this.infoWindow.open(this.map, e.data);
        }
      });
    },

    // 设置窗体信息和样式
    createInfoWindow(info) {
      return new window.AMap.InfoWindow({
        anchor: "top-center",
        isCustom: true,
        offset: new window.AMap.Pixel(0, 15),
        content: `<div class="custom-info-window top-center">
                      <div>当前位置信息</div>
                      <div>提交时间:${info.time}</div>
                      <div>队伍名称:${info.name}</div>
                      <div>漏洞单位名称:${info.bugCompanyName}</div>
                      <div>漏洞类型:${info.bugType}</div>
                      <div>安全评级:${info.bugLevel}</div>
                      <div class="amap-info-sharp"></div>
                  </div>`
      });
    }

 
  }
};
</script>

<style lang="scss" scoped>
.map-comp {
  width: 100%;
  height: 100%;
}
</style>

<style>
.custom-info-window {
  color: #fff;
  background: rgba(25, 93, 202, 0.5);
  font-size: 12px;
  border: 1px solid rgba(25, 93, 202, 0.5);
}
.custom-info-window div:not(.amap-info-sharp) {
  padding: 2px 10px;
}
.custom-info-window div:first-of-type {
  border-bottom: 1px solid rgba(25, 93, 202, 0.5);
  text-align: center;
}
.top-center .amap-info-sharp {
  border-bottom-color: rgba(25, 93, 202, 0.5);
}
</style>

七、子组件的完整代码

<template>
  <div
    ref="map"
    class="map-comp"
    id="container"
    style="width: 1710px;height: 845px;"
  ></div>
</template>

<script>
import "echarts-extension-amap";
import * as echarts from "echarts";
export default {
  name: "MapComp",
  props: {
    points: {
      type: Array,
      default: () => []
    },
    toScatters: {
      type: Array,
      default: () => []
    },
  },

  data() {
    return {
      map: null,
      chart: null,
      district: new window.AMap.DistrictSearch({
        extensions: "all",
        subdistrict: false
      }),
      polygons: null
    };
  },

  mounted() {
    this.initMap();
  },

  methods: {
    createOption() {
      return {
        amap: {
          resizeEnable: true,
          mapStyle: "amap://styles/darkblue",
          viewMode: "3D", //是否启用3d地图
          pitch: 30, //视角高度
          skyColor: "#021929",
          showLabel: false, // 是否显示城市的名称
          center: [108.94, 34.34] // 中心点坐标
        },
        animation: true,
        series: [
          //呼吸灯
          {
            name: "scatter",
            type: "effectScatter",
            zlevel: 2,
            // 使用高德地图坐标系
            coordinateSystem: "amap",
            data: this.toScatters, //数据格式[y,x,name]
            symbolSize: 20, // 设置呼吸灯的大小
            encode: {
              //维度
              value: 2
            },
            label: {
              normal: {
                formatter: "{@[2]}", //title提示的文字@后为索引
                position: "right", //显示位置
                show: true
              },
              emphasis: {
                //重点显示
                show: true
              }
            },
            itemStyle: {
              normal: {
                color: "#00c1de" //颜色
              }
            },
            hoverAnimation: true,
            tooltip: {
              trigger: "item",
              formatter: "123"
            }
          },
          //飞线
          {
            type: "lines",
            zlevel: 1,
            coordinateSystem: "amap",
            animation: false,
            effect: {
              show: true,
              // constantSpeed: 60,
              period: 2,
              symbol: "pin",
              symbolSize: 8,
              trailLength: 0.5
            },
            label: {
              normal: {
                show: false
              }
            },
            lineStyle: {
              normal: {
                width: 2, //尾迹线条宽度
                opacity: 0, //尾迹线条透明度
                curveness: 0.2 //尾迹线条曲直度
              }
            },
            //数据格式
            data: this.points.map(item => {
              return {
                coords: [item.from, item.to]
              };
            })
          }
        ]
      };
    },
    initMap() {
      const option = this.createOption();
      const chart = (this.chart = echarts.init(
        document.getElementById("container")
      ));
      chart.setOption(option);

      // get amap instance
      this.map = chart
        .getModel()
        .getComponent("amap")
        .getAMap();

      this.map.on("click", () => {
        if (this.infoWindow) this.infoWindow.close();
        if (this.polygons) {
          this.map.remove(this.polygons);
          this.polygons = null;
        }
      });

      chart.on("click", e => {
        if (e.componentSubType === "effectScatter" && e.data[3]) {
          if (this.infoWindow) this.infoWindow.close();
          this.infoWindow = this.createInfoWindow(e.data[3]);
          this.infoWindow.open(this.map, e.data);
        }
      });
    },
    createInfoWindow(info) {
      return new window.AMap.InfoWindow({
        anchor: "top-center",
        isCustom: true,
        offset: new window.AMap.Pixel(0, 15),
        content: `<div class="custom-info-window top-center">
                      <div>烽火</div>
                      <div>提交时间:${info.time}</div>
                      <div>名称:${info.name}</div>
                      <div class="amap-info-sharp"></div>
                  </div>`
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.map-comp {
  width: 100%;
  height: 100%;
}
</style>

<style>
.custom-info-window {
  color: #fff;
  background: rgba(25, 93, 202, 0.5);
  font-size: 12px;
  border: 1px solid rgba(25, 93, 202, 0.5);
}
.custom-info-window div:not(.amap-info-sharp) {
  padding: 2px 10px;
}
.custom-info-window div:first-of-type {
  border-bottom: 1px solid rgba(25, 93, 202, 0.5);
  text-align: center;
}
.top-center .amap-info-sharp {
  border-bottom-color: rgba(25, 93, 202, 0.5);
}
</style>

八、按照以上步骤操完成之后会得到这样的一个地图,希望能帮到大家

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值