高德地图(前端入门学习)

参考文档

官方教程

基础知识

lng:经度
lat:纬度

在百度地图中,习惯经度在前,纬度在后

地球上同一个地理位置的经纬度,在不同的坐标系中,会有少于偏移,国内目前常见的坐标系主要分为三种:

地球坐标系——WGS84:常见于 GPS 设备,Google 地图等国际标准的坐标体系。
火星坐标系——GCJ-02:中国国内使用的被强制加密后的坐标体系,高德坐标就属于该种坐标体系。
百度坐标系——BD-09:百度地图所使用的坐标体系,是在火星坐标系的基础上又进行了一次加密处理。

准备

1、注册开发者账号
2、创建新应用
3、为应用添加 Key,「服务平台」一项请选择「 Web 端 ( JSAPI ) 」

vue项目使用(方案一:引用原生api)(全局注册)(不推荐)

首先,申请 Key
其次,引入地图 js,在public/index.html里面添加下面代码

<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script> 

然后,创建vue.config.js文件,写入

module.exports = {
  configureWebpack: {
    externals: {
      'AMap': 'AMap',
      'AMapUI': 'AMapUI'
    }
  }
};

最后,组件引入,mounted时初始化地图(注意要设置容器的宽高)

<template>
  <div class="wrap">
    <!-- 1、创建地图容器 -->
    <div id="container"
         style="width:100%;height:600px"></div>
  </div>
</template>

<script>
// 2、引用地图类
import AMap from "AMap"
// import AMapUI from 'AMapUI'
export default {
  data () {
    return {
      map: null,
    }
  },
  // 3、mounted时初始化地图
  mounted () {
    this.init();
  },
  methods: {
    init () {
      this.map = new AMap.Map("container", {
        zoom: 11, //级别
        resizeEnable: true
      });
    },
  }
};
</script>

vue项目使用(方案二:引用原生api)(单页面按需加载)

1、创建utils/AMap.js文件,写入初始化函数loadAMap,用于动态加载地图api。

/* eslint-disable */
export default function loadAMap(ak) {
  return new Promise(function(resolve, reject) {
    if (typeof AMap !== 'undefined') {
      resolve(AMap)
      return true
    }
    window.onAMapCallback = function() {
      resolve(AMap)
    }
//     let script = document.createElement('script')
//     script.type = 'text/javascript'
//     script.src = 'https://webapi.amap.com/maps?v=2.0&key=' + ak + '&callback=onAMapCallback'
//     script.onerror = reject
//     document.head.appendChild(script)
    let AMapURL = 'https://webapi.amap.com/maps?v=2.0&key=' + ak + '&callback=onAMapCallback'
    let scriptNode = document.createElement('script')
    scriptNode.setAttribute('type', 'text/javascript')
    scriptNode.setAttribute('src', AMapURL)
    scriptNode.onerror = reject
    document.body.appendChild(scriptNode)
  })
}

2、页面使用

a、创建地图容器Div
b、引用import loadAMap from "@/utils/AMap.js"
c、在mounted使用loadAMap函数创建地图实例

<template>
  <div class="home">
    <h1>高德地图</h1>
    <div id="container"
         style="width:100%;height:500px"></div>
  </div>
</template>

<script>
import loadAMap from "@/utils/AMap.js"
export default {
  data () {
    return {
      map: {},
    }
  },
  mounted () {
    let that = this
    this.$nextTick(() => {
      loadAMap("您申请的key值")
        .then((AMap) => {
          // 创建地图实例
          var map = new AMap.Map('container', {
            zoom: 11,//级别
            center: [116.397428, 39.90923],//中心点坐标
            viewMode: '3D'//使用3D视图
          });
          that.map = map
          //异步加载控件
          AMap.plugin('AMap.ToolBar', function () {
            var toolbar = new AMap.ToolBar();
            that.map.addControl(toolbar);
          });
        })
        .catch((err) => {
          console.log("地图加载失败", err);
        });
    })
  }
}
</script>

vue项目使用(方案三:引用原生api)(按 NPM 方式使用 Loader)(推荐)

JSAPI 脚本加载详解

安装:

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

使用:

import AMapLoader from '@amap/amap-jsapi-loader';

let that = this
AMapLoader.load({
    "key": "您申请的key值",              // 申请好的Web端开发者Key,首次调用 load 时必填
    "version": "1.4.15",   // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    "plugins": [],           // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    "AMapUI": {             // 是否加载 AMapUI,缺省不加载
        "version": '1.1',   // AMapUI 缺省 1.1
        "plugins":[],       // 需要加载的 AMapUI ui插件
    },
    "Loca":{                // 是否加载 Loca, 缺省不加载
        "version": '1.3.2'  // Loca 版本,缺省 1.3.2
    },
}).then((AMap)=>{
    that.map = new AMap.Map('container');
}).catch(e => {
    console.log(e);
})

vue项目使用(方案四:vue-amap组件)

官方文档
npm地址

参考案例

点线面地图选点组件封装案例(vue引用原生api)

<template>
  <a-modal title="坐标拾取"
           :width="1000"
           :visible="visible"
           :maskClosable="false"
           @ok="handleConfirm"
           @cancel="handleCancel"
           :bodyStyle="{padding:'12px'}">
    <div style="position: relative;">
      <a-select size="small"
                placeholder="请选择地点类型"
                v-model="locationType"
                @change="changeType"
                style="position: absolute;top: 0;right: 0;z-index:2;width:160px;">
        <a-select-option :value="0"></a-select-option>
        <a-select-option :value="1">线</a-select-option>
        <a-select-option :value="2"></a-select-option>
      </a-select>
      <div id="pickUpMap"
           style="height:500px"></div>
    </div>
  </a-modal>
</template>
<script>

import AMap from 'AMap'
// import AMapUI from 'AMapUI'
import { IconFont } from '@/core/my_icon'
export default {
  components: { IconFont },
  data () {
    return {
      submitLoading: false,
      visible: false,
      // 覆盖物集合
      overlays: [],
      coordinate: [],
      locationType: 0,
      oldType: 0,
      map: null,
      mouseTool: null,
      oldMarker: null,
      oldPolyline: null,
      oldPolygon: null
    }
  },
  computed: {
    show: {
      get: function () {
        return this.visible
      },
      set: function () { }
    }
  },
  watch: {
    visible (newVal, oldVal) {
      // if (newVal) {
      //   setTimeout(() => {
      //     this.init()
      //   }, 400)
      // }
    }
  },
  methods: {
    showMap (coordinate, locationType) {
      this.visible = true
      this.locationType = locationType || 0
      this.oldType = locationType || 0
      this.coordinate = coordinate ? coordinate.split(',') : []
      setTimeout(() => {
        this.init()
      }, 100)
    },
    // 地图初始化
    init () {
      const that = this
      that.map = new AMap.Map('pickUpMap', {
        zoom: 11,
        resizeEnable: true
      })
      // 添加工具类
      this.addTool()
      // 如果有覆盖物,触发绘制函数
      if (this.coordinate.length) {
        this.initDraw()
      }
    },
    initDraw () {
      const arr = this.coordinate.map(item => ({
        lng: parseFloat(item.split(' ')[0]),
        lat: parseFloat(item.split(' ')[1])
      }))
      // console.log(this.oldType, arr)
      if (this.oldType == 0) {
        this.oldMarker = new AMap.Marker({
          position: new AMap.LngLat(arr[0].lng, arr[0].lat)
        })
        // console.log('marker', this.oldMarker)
        this.map.add(this.oldMarker)
        this.map.setFitView()
      } else if (this.oldType == 1) {
        var path1 = arr.map(item => {
          return new AMap.LngLat(item.lng, item.lat)
        })
        // console.log('path1', path1)
        this.oldPolyline = new AMap.Polyline({
          path: path1,
          strokeColor: '#80d8ff'
        })
        this.map.add(this.oldPolyline)
        this.map.setFitView()
      } else if (this.oldType == 2) {
        var path2 = arr.map(item => {
          return new AMap.LngLat(item.lng, item.lat)
        })
        // console.log('path2', path2)
        this.oldPolygon = new AMap.Polygon({
          path: path2,
          fillColor: '#00b0ff',
          strokeColor: '#80d8ff'
        })
        this.map.add(this.oldPolygon)
        this.map.setFitView()
      }
    },
    addTool () {
      const that = this
      // 缩放控制条-地图工具条(ToolBar)
      AMap.plugin(['AMap.ToolBar'], () => {
        const toolbar = new AMap.ToolBar()
        that.map.addControl(toolbar)
      })
      // 缩略图-鹰眼(OverView)
      AMap.plugin(['AMap.OverView'], () => {
        const overView = new AMap.OverView({
          visible: true // 初始化显示鹰眼
        })
        that.map.addControl(overView)
        overView.open() // 展开鹰眼
      })
      //  比例尺(Scale)
      AMap.plugin(['AMap.Scale'], () => {
        const scale = new AMap.Scale()
        that.map.addControl(scale)
        scale.show()
      })
      //  添加鼠标工具(MouseTool)
      AMap.plugin(['AMap.MouseTool'], () => {
        const MouseTool = new AMap.MouseTool(that.map)
        that.mouseTool = MouseTool
      })
      // 添加绘制事件
      that.draw(that.locationType)
      // 监听绘图事件,获取覆盖物对象信息
      that.mouseTool.on('draw', function (e) {
        // console.log(e.obj)
        // 先清空再添加覆盖物信息
        that.clearAll()
        that.overlays.push(e.obj)
      })
    },
    clearAll () {
      const that = this
      that.map.remove(that.overlays)
      // 清空当前绘画物
      that.overlays = []
      // 如果是修改,有且仅需要操作一次  清空原来的绘制覆盖物
      if (that.coordinate.length) {
        that.coordinate = []
        if (that.oldType == 0) {
          that.map.remove(that.oldMarker)
        } else if (that.oldType == 1) {
          that.map.remove(that.oldPolyline)
        } else if (that.oldType == 2) {
          that.map.remove(that.oldPolygon)
        }
      }
    },
    changeType (val) {
      this.draw(val)
    },
    // 绘图
    draw (type) {
      switch (type) {
        case 0: {
          this.mouseTool.marker({
            // 同Marker的Option设置
          })
          break
        }
        case 1: {
          this.mouseTool.polyline({
            strokeColor: '#80d8ff'
            // 同Polyline的Option设置
          })
          break
        }
        case 2: {
          this.mouseTool.polygon({
            fillColor: '#00b0ff',
            strokeColor: '#80d8ff'
            // 同Polygon的Option设置
          })
          break
        }
      }
    },
    handleCancel () {
      this.visible = false
      this.overlays = []
      this.coordinate = []
      this.locationType = 0
      this.oldType = 0
      this.map = null
      this.mouseTool = null
      this.oldMarker = null
      this.oldPolyline = null
      this.oldPolygon = null
    },
    handleConfirm () {
      const { overlays, locationType } = this
      const coordinate = this.toPosition(overlays[0])
      this.$emit('confirm', { coordinate, locationType })
      this.handleCancel()
    },
    toPosition (overlay) {
      let str = ''
      if (overlay['CLASS_NAME'] == 'AMap.Marker') {
        // //console.log('Marker', overlay.getPosition())
        const marker = overlay.getPosition()
        str = marker['R'] + ' ' + marker['Q']
        return str
      } else if (overlay['CLASS_NAME'] == 'AMap.Polyline') {
        // //console.log('Polyline', overlay.getPath())
        const arr = overlay.getPath().map(item => {
          return item['R'] + ' ' + item['Q']
        })
        str = arr.join(',')
        return str
      } else if (overlay['CLASS_NAME'] == 'AMap.Polygon') {
        // //console.log('Polygon', overlay.getPath())
        const arr = overlay.getPath().map(item => {
          return item['R'] + ' ' + item['Q']
        })
        arr.push(arr[0])
        str = arr.join(',')
        return str
      }
    }
  }
}
</script>
<style lang="less" scoped>
</style>

组件使用

<CoordinateMap ref="CoordinateMap"
               @confirm="pickUpConfirm" />


coordinate: '',
locationType: null


// 坐标拾取
openCoordinateMap () {
  const { coordinate, locationType } = this
  this.$refs.CoordinateMap.showMap(coordinate, locationType)
},
// 组件回调
pickUpConfirm (obj) {
  // console.log('pickUpConfirm', obj)
  this.coordinate = obj.coordinate
  this.locationType = obj.locationType
},

你可能感兴趣的:(地图,前端,javascript,vue.js)