vue项目中使用高德地图
vue中使用高德地图
-
使用高德官方案例
[概述-地图 JS API 高德地图API (amap.com)](https://lbs.amap.com/api/javascript-api/summary/) -
使用第三方基于高德官方开放api的二次封装
-
vue-amap
[组件 vue-amap (elemefe.github.io)](https://elemefe.github.io/vue-amap/#/) 饿了么团队封装的组件, 首推, 有时间了好好研究一下
-
AMap-Vue
使用者较少, 但用起来也还舒服, 文档相对简陋, 但他提供了扩展自定义组件的方法(还是比较舒服的),本次主要使用这个.
-
至于如何安装官方文档已经说明了: [介绍 AMap-Vue (gitee.io)](https://jimnox.gitee.io/amap-vue/intro/) -
在AMap-Vue基础上封装的定位到当前城市的按钮组件
<template> <!-- 定位按钮(需要放在 <amap></amap>标签内) --> <div class="amap-geolocation" @click="resetLocation"> <el-button type="primary" icon="el-icon-map-location" /> </div> </template> <script> import { withAmap, loadPlugins } from '@amap/amap-vue' export default { name: 'Amapgeolocation', mixins: [withAmap], data() { return {} }, async mounted() { // 加载插件与初始化---精确定位与城市定位 await loadPlugins(['AMap.Geolocation', 'AMap.CitySearch']) this.gl = new AMap.Geolocation() this.cs = new AMap.CitySearch() }, methods: { // 获取定位 resetLocation() { let that = this this.cs.getLocalCity(function(status, result) { if (status === 'complete' && result.info === 'OK') { // 查询成功,result即为当前所在城市信息 console.log(result) that.$map.setCenter([(result.bounds.northEast.lng + result.bounds.southWest.lng) / 2, (result.bounds.northEast.lat + result.bounds.southWest.lat) / 2]) that.$map.setZoom(14) } }) } } } </script> <style lang="scss" scoped> .amap-geolocation { position: absolute; right: 20px; top: 20px; width: 32px; height:32px; display: flex; flex-direction: column; justify-content: center; background-image: none; border-radius: 10%; &:hover { background-color: #f0f0f0; } .el-button { width: 32px; height:32px; font-size: 16px; padding: 0; } } </style> -
在AMap-Vue基础上封装的 支持聚合的marker点 组件
使用需要为组件传入
markerData,markerData需要包含定位点数组 lnglat = [lat, lng] (如果需要使用infowindow和label则把需要的参数也一起放进markerData里), 组件中的infowindow和marker的label可按需选择是否保留markerData : [ lnglat: [,], sex: '', // 额外的数据 age: '' // 额外的数据 ]<template> <div> <amap-marker-cluster key="custom-cluster" :data="markerData" key-prop="poiid" :marker-options="getMarkerOptions" :cluster-options="getClusterOptions" :grid-size="options.gridSize" :average-center="options.averageCenter" > <!-- 多个marker时的样式 --> <template v-slot:cluster="context"> <div :style="getClusterStyle(context)" @click="resetZoom(context)"> </div> </template> <!-- 单个marker时的样式 --> <template v-slot:marker="point"> <div class="custom-marker" :class="{warning : point.warning}" @click="clickMarker(point)" /> </template> </amap-marker-cluster> <amap-marker v-if="current" :key="current.memberId" :position="[current.lnglat.lng, current.lnglat.lat]" :label="{ content: current === hover ? current.memberName : '', direction: 'bottom', }" :z-index="current === hover ? 110 : 100" @click="clickMarker(current, current.memberName)" /> <amap-info-window v-if="current && activeAoi" :position="activeAoi.position" :offset="[0, -30]" auto-move ><div> <div>性别: </div> <div>年龄: </div> </div> </amap-info-window> </div> </template> <script> import { withAmap } from '@amap/amap-vue' function interpolate(u, begin, end) { if (u < 0) u = 0 if (u > 1) u = 1 u = Math.pow(u, 1 / 10) return u * (end - begin) + begin } export default { name: 'Comamapmarker', mixins: [withAmap], props: { markerData: { type: Array, default: [] } }, data() { return { warning: 'warning', hover: null, activeAoi: '', options: { gridSize: 40, averageCenter: true, zoomOnClick: true }, current: null } }, mounted() {}, methods: { // 点击点标记 clickMarker(poi, value) { console.log('此标记点的信息', poi, value) poi.position = [poi.lnglat.lng, poi.lnglat.lat] this.activeAoi = this.activeAoi === '' ? poi : '' this.hover = this.hover === null ? poi : null this.current = poi console.log('activeAoi: ', this.activeAoi) // 通知父组件当前选中的是哪个marker this.$emit('markerValue', value) }, // 移除地图覆盖物 fitView() { requestAnimationFrame(() => { // todo 移除地图覆盖物 this.$map.setFitView(null, false, [0, 0, 300, 0]) }) }, // 根据经纬度查询地址信息 getAddress(lng, lat) { let lnglat = [lng, lat] this.gc.getAddress(lnglat, function(status, result) { if (status === 'complete' && result.info === 'OK') { // result为对应的地理位置详细信息 console.log(result.regeocode.formattedAddress) } }) }, getMarkerOptions(point) { return { offset: [0, 0] } }, getClusterOptions(context) { const size = Math.round( 30 + Math.pow(context.count / this.markerData.length, 1 / 5) * 20 ) return { offset: [-size / 2, -size / 2] } }, getClusterStyle(context) { const u = context.count / this.markerData.length const hue = ~~interpolate(u, 90, 0) const size = ~~interpolate(u, 30, 50) return { backgroundColor: `hsla(${hue}, 100%, 50%, 0.7)`, width: `${size}px`, height: `${size}px`, lineHeight: `${size}px`, borderRadius: `${size / 2}px`, border: `1px solid hsla(${hue}, 100%, 40%, 1)`, boxShadow: `0 0 1px hsla(${hue}, 100%, 50%, 1)`, color: `hsla(${hue}, 100%, 20%, 1)`, fontSize: '14px', textAlign: 'center' } }, // 地图尺寸放大 resetZoom(context) { console.log(context) // todo 设置地图中心点 this.$map.setCenter(context.marker._position) // todo 重设设置地图zoom let zoom = this.$map.getZoom() this.$map.setZoom(++zoom) } } } </script> <style lang="scss" scoped> // myMarkers { .map-container { width: 100%; height: 500px; } .custom-marker { $color: hsla(128, 100%, 58%, 0.8); background-color: $color; border: 1px solid darken($color, 50%); box-sizing: border-box; $size: 20px; height: $size; width: $size; border-radius: $size / 2; transform: translate3d(-50%, -50%, 0); } .onlyMarker { display: flex; flex-direction: row; justify-content: center; } .amap-marker-label { // position: absolute; z-index: 2; border: 1px solid #00f; background-color: #fff; cursor: default; padding: 3px; width: max-content; /* 元素内容固有的(intrinsic)合适宽度。 */ max-width: 120px; word-break: break-word; /* 文本行的任意字内断开 */ white-space: normal; /* 超出最大宽度换行 */ font-size: 16px; line-height: 1.5; } .info-window-content { position: relative; width: 220px; z-index: 4000; } .warning { background-color: red; } // } </style> <style lang="scss"> // 让marker点标记的内容自动换行 .amap-marker-label { // margin: 15px; max-width: 120px; width: max-content; /* 元素内容固有的(intrinsic)合适宽度。 */ white-space: normal; font-size: 16px; line-height: 1.5; } .amap-info-content { max-width: 200px; white-space: normal; z-index: 1001; } </style> -
作者提供的封装好的组件:
<!-- 地图类型 --> <!-- <amap-map-type /> --> <!-- 缩略图 --> <!-- <amap-hawk-eye /> --> <!-- 指南针 --> <!-- <amap-control-bar /> --> <!-- 缩放工具条 --> <amap-tool-bar /> <!-- 比例尺 属性配置可参考官方文档 position是组件停靠位置, offset是组件相对于地图的偏移 --> <amap-scale :offset="[60, 30]" position="RB" />
-
-