基于Vue2.0和高德地图的地图组件实例

  1. 安装插件
//高德地图插件
npm install vue-amap --save
//高德vue组件库
npm install @vuemap/vue-amap --save

2.官网
申请高德地图账号和key。高德官网入门指南
@vuemap/vue-amap是基于高德JSAPI2.0、Loca2.0封装的vue组件库。组件库网址

  1. main.js中引入
import VueAMap from 'vue-amap';
Vue.use(VueAMap);
// 初始化vue-amap
VueAMap.initAMapApiLoader({
  // 高德的key
  key: '',
  // 插件集合 (插件按需引入)
  plugin: ['AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView', 'AMap.ToolBar', 'AMap.MapType',
    'AMap.PolyEditor', 'AMap.Circle', 'AMap.CircleEditor', 'AMap.DistrictSearch','AMap.CircleMarker','AMap.Polyline','AMap.RangingTool'
    ,'AMap.CitySearch','AMap.MoveAnimation','AMap.RectangleEditor','AMap.Rectangle','AMap.LngLat','AMap.Bounds','AMap.Map',
    'AMap.Polygon'
    // 'AMap.Object3DLayer', 'AMap.Object3D'
  ],
  viewMode:'3D',//开启3D视图,默认为关闭
});
//高德的安全密钥
window._AMapSecurityConfig = {
  securityJsCode: '',
}
  1. 地图选点
<template>
  <div>
    <div style="height: 500px;">
      <el-amap
        ref="map"
        vid="amapDemo"
        :amap-manager="amapManager"
        :center="center"
        :zoom="zoom"
        viewMode="3D"
        :plugin="plugin"
        :events="events"
        class="amap-demo"
      >
        <el-amap-marker :position="marker.position">
          <div 
            style="color: #eee;width: 20px;height: 20px;text-align: center;position: relative">
            <i class="iconfont icon-xiaoshuidifuzhi"
              style="color:#009cf9;font-size: 30px;"
            ></i>
          </div>
        </el-amap-marker>
      </el-amap>
    </div>
    <div>
      坐标:{{ address }}
    </div>
  </div>
</template>

<script>
  import { AMapManager } from "vue-amap";
  let amapManager = new AMapManager();
  export default {
    components: {},
    props: {},
    data: function (){
      const self = this;
      return {
        amapManager,
        plugin: [
          "ToolBar",
          {
            pName: "MapType",
            defaultType: 0,
            events: {
              init(o) {},
            },
          },
        ],
        address:null,
        center: [121.59996, 31.197646],
        zoom: 12,
        events: {
          init: (o) => {
            o.setDefaultCursor("crosshair");
          },
          moveend: () => {},
          zoomchange: () => {},
          click: (e) => {
            self.address =  e.lnglat.lng  + "," +  e.lnglat.lat
            // 将设定的航点展示在地图上
            self.marker = {
              position: [e.lnglat.lng, e.lnglat.lat],
            }
          },
        },
        marker: {
          position: [121.5273285, 31.21515044],
        },
      };
    },
    watch: {},
    computed: {},
    created() {},
    mounted() {},
    methods: {},
  };
</script>
<style lang="scss" scoped>
</style>

在这里插入图片描述
5. 电子围栏

<template>
  <div>
    <div style="height: 500px;">
      <el-amap
        ref="map"
        vid="amapDemo"
        :amap-manager="amapManager"
        :center="center"
        :zoom="zoom"
        viewMode="3D"
        :plugin="plugin"
        :events="events"
        class="amap-demo"
      >
        <el-amap-circle 
          v-if="circles.visible"
          :center="circles.circleCenter"
          :radius="circles.radius"
          :editable="circles.edit"
          :draggable="circles.draggable"
          :fillColor="circles.fillColor"
          :strokeColor="circles.strokeColor"
        ></el-amap-circle>
        <el-amap-rectangle 
          v-if="rectangles.visible"
          :bounds="rectangles.path"
          :editable="rectangles.edit"
          :draggable="rectangles.draggable"
          :fillColor="rectangles.fillColor"
          :strokeColor="rectangles.strokeColor"
        ></el-amap-rectangle>
        <el-amap-polygon
          v-if="polygons.visible"
          :path="polygons.path"
          :editable="polygons.edit"
          :draggable="polygons.draggable"
          :fillColor="polygons.fillColor"
          :strokeColor="polygons.strokeColor"
        />
      </el-amap>
    </div>
    <div>
      <el-button @click="draw('circle')">绘制圆形</el-button>
      <el-button @click="draw('rectangle')">绘制矩形</el-button>
      <el-button @click="draw('polygon')">绘制多边形</el-button>
    </div>
  </div>
</template>

<script>
  import { AMapManager } from "vue-amap";
  let amapManager = new AMapManager();
  export default {
    components: {},
    props: {},
    data: function (){
      const self = this;
      return {
        amapManager,
        type:null,
        plugin: [
          "ToolBar",
          {
            pName: "MapType",
            defaultType: 0,
            events: {
              init(o) {},
            },
          },
        ],
        center: [121.59996, 31.197646],
        zoom: 12,
        clicksNum:0,//点击次数
        circles:{
          center: [121.5273285, 31.21515044],
          draggable: false,
          visible: true,
          edit: false,
          circleCenter: [0, 0],
          radius: 0,
          strokeColor:'#F56C6C',
          fillColor:'#F56C6C'
        },
        rectangles:{
          firstPoint:[],
          visible: true,
          path:[[0, 0], [0, 0]],
          edit: false,
          draggable: false,
          fillColor:'#F56C6C',
          strokeColor:'#F56C6C',
        },
        polygons:{
          visible: true,
          path:[],
          edit: false,
          draggable: false,
          fillColor:'#F56C6C',
          strokeColor:'#F56C6C',
        },
        events: {
          init: (o) => {
            o.setDefaultCursor("crosshair");
          },
          moveend: () => {},
          zoomchange: () => {},
          click: (e) => {
            if(self.type == 'circle'){
              self.clicksNum = self.clicksNum + 1//点击次数
              if(self.clicksNum%2===0){
                self.circles = {
                  ...self.circles,
                  radius: self.getDistanceBmarker(self.circles.circleCenter,[e.lnglat.lng, e.lnglat.lat]),
                }
              }else{
                self.circles.radius = 0
                self.circles.circleCenter = [e.lnglat.lng, e.lnglat.lat]
              }
            }else if(self.type == 'rectangle'){
              self.clicksNum = self.clicksNum + 1//点击次数
              if(self.clicksNum%2===0){
                self.rectangles = {
                  ...self.rectangles,
                  path: [self.firstPoint, [e.lnglat.lng, e.lnglat.lat]]
                }
              }else{
                self.firstPoint = [e.lnglat.lng, e.lnglat.lat]
              }
            }else if(self.type == 'polygon'){
              self.polygons.path.push(
                [e.lnglat.lng, e.lnglat.lat]
              )
            }
          },
        },
      };
    },
    watch: {},
    computed: {},
    created() {},
    mounted() {},
    methods: {
      draw(type){
        this.clicksNum = 0,//点击次数
        this.type = type
      },
      //算出两个点坐标间的直线距离
      getDistanceBmarker(m1, m2) {
        // AMap.LngLat
        let p1 = new window.AMap.LngLat(m1[0], m1[1]);
        var distance = Math.round(p1.distance(m2));

        return distance;
      },
    },
  };
</script>
<style lang="scss" scoped>
</style>

在这里插入图片描述

  1. 3D地图(鼠标右键可拖拽调整方向)
<template>
  <div>
    <div style="height: 500px;">
      <el-amap
        ref="map"
        vid="amapDemo"
        :amap-manager="amapManager"
        :center="center"
        :zoom="zoom"
        <!-- 3D  -->
        :pitchEnable="true"
        :rotateEnable="true"
        :pitch="50" 地图俯仰角度,有效范围 0 度- 83 度
        viewMode="3D"
        <!-- 3D -->
        :plugin="plugin"
        :events="events"
        class="amap-demo"
      >
        <el-amap-marker :position="marker.position">
          <div 
            style="color: #eee;width: 20px;height: 20px;text-align: center;position: relative">
            <i class="iconfont icon-xiaoshuidifuzhi"
              style="color:#009cf9;font-size: 30px;"
            ></i>
          </div>
        </el-amap-marker>
      </el-amap>
    </div>
    <div>
      坐标:{{ address }}
    </div>
  </div>
</template>

<script>
  import { AMapManager } from "vue-amap";
  let amapManager = new AMapManager();
  export default {
    components: {},
    props: {},
    data: function (){
      const self = this;
      return {
        amapManager,
        plugin: [
          "ToolBar",
          {
            pName: "MapType",
            defaultType: 0,
            events: {
              init(o) {},
            },
          },
        ],
        address:null,
        center: [121.59996, 31.197646],
        zoom: 12,
        events: {
          init: (o) => {
            o.setDefaultCursor("crosshair");
          },
          moveend: () => {},
          zoomchange: () => {},
          click: (e) => {
            self.address =  e.lnglat.lng  + "," +  e.lnglat.lat
            // 将设定的航点展示在地图上
            self.marker = {
              position: [e.lnglat.lng, e.lnglat.lat],
            }
          },
        },
        marker: {
          position: [121.5273285, 31.21515044],
        },
      };
    },
    watch: {},
    computed: {},
    created() {},
    mounted() {},
    methods: {},
  };
</script>
<style lang="scss" scoped>
</style>

在这里插入图片描述
7. 折线(判断折现是否交叉)

<template>
  <div>
    <div style="height: 500px">
      <el-amap
        ref="map"
        vid="amapDemo"
        :amap-manager="amapManager"
        :center="center"
        :zoom="zoom"
        viewMode="3D"
        :plugin="plugin"
        :events="events"
        class="amap-demo"
      >
        <div v-for="(item, index) in tableData" :key="index">
          <el-amap-marker :position="[item.lng, item.lat]">
            <div
              style="
                color: #eee;
                width: 20px;
                height: 20px;
                text-align: center;
                position: relative;
              "
            >
              <i
                class="iconfont icon-xiaoshuidifuzhi"
                style="color: #009cf9; font-size: 30px"
              ></i>
              <span style="color: #fff; position: absolute; top: 10px; left: 10px">{{
                index + 1
              }}</span>
            </div>
          </el-amap-marker>
          <el-amap-polyline
            :editable="polyline.editable"
            :visible="polyline.visible"
            :draggable="polyline.draggable"
            :path="polyline.path"
            :strokeColor="polyline.strokeColor"
          ></el-amap-polyline>
        </div>
        <div v-for="(item, index) in tableData1" :key="index">
          <el-amap-marker :position="[item.lng, item.lat]">
            <div
              style="
                color: #eee;
                width: 20px;
                height: 20px;
                text-align: center;
                position: relative;
              "
            >
              <i
                class="iconfont icon-xiaoshuidifuzhi"
                style="color: #3657ff; font-size: 30px"
              ></i>
              <span style="color: #fff; position: absolute; top: 10px; left: 10px">{{
                index + 1
              }}</span>
            </div>
          </el-amap-marker>
          <el-amap-polyline
            :editable="polyline1.editable"
            :visible="polyline1.visible"
            :draggable="polyline1.draggable"
            :path="polyline1.path"
            :strokeColor="polyline1.strokeColor"
          ></el-amap-polyline>
        </div>
      </el-amap>
    </div>
    <el-button style="margin: 10px 0" type="primary" size="mini" @click="compare()"
      >比较</el-button
    >
    <span style="color: red">{{ result }}</span>
    <div style="display: flex">
      <div>
        <el-button type="primary" size="mini" @click="getlnglat('left')">取点</el-button>
        <el-table :data="tableData" style="width: 500px">
          <el-table-column type="index" label="序号" width="180"> </el-table-column>
          <el-table-column prop="lng" label="经度" width="180"> </el-table-column>
          <el-table-column prop="lat" label="纬度"> </el-table-column>
        </el-table>
      </div>
      <div>
        <el-button type="primary" size="mini" @click="getlnglat('right')">取点</el-button>
        <el-table :data="tableData1" style="width: 500px; margin-left: 10px">
          <el-table-column type="index" label="序号" width="180"> </el-table-column>
          <el-table-column prop="lng" label="经度" width="180"> </el-table-column>
          <el-table-column prop="lat" label="纬度"> </el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>

<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
  components: {},
  props: {},
  data: function () {
    const self = this;
    return {
      amapManager,
      plugin: [
        "ToolBar",
        {
          pName: "MapType",
          defaultType: 0,
          events: {
            init(o) {},
          },
        },
      ],
      center: [121.59996, 31.197646],
      zoom: 12,
      events: {
        init: (o) => {
          o.setDefaultCursor("crosshair");
        },
        moveend: () => {},
        zoomchange: () => {},
        click: (e) => {
          if (self.flag) {
            self.tableData.push({
              lng: e.lnglat.lng,
              lat: e.lnglat.lat,
            });
            self.polyline.path.push([e.lnglat.lng, e.lnglat.lat]);
          } else {
            self.tableData1.push({
              lng: e.lnglat.lng,
              lat: e.lnglat.lat,
            });
            self.polyline1.path.push([e.lnglat.lng, e.lnglat.lat]);
          }
        },
      },
      polyline: {
        path: [],
        editable: false, //折线当前是否可编辑
        visible: true, //是否可见
        draggable: false, //是否可拖拽移动
        strokeColor: "#009cf9",
      },
      polyline1: {
        path: [],
        editable: false, //折线当前是否可编辑
        visible: true, //是否可见
        draggable: false, //是否可拖拽移动
        strokeColor: "#3657FF",
      },
      tableData: [],
      tableData1: [],
      flag: false,
      result: "",
    };
  },
  watch: {},
  computed: {},
  created() {},
  mounted() {},
  methods: {
    getlnglat(type) {
      if (type == "left") {
        this.flag = true;
      } else {
        this.flag = false;
      }
    },
    compare() {
      if (this.isLineCross(this.tableData, this.tableData1)) {
         return this.result = "航线交叉";
      }
      return this.result = "航线未交叉";
    },
    // 判断折现是否交叉
    isLineCross(line1, line2) {
      // 获取两条折线的所有点
      const points1 = line1;
      const points2 = line2;
      // 遍历第一条折线的每个点
      for (let i = 0; i < points1.length - 1; i++) {
        // 判断每个点与第二条折线上的点的组合情况
        for (let j = 0; j < points2.length - 1; j++) {
          // 如果存在线段相交,则返回true
          if (
            this.isSegmentCross(points1[i], points1[i + 1], points2[j], points2[j + 1])
          ) {
            return true;
          }
        }
      }
      return false;
    },
    isSegmentCross(p0, p1, p2, p3) {
      const s1 = {
        x: p1.lng - p0.lng,
        y: p1.lat - p0.lat,
      };
      const s2 = {
        x: p3.lng - p2.lng,
        y: p3.lat - p2.lat,
      };

      const s =
        (-s1.y * (p0.lng - p2.lng) + s1.x * (p0.lat - p2.lat)) /
        (-s2.x * s1.y + s1.x * s2.y);
      const t =
        (s2.x * (p0.lat - p2.lat) - s2.y * (p0.lng - p2.lng)) /
        (-s2.x * s1.y + s1.x * s2.y);
      return s >= 0 && s <= 1 && t >= 0 && t <= 1;
    },
  },
};
</script>
<style lang="scss" scoped></style>

在这里插入图片描述
8. 两点测距、两点连线角度

<template>
  <div>
    <div style="height: 500px">
      <el-amap
        ref="map"
        vid="amapDemo"
        :amap-manager="amapManager"
        :center="center"
        :zoom="zoom"
        viewMode="3D"
        :plugin="plugin"
        :events="events"
        class="amap-demo"
      >
        <div v-for="(item, index) in rulerMakers" :key="index">
          <el-amap-marker :position="item.lnglat">
            <div
              style="
                color: #eee;
                width: 20px;
                height: 20px;
                text-align: center;
                position: relative;
              "
            >
              <i
                class="iconfont icon-xiaoshuidifuzhi"
                style="color: #009cf9; font-size: 30px"
              ></i>
            </div>
          </el-amap-marker>
        </div>
      </el-amap>
    </div>
    <div style="background-color: #eee">
      两点距离:{{ ruleFormInfo.distance }} 两点连线角度:{{ ruleFormInfo.angle }}
    </div>
  </div>
</template>

<script>
import { AMapManager } from "vue-amap";
let amapManager = new AMapManager();
export default {
  components: {},
  props: {},
  data: function () {
    const self = this;
    return {
      amapManager,
      plugin: [
        "ToolBar",
        {
          pName: "MapType",
          defaultType: 0,
          events: {
            init(o) {},
          },
        },
      ],
      address: null,
      center: [121.59996, 31.197646],
      zoom: 12,
      events: {
        init: (o) => {
          o.setDefaultCursor("crosshair");
        },
        moveend: () => {},
        zoomchange: () => {},
        click: (e) => {
          self.clickRuleMaker([e.lnglat.lng, e.lnglat.lat]);
        },
      },
      rulerMakers: [],
      ruleFormInfo: {
        start: [],
        ende: [],
        distance: null,
        angle: null,
      },
    };
  },
  watch: {
    rulerMakers: {
      handler(newValue) {
        console.log(newValue);
        if (newValue.length == 2) {
          let start = this.rulerMakers[0].lnglat,
            end = this.rulerMakers[1].lnglat;
          this.ruleFormInfo.distance = this.getDistanceBmarker(start, end) + "m";
          this.ruleFormInfo.angle = this.bearing(start, end) + "°";
        }
      },
    },
  },
  computed: {},
  created() {},
  mounted() {},
  methods: {
    /**
     * @method 点击地图出现点坐标
     * @param
     */
    clickRuleMaker(lnglat) {
      if (this.rulerMakers.length < 2) {
        this.rulerMakers.push({
          type: 1,
          lnglat: lnglat,
          title: this.rulerMakers.length == 0 ? "" : "",
        });
        this.ruleFormInfo.start = this.rulerMakers[0].lnglat.join(",");
        if (this.rulerMakers[1])
          this.ruleFormInfo.end = this.rulerMakers[1].lnglat.join(",");
      } else if (this.rulerMakers.length === 2) {
        //如果点击地图时测距的点坐标已有两个就删除这两个重新开始测距
        this.rulerMakers = [];
        this.clickRuleMaker(lnglat);
      }
    },
    /**
     * @method 算出两个点坐标间的直线距离
     * @param
     */
    getDistanceBmarker(m1, m2) {
      // AMap.LngLat
      let p1 = new window.AMap.LngLat(m1[0], m1[1]);
      var distance = Math.round(p1.distance(m2));

      return distance;
    },
    /**
     * @method 计算两个经纬度点连线后与正北线的角度
     * @param
     */
    bearing(start, end) {
      let rad = Math.PI / 180,
        lat1 = start[1] * rad,
        lat2 = end[1] * rad,
        lon1 = start[0] * rad,
        lon2 = end[0] * rad;
      const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
      const b =
        Math.cos(lat1) * Math.sin(lat2) -
        Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
      return this.radiansToDegrees(Math.atan2(a, b)).toFixed(2);
    },

    /*
     * 弧度转换为角度
     */
    radiansToDegrees(radians) {
      const degrees = radians % (2 * Math.PI);
      return (degrees * 180) / Math.PI;
    },
  },
};
</script>
<style lang="scss" scoped></style>

在这里插入图片描述
9. 在高德地图API中,要判断一个点是否在矩形(多边形)内,可以使用contains方法。首先,你需要创建一个矩形(多边形)对象,然后使用该对象(多边形)的contains方法来判断点是否在矩形内。

// 创建高德地图实例(矩形)
var map = new AMap.Map('container', {
    zoom: 11,
    center: [116.397428, 39.90923]
});
 
// 创建矩形对象
var bounds = new AMap.Bounds(
    // 左下角坐标
    [116.365145, 39.906018], 
    // 右上角坐标
    [116.418654, 39.940732]
);
 
// 创建一个点坐标
var point = new AMap.LngLat(116.401476, 39.920765);
 
// 使用contains方法判断点是否在矩形内
if (bounds.contains(point)) {
    console.log('点在矩形内');
} else {
    console.log('点不在矩形内');
}
// 创建地理坐标点
var point = new AMap.LngLat(116.397428, 39.90923); // 举例的点
 
// 创建多边形
var polygonPath = [
    new AMap.LngLat(116.368904,39.913423),
    new AMap.LngLat(116.382122,39.901176),
    new AMap.LngLat(116.387271,39.912501),
    new AMap.LngLat(116.398258,39.904600)
];
var polygon = new AMap.Polygon({
    path: polygonPath,
    strokeColor: 'red',
    strokeWeight: 3
});
 
// 将多边形添加到地图
map.add(polygon);
 
// 使用contains方法判断点是否在多边形内
if (polygon.contains(point)) {
    console.log('点在多边形内');
} else {
    console.log('点在多边形外');
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据引用\[1\]和引用\[2\]的内容,如果你在Vue3项目中需要使用地图定位组件,目前百度地图高德地图并没有针对Vue3封装好的组件。不过,你可以使用vue-baidu-map和vue-Amap这两个针对Vue2封装好的组件。你可以参考它们的官方文档来学习如何使用它们的功能。如果需要实现特定的功能,你可以在百度地图高德地图的官方API平台上进行学习和查找相关信息。 另外,根据引用\[3\]的内容,如果你想在Vue3项目中使用高德地图,你可以在HTML文件中引入相关的JavaScript文件,并根据你自己的密钥进行配置。你还可以根据需要引入其他插件和样式文件。需要注意的是,某些样式文件可能会影响其他组件的样式,所以你可以在对应的组件中使用scoped来限定样式的作用范围。 综上所述,如果你在Vue3项目中需要地图定位组件,你可以选择使用vue-baidu-map和vue-Amap这两个Vue2封装好的组件,或者根据引用\[3\]的内容自行配置和使用高德地图组件。 #### 引用[.reference_title] - *1* *3* [vue3项目中使用百度地图高德地图,添加控件,搜索api, 热力图](https://blog.csdn.net/weixin_59832677/article/details/126657850)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [vue制作腾讯地图组件](https://blog.csdn.net/wyljz/article/details/123552636)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值