文章目录
- 1、页面效果
- 2、注册 key
- 2.1 登录 [高德开放平台](https://console.amap.com/dev/key/app)
- 2.2 创建新应用
- 3、代码逻辑
- 3.1 引入高德地图
- 3.2 初始化地图
- 3.3 设置定位按钮,获取当前位置,地址逆解析
- 4、源码
- 4.1 应用
- 4.2 map.vue
1、页面效果
2、注册 key
2.1 登录 高德开放平台
2.2 创建新应用
3、代码逻辑
3.1 引入高德地图
npm i @amap/amap-jsapi-loader --save
3.2 初始化地图
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
// 安全密钥
window._AMapSecurityConfig = { securityJsCode: '安全密钥' }
export default {
methods: {
initMap() {
AMapLoader.reset()
AMapLoader.load({
key: 'key(Web端)', // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺少时默认为 1.4.15
plugins: ['AMap.AutoComplete', 'AMap.Marker', 'AMap.PlaceSearch', 'AMap.Geolocation'] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap) => {
this.aMap = AMap
// 设置地图容器id
this.mapEl = new AMap.Map('container', {
viewMode: '3D', // 是否为3D地图模式
zoom: 12 // 初始化地图级别
// center: [116.397428, 39.90923] // 初始化地图中心点位置 默认当前行政区
})
})
}
}
}
</script>
3.3 设置定位按钮,获取当前位置,地址逆解析
this.geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 是否使用高精度定位,默认:true
timeout: 10000, // 超过10秒后停止定位,默认:5s
showButton: true, // 显示定位按钮,默认:true
position: 'RB', // 定位按钮的停靠位置
offset: [10, 20], // 定位按钮与设置的停靠位置的偏移量,默认:[10, 20]
showMarker: true, // 定位成功后在定位到的位置显示点标记,默认:true
panToLocation: true, // 定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy: true // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
})
this.mapEl.addControl(this.geolocation)
this.geolocation.getCurrentPosition() // 自动获取定位
// 返回定位信息
this.geolocation.on('complete', (res) => {
console.log('res', res)
})
// 返回定位出错信息
this.geolocation.on('error', (err) => {
console.log('err', err)
})
// 获取当前位置
getCurrentAddr() {
this.geolocation.getCurrentPosition((status, result) => {
// console.log(status, result)
if (status == 'complete') {
this.getAddress(result.position.lng, result.position.lat)
return result.position
} else {
this.$message.error('获取定位失败')
}
})
},
// 地址逆解析
getAddress(lng, lat) {
request({
url: `https://restapi.amap.com/v3/geocode/regeo?location=${lng},${lat}&key=${key(Web服务)}&radius=1000&extensions=all`
method: 'get'
}).then((res) => {
if (res.status == '1') {
console.log('res', res)
} else {
this.$message({ message: res.info, type: 'error' })
}
})
},
注意:
地图初始化所用 key 和地址逆解析不同,前者属于
Web端(JS API)
,后者属于Web服务
4、源码
4.1 应用
<script>
import Map from './map.vue'
export default {
components: {
Map
},
data() {
return {
show: false,
addr: {}
}
},
mounted() {},
methods: {
open() {
this.show = true
},
confirm(info) {
this.addr = info
}
}
}
</script>
<template>
<div class="map-point">
<div class="open">
<div class="info">
<p>地址:{{ addr.name }}</p>
<p>经度:{{ addr.lng }}</p>
<p>纬度:{{ addr.lat }}</p>
</div>
<el-button type="primary" @click="open">打 开</el-button>
</div>
<Map :show="show" :info="addr" @cancel="show = false" @confirm="confirm" />
</div>
</template>
<style lang="scss" scoped>
.map-point {
.open {
width: 460px;
margin: 300px auto;
.info {
margin-bottom: 20px;
}
}
}
</style>
4.2 map.vue
<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import request from '@/hooks/request.js'
// 安全密钥
window._AMapSecurityConfig = { securityJsCode: '安全密钥' }
export default {
props: {
show: {
type: Boolean,
default: false
},
info: {
type: Object,
default: () => {}
}
},
data() {
return {
visible: false,
loading: false,
addrVal: '',
currentAddr: {},
addrList: [],
mapEl: null,
aMap: null,
geolocation: null,
autoComplete: null,
marker: null
}
},
watch: {
show(n) {
this.visible = n
if (n) {
this.$nextTick(() => {
this.initMap()
})
}
},
info(n) {
this.currentAddr = n
}
},
methods: {
initMap() {
AMapLoader.reset()
AMapLoader.load({
key: 'key(Web端)', // 申请好的Web端开发者Key,首次调用 load 时必填
version: '2.0', // 指定要加载的 JSAPI 的版本,缺少时默认为 1.4.15
plugins: ['AMap.AutoComplete', 'AMap.Marker', 'AMap.PlaceSearch', 'AMap.Geolocation'] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then((AMap) => {
this.aMap = AMap
// 设置地图容器id
this.mapEl = new AMap.Map('container', {
viewMode: '3D', // 是否为3D地图模式
zoom: 12 // 初始化地图级别
// center: [116.397428, 39.90923] // 初始化地图中心点位置 默认当前行政区
})
// this.geolocation = new AMap.Geolocation({
// enableHighAccuracy: true, // 是否使用高精度定位,默认:true
// timeout: 10000, // 超过10秒后停止定位,默认:5s
// showButton: true, // 显示定位按钮,默认:true
// position: 'RB', // 定位按钮的停靠位置
// offset: [10, 20], // 定位按钮与设置的停靠位置的偏移量,默认:[10, 20]
// showMarker: true, // 定位成功后在定位到的位置显示点标记,默认:true
// panToLocation: true, // 定位成功后将定位到的位置作为地图中心点,默认:true
// zoomToAccuracy: true // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
// })
// this.mapEl.addControl(this.geolocation)
// this.geolocation.getCurrentPosition() // 自动获取定位
// // 返回定位信息
// this.geolocation.on('complete', (res) => {
// console.log('res', res)
// })
// // 返回定位出错信息
// this.geolocation.on('error', (err) => {
// console.log('err', err)
// })
this.autoComplete = new AMap.AutoComplete({
city: '全国'
})
if (this.info.lng && this.info.lat) {
this.addmark(this.currentAddr)
}
this.mapEl.on('click', (e) => {
this.getAddress(e.lnglat.getLng(), e.lnglat.getLat())
})
})
},
// 获取当前位置
getCurrentAddr() {
this.geolocation.getCurrentPosition((status, result) => {
// console.log(status, result)
if (status == 'complete') {
this.getAddress(result.position.lng, result.position.lat)
return result.position
} else {
this.$message.error('获取定位失败')
}
})
},
// 地址逆解析
getAddress(lng, lat) {
request({
url: `https://restapi.amap.com/v3/geocode/regeo?location=${lng},${lat}&key=${key(Web服务)}&radius=1000&extensions=all`,
method: 'get'
}).then((res) => {
if (res.status == '1') {
// console.log('res', res)
this.addmark({ lng, lat, name: res.regeocode.formatted_address })
} else {
this.$message({ message: res.info, type: 'error' })
}
})
},
addmark(info) {
if (this.marker) this.mapEl.remove(this.marker)
this.currentAddr = info
this.marker = new this.aMap.Marker({
position: new this.aMap.LngLat(info.lng, info.lat),
title: info.name, // 鼠标滑过点标记时的文字提示
label: {
content: info.name // 文本标注的内容
}
// zooms: 14 // 点标记显示的层级范围,超过范围不显示。默认值:zooms: [2, 20]
})
this.mapEl.add(this.marker)
this.mapEl.setCenter([info.lng, info.lat], false, 500) // 中心点 是否直接迁移(动画过度) 过渡时间
},
// 自定义远程搜索方法
remoteMethod(e) {
if (e.trim() != '') {
this.loading = true
setTimeout(() => {
this.autoComplete.search(e, (status, result) => {
// console.log(status, result)
this.loading = false
if (status == 'complete' && result.tips.length) {
this.addrList = result.tips
}
})
}, 200)
}
},
selectChange(e) {
if (!e) return
let info = this.addrList.find((v) => v.name + '_' + v.district == e)
if (info.location) {
// 自动适应显示想显示的范围区域
// this.mapEl.setFitView()
this.addmark({ ...info.location, name: info.name })
} else {
this.$message.warning('该地点经纬度信息缺失')
}
},
cancel() {
this.visible = false
this.$emit('cancel', false)
},
confirm() {
if (!this.currentAddr.name) {
this.$message.warning('请先选择一个地址')
return
}
this.cancel()
this.$emit('confirm', this.currentAddr)
}
}
}
</script>
<template>
<div class="map_point">
<el-dialog
class="dialog"
title="地图选点"
v-model="visible"
top="100px"
width="80%"
:draggable="true"
:show-close="false"
:close-on-click-modal="false"
destroy-on-close
>
<div class="map-head">
<el-select
v-model="addrVal"
:loading="loading"
clearable
remote
filterable
reserve-keyword
placeholder="请输入关键词"
style="width: 320px"
:remote-method="remoteMethod"
@change="selectChange"
>
<el-option
v-for="item in addrList"
:key="item.id"
:label="item.name"
:value="item.name + '_' + item.district"
>
<div class="option" style="display: flex; justify-content: space-between">
<span>{{ item.name }}</span>
<span style="margin-left: 20px; color: #999; font-size: 12px">
{{ item.district }}
</span>
</div>
</el-option>
</el-select>
<div class="currentAddr">当前选择地址:{{ currentAddr.name }}</div>
</div>
<div id="container"></div>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancel">关 闭</el-button>
<el-button type="primary" @click="confirm">确 定</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<style lang="scss" scoped>
.dialog {
border-radius: 4px;
background-color: #ffffff;
.map-head {
height: 40px;
width: 100%;
display: flex;
align-items: center;
.currentAddr {
margin-left: 32px;
}
}
#container {
height: 500px;
width: 100%;
margin-top: 10px;
}
}
</style>