高德地图申请apikey,
在项目index.html中放入
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<script type="text/javascript">
window._AMapSecurityConfig = {
// serviceHost:'您的代理服务器域名或地址/_AMapService',
// 例如 :serviceHost:'http://1.1.1.1:80/_AMapService',
securityJsCode: '1233************'
}
</script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
<template>
<div class="car-home">
<Button @click="() => {this.$router.push('/')}">返回首页</Button>
<div style="margin-top: 10px">
<div class="input-content">
<span class="input-title">起点</span>
<Input v-model="startPoint" placeholder="请输入..." style="width: 300px" @on-blur="getNewAddress('start')"></Input>
</div>
<div class="input-content">
<span class="input-title">终点</span>
<Input v-model="endPoint" placeholder="请输入..." style="width: 300px" @on-blur="getNewAddress('end')"></Input>
</div>
</div>
<div id="container"></div>
<div id="panel"></div>
<Button @click="openGDApp">打开高德地图app</Button>
</div>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import Vue from "vue";
export default Vue.extend({
data() {
return {
map:null,
driving: null,
geocoder: null,
isFirst: true,
startPoint: '我的位置',
endPoint: '香港理工大学',
startPointArr: [],
startFormattedAddress: '', // 正向地址解析后得具体地址(起点)
endPointArr: [],
endFormattedAddress: '', // 正向地址解析后的具体地址(终点)
}
},
async mounted() {
await this.initMap()
},
methods: {
initMap() {
AMapLoader.load({
"key": "012121*************************a", // 申请好的Web端开发者Key,首次调用 load 时必填
"version": "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
"plugins": ['AMap.Geolocation', 'AMap.Geocoder', 'AMap.ToolBar', 'AMap.Driving', 'AMap.Scale'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then(async(AMap)=>{
this.map = new AMap.Map('container', {
resizeEnable: true,
// center: [116.397428, 39.90923],//地图中心点
zoom: 13 //地图显示的缩放级别
});
await this.getGeolocation()
}).catch(e => {
console.log(e);
})
},
async getGeolocation() {
this.geolocation = new AMap.Geolocation({
enableHighAccuracy: true,//是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:无穷大
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB',左下角
buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: false, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
zoomToAccuracy:true //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
})
this.geolocation.getCurrentPosition(async(status, result) => {
console.log("获取当前位置", status, result)
if (status == 'complete') {
this.$set(this.startPointArr, 0, result.position.lng)
this.$set(this.startPointArr, 1, result.position.lat)
let addressResult = await this.getAddressGeocoder(1, this.startPointArr)
this.startPoint = addressResult.regeocode.formattedAddress
let addressResult1 = await this.getAddressGeocoder(0, this.endPoint)
this.endPointArr[0] = addressResult1.geocodes[0].location.lng
this.endPointArr[1] = addressResult1.geocodes[0].location.lat
this.endFormattedAddress = addressResult1.geocodes[0].formattedAddress
await this.getDriving()
} else {
console.log('err', result)
}
})
},
getDriving() {
if(this.driving) {
this.driving.clear()
}
let a1 = this.startPointArr[0]
let a2 = this.startPointArr[1]
let a3 = this.endPointArr[0]
let a4 = this.endPointArr[1]
console.log("起点坐标", this.startPointArr)
console.log("终点坐标", this.endPointArr)
this.driving = new AMap.Driving({
policy: AMap.DrivingPolicy.LEAST_TIME,
map:this.map //绑定地图组件
})
this.driving.search(new AMap.LngLat(a1, a2), new AMap.LngLat(a3, a4), (status, result) => {
// driving.search(new AMap.LngLat(116.397428, 39.90923), new AMap.LngLat(116.427281, 39.903719), function(status, result) {
console.log("status=",status)
console.log('result=', result)
console.log(result.destination.KL)
this.result = result
if (status === 'complete') {
// console.log('绘制驾车路线完成')
} else {
// console.log('获取驾车数据失败:' + result)
}
})
},
/**
* 输入框
*/
async getNewAddress(which) {
let addressResult = which === 'start' ? await this.getAddressGeocoder(0, this.startPoint) : await this.getAddressGeocoder(0, this.endPoint)
console.log("addressResult==",addressResult)
if(which === 'start') {
this.startPointArr[0] = addressResult.geocodes[0].location.lng
this.startPointArr[1] = addressResult.geocodes[0].location.lat
this.startFormattedAddress = addressResult.geocodes[0].formattedAddress
} else {
this.endPointArr[0] = addressResult.geocodes[0].location.lng
this.endPointArr[1] = addressResult.geocodes[0].location.lat
this.endFormattedAddress = addressResult.geocodes[0].formattedAddress
}
this.$nextTick(() => {
this.getDriving()
})
},
/**
* 正向、逆向地址解析
*/
getAddressGeocoder(isGetAdress = 0, pointArr) {
var geocoder = new AMap.Geocoder({
// city 指定进行编码查询的城市,支持传入城市名、adcode 和 citycode
// city: '010'
})
return new Promise((resolve, reject) => {
if(isGetAdress === 1) {
geocoder.getAddress(pointArr, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
resolve(result)
} else {
reject(result)
}
})
} else {
geocoder.getLocation(pointArr, (status, result) => {
if (status === 'complete' && result.info === 'OK') {
resolve(result)
} else {
reject(result)
}
})
}
})
},
openGDApp() {
const url = `https://uri.amap.com/navigation?from=${this.startPointArr[0]},${this.startPointArr[1]},${this.startPoint}&to=${this.endPointArr[0]},${this.endPointArr[1]},${this.endPoint}&mode=car&callnative=1&coordinate=wgs84&src=mypage`
// https://segmentfault.com/q/1010000010711865?sort=created
// https://lbs.amap.com/api/amap-mobile/guide/android/navigation
// const url = `androidamap://navi?sourceApplication=appname&poiname=fangheng&lat=36.547901&lon=104.258354&dev=1&style=2`
window.open(url)
}
},
destroyed() {
this.map.destroy()
}
})
</script>
<style lang="less" scoped>
#container {
width: 100%;
height: 400px;
}
.input-content {
margin-bottom: 8px;
}
.input-title {
margin-right: 8px;
}
.car-home {
width: 100%;
padding: 10px;
// height: 500px;
}
#panel {
position: fixed;
background-color: white;
max-height: 90%;
overflow-y: auto;
top: 10px;
right: 10px;
width: 280px;
}
#panel .amap-call {
background-color: #009cf9;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
#panel .amap-lib-driving {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
overflow: hidden;
}
</style>
<template>
<div class="demo-nav1">
<div class="header-content">
<Button @click="() => {this.$router.push('/')}">返回首页</Button>
<div class="point-content">
<span class="point-text">起点</span>
<Input v-model="startPoint" placeholder="请输入..." style="width: 300px" @on-blur="getNewAddress('start')" />
</div>
<div class="point-content">
<span class="point-text">终点</span>
<Input v-model="endPoint" placeholder="请输入..." style="width: 300px" @on-blur="getNewAddress('end')" />
</div>
</div>
<div id="container1" class="map-content"></div>
<div id="panel"></div>
<div class="input-item">
<Button @click="startAnimation()">开始导航</Button>
<Button @click="stopAnimation()">停止导航</Button>
<Button @click="stopAnimation2()">模拟导航</Button>
</div>
</div>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
import Vue from "vue";
export default Vue.extend({
// name: "Map",
data() {
return {
map: null,
driving: null,
moveAnimation: null,
startPoint: '我的位置',
startPointArr: [],
startFormattedAddress: '', // 正向地址解析后得具体地址(起点)
endPoint: '江苏省苏州市苏州大学',
endPointArr: [],
endFormattedAddress: '', // 正向地址解析后的具体地址(终点)
carIconPoint: [],
lineArr: [],
path: [], // 该值用于实时导航的数据值,具体用于俺也不是非常清楚
marker: null,
flag: true,
interval: null,
polyline: null, // 绘制轨迹
passedPolyline: null,
}
},
async mounted() {
await this.clearPolyline()
await this.initMap()
},
destroyed() {
this.map.destroy()
},
methods: {
initMap() {
// https://lbs.amap.com/api/jsapi-v2/documentation#map
AMapLoader.load({
"key": "0d8322**************************a", // 申请好的Web端开发者Key,首次调用 load 时必填
"version": "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
"plugins": ['AMap.Geolocation', 'AMap.Geocoder', 'AMap.ToolBar', 'AMap.Driving', 'AMap.Scale', 'AMap.MoveAnimation', 'AMap.HawkEye', 'AMap.ControlBar'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
}).then(async(AMap) => {
this.map = new AMap.Map('container1', {
resizeEnable: true,
// center: [116.397428, 39.90923],//地图中心点
zoom: 13 //地图显示的缩放级别
});
// 新建当前定位
await this.getGeolocation()
// 当前位置设为起点
await this.setStartPointArr()
// 根据终点地址-正向解析地址
let addressResult1 = await this.getAddressGeocoder(0, this.endPoint)
this.endPointArr[0] = addressResult1.geocodes[0].location.lng
this.endPointArr[1] = addressResult1.geocodes[0].location.lat
this.endFormattedAddress = addressResult1.geocodes[0].formattedAddress
console.log("this.startPointArr==",this.startPointArr)
console.log("this.endPointArr==",this.endPointArr)
await this.getDriving()
}).catch(e => {
console.log(e);
})
},
/**
* 方向工具条
*/
getControlBar() {
this.map.addControl(new AMap.ControlBar({
visible: true,
position: {
top: '10px',
right: '10px'
}
}));
},
/**
* 设置起点位置为当前位置
*/
async setStartPointArr() {
let startPointArr = await this.getCurrentPosition()
this.$set(this.startPointArr, 0, startPointArr[0])
this.$set(this.startPointArr, 1, startPointArr[1])
let addressResult = await this.getAddressGeocoder(1, this.startPointArr)
this.startPoint = addressResult.regeocode.formattedAddress
},
/**
* 输入框的内容
*/
async getNewAddress(which) {
await this.clearPolyline()
let addressResult = which === 'start' ? await this.getAddressGeocoder(0, this.startPoint) : await this.getAddressGeocoder(0, this.endPoint)
if (which === 'start') {
this.startPointArr[0] = addressResult.geocodes[0].location.lng
this.startPointArr[1] = addressResult.geocodes[0].location.lat
this.startFormattedAddress = addressResult.geocodes[0].formattedAddress
} else {
this.endPointArr[0] = addressResult.geocodes[0].location.lng
this.endPointArr[1] = addressResult.geocodes[0].location.lat
this.endFormattedAddress = addressResult.geocodes[0].formattedAddress
}
this.$nextTick(() => {
this.getDriving()
})
},
/**
* 正向、逆向地址解析
* https://lbs.amap.com/api/jsapi-v2/guide/services/geocoder
*/
getAddressGeocoder(isGetAdress = 0, pointArr) {
var geocoder = new AMap.Geocoder({})
return new Promise((resolve, reject) => {
if (isGetAdress === 1) {
geocoder.getAddress(pointArr, (status, result) => { // 逆向地理编码方法
if (status === 'complete' && result.info === 'OK') {
resolve(result)
} else {
reject(result)
}
})
} else {
geocoder.getLocation(pointArr, (status, result) => { // 正向地理编码方法
if (status === 'complete' && result.info === 'OK') {
resolve(result)
} else {
reject(result)
}
})
}
})
},
/**
* 创建定位
*/
getGeolocation() {
this.geolocation = new AMap.Geolocation({
enableHighAccuracy: true,//是否使用高精度定位,默认:true
timeout: 10000, //超过10秒后停止定位,默认:无穷大
// offset: [10, 20], // 定位按钮的停靠位置的偏移量
zoomToAccuracy:true, //定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
// position: 'RB', // 定位按钮的排放位置, RB表示右下
maximumAge: 0, //定位结果缓存0毫秒,默认:0
convert: true, //自动偏移坐标,偏移后的坐标为高德坐标,默认:true
showButton: true, //显示定位按钮,默认:true
buttonPosition: 'LB', //定位按钮停靠位置,默认:'LB'
buttonOffset: new AMap.Pixel(10, 20),//定位按钮与设置的停靠位置的偏移量,默认:Pixel(10, 20)
showMarker: true, //定位成功后在定位到的位置显示点标记,默认:true
showCircle: false, //定位成功后用圆圈表示定位精度范围,默认:true
panToLocation: true, //定位成功后将定位到的位置作为地图中心点,默认:true
})
},
/***
* 获取当前定位位置
*/
getCurrentPosition() {
return new Promise((resolve, reject) => {
this.geolocation.getCurrentPosition((status, result) => {
if(status === 'complete') {
resolve([result.position.lng, result.position.lat])
} else {
reject(result)
}
})
})
},
/**
* 行驶路径规划
*/
getDriving() {
if(this.driving) {
this.driving.clear()
}
this.driving = new AMap.Driving({
policy: AMap.DrivingPolicy.LEAST_TIME, // 驾车路线规划策略,AMap.DrivingPolicy.LEAST_TIME是最快捷模式
map: this.map // 绑定组件
})
let _this = this
this.driving.search(new AMap.LngLat(_this.startPointArr[0], _this.startPointArr[1]), new AMap.LngLat(_this.endPointArr[0], _this.endPointArr[1]), (status, result) => {
result.routes[0].steps.forEach((item,index) => {
item.path.forEach((sitem, sindex) => {
if(index === 0 && sindex === 0) {
_this.carIconPoint = [sitem.lng, sitem.lat]
}
_this.lineArr.push([sitem.lng, sitem.lat])
})
})
this.getMoveAnimation()
})
},
/**
* 轨迹路径绘制
* https://lbs.amap.com/api/jsapi-v2/update
*/
getMoveAnimation() {
AMap.plugin('AMap.MoveAnimation', async() => {
// https://lbs.amap.com/api/jsapi-v2/documentation#map
this.map = new AMap.Map('container1', {
resizeEnable: true,
center: this.startPointArr,
zoom: 15, // 地图显示的缩放级别,可以设置为浮点数;若center与level未赋值,地图初始化默认显示用户所在城市范围。
pitch: 50, // 俯仰角度,默认 0,最大值根据地图当前 zoom 级别不断增大,2D地图下无效
terrain: true, // 地图是否展示地形,此属性适用于 3D 地图。默认为值 false 不展示地形,可选 true ,选择 true 会展示地形效果。(注意:此属性适用于 JSAPI v2.1Beta 及以上版本)。
// rotation: -0.7908261543741522,
viewMode: '3D', //开启3D视图,默认为关闭
buildingAnimation: true, //楼块出现是否带动画
})
window.map = this.map
await this.getControlBar()
// https://lbs.amap.com/api/jsapi-v2/documentation#marker
this.marker = new AMap.Marker({
map: this.map, // 要显示该marker的地图对象
position: this.carIconPoint, // 点标记在地图上显示的位置,如果用作startPointArr会出现偏差!!!
// position: this.startPointArr, // 点标记在地图上显示的位置,如果用作startPointArr会出现偏差!!!
icon: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png', // 在点标记中显示的图标。可以传一个图标地址,也可以传Icon对象。有合法的content内容设置时,此属性无效。
offset: new AMap.Pixel(-13, -26),
})
// // 绘制轨迹
this.polyline = new AMap.Polyline({
// new AMap.Polyline({
map: this.map,
path: this.lineArr,
showDir: true,
strokeColor: "#0076ff", //线颜色
// strokeOpacity: 1, //线透明度
strokeWeight: 6, //线宽
// strokeStyle: "solid" //线样式
})
this.passedPolyline = new AMap.Polyline({
map: this.map,
strokeColor: "#00ff14", //线颜色
strokeWeight: 6, //线宽
})
this.marker.on('moving', (e) => {
console.log('moving', e)
if(this.flag) {
Array.prototype.push.apply(this.path, e.passedPath)
this.passedPolyline.setPath(this.path)
} else {
this.passedPolyline.setPath(e.passedPath) // 延长驾驶途径过的轨迹
}
this.map.setCenter(e.target.getPosition()) // 设置地图中心点
this.map.setRotation(-e.target.getOrientation()) // 设置旋转角
console.log("eee",e)
})
})
},
clearPolyline() {
console.log('clearPolyline')
this.path.length > 0 && (this.path = [])
this.lineArr.length > 0 && (this.lineArr = [])
this.map && (this.map.clearMap())
},
/**
* 开始导航
*/
async startAnimation() {
this.flag = true
// 清楚画布
await this.clearPolyline()
// 将起点位置定位到当前位置,终点位置不变,画出路径,在实时勾画轨迹
await this.setStartPointArr()
// 路径规划
await this.getDriving()
this.interval = setInterval(async() => {
let curPosition = await this.getCurrentPosition()
this.marker.moveTo(curPosition, {
duration: 1000,
delay: 500,
autoRotation: true
})
}, 1000)
},
/**
* 地图中心点以及缩放级别
* https://lbs.amap.com/api/jsapi-v2/guide/map/state
* isPlay为1在实时行驶过程中地图放大,isPlay为0在回到暂停或者不在播放的时候显示小地图
*/
getZoomAndCenter() {
this.map.setZoomAndCenter(40, this.startPointArr)
},
stopAnimation2() { // 开始移动
this.flag = false
this.getZoomAndCenter()
this.marker.moveAlong(this.lineArr, {
duration: 1000,
delay: 500,
autoRotation: true
})
},
// 暂停移动
pauseAnimation() {
this.marker.pauseMove()
},
// 恢复移动
resumeAnimation() {
this.marker.resumeMove();
},
// 停止移动
stopAnimation() {
clearInterval(this.interval)
this.marker.stopMove()
}
}
})
</script>
<style lang="less" scoped>
.demo-nav1 {
width: 100%;
height: 100%;
position: fixed;
bottom: 0;
}
.header-content {
padding: 10px;
}
.point-content {
margin-top: 10px;
}
.point-text {
margin-right: 10px;
}
.map-content {
width: 100%;
height: 100%;
}
#panel {
position: fixed;
background-color: white;
max-height: 90%;
overflow-y: auto;
top: 10px;
right: 10px;
width: 280px;
}
#panel .amap-call {
background-color: #009cf9;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
#panel .amap-lib-driving {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
overflow: hidden;
}
.input-item {
position: absolute;
bottom: 5%;
right: 0;
}
</style>