在高德控制台创建项目
创建项目,填写key名称,选择服务平台,完成后会生成key和安全秘钥jscode(安全秘钥使用说明)
安全秘钥使用方式:
1. JSAPI key搭配代理服务器并携带安全密钥转发(安全)
引入地图 JSAPI 脚本之前增加代理服务器设置脚本标签,设置代理服务器域名或地址,将下面示例代码中的「您的代理服务器域名或地址」替换为您的代理服务器域名或ip地址,其中_AMapService为代理请求固定前缀,不可省略或修改。(注意您这个设置必须是在 JSAPI 的脚本加载之前进行设置,否则设置无效。)
<script type="text/javascript">
window._AMapSecurityConfig = {
serviceHost:'您的代理服务器域名或地址/_AMapService',
// 例如 :serviceHost:'http://1.1.1.1:80/_AMapService'
}
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script>
代理服务器的设置: 以 Nginx 反向代理为例,参考以下三个location配置,进行反向代理设置,分别对应自定义地图、海外地图、Web服务,其中自定义地图和海外地图如果没有使用到相关功能也可以不设置。需要将以下配置中的“您的安全密钥”六个字替换为您刚刚获取的jscode安全密钥。如果您使用了多个key,需要在代理设置中根据 key来映射不同的安全密钥。
server {
listen 80; #nginx端口设置,可按实际端口修改
server_name 127.0.0.1; #nginx server_name 对应进行配置,可按实际添加或修改
# 自定义地图服务代理
location /_AMapService/v4/map/styles {
set $args "$args&jscode=您的安全密钥";
proxy_pass https://webapi.amap.com/v4/map/styles;
}
# 海外地图服务代理
location /_AMapService/v3/vectormap {
set $args "$args&jscode=您的安全密钥";
proxy_pass https://fmap01.amap.com/v3/vectormap;
}
# Web服务API 代理
location /_AMapService/ {
set $args "$args&jscode=您的安全密钥";
proxy_pass https://restapi.amap.com/;
}
}
2. JSAPI key搭配静态安全密钥以明文设置(不安全,建议开发环境用):
引入地图 JSAPI 脚本之前增加设置 JSAPI 安全密钥的脚本标签,并将您的安全密钥「您申请的安全密钥」替换为您的安全密钥;(注意这个设置必须是在 JSAPI 的脚本加载之前进行设置,否则设置无效。)
<script type="text/javascript">
window._AMapSecurityConfig = {
securityJsCode:'您申请的安全密钥'
}
</script>
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=您申请的key值"></script>
初始化地图
定义地图容器
<template>
<div id="map-container"></div>
</template>
<style scoped lang="less">
#map-container {
padding: 0;
margin: 0;
width: 100%;
height: 600px;
}
</style>
定义地图配置信息
//store/mapOption.js
export default {
namespaced: true,
state: {
securityJsCode: '安全秘钥',//安全秘钥
option: {
key: '您的key', //设置您的key
version: "2.0",
plugins: ['AMap.ToolBar', 'AMap.Driving', 'AMap.Geocoder','AMap.PolygonEditor'],//需要加载的插件
AMapUI: {
version: "1.1",
plugins: [],
},
Loca: {
version: "2.0"//版本
},
}
}
}
使用AMapLoader来初始化渲染地图组件
//初始化地图
initAMap() {
AMapLoader.load(this.$store.state.mapOption.option)
.then((AMap) => {
this.map = new AMap.Map("map-container", {
viewMode: "3D",
zoom: 14,
zooms: [2, 22],
mapStyle: 'amap://styles/darkblue',// 地图底色
center: this.center//地图中心点
});
})
}
项目中比较常见的实践案例
图层
- 标准图层
- 卫星图层
- 路网图层
- 实时交通图层
- 楼块图层
- 室内图层
//使用卫星图层举例
const satellite = new AMap.TileLayer.Satellite();
//添加图层
map.addLayer(satellite);
//移除图层
map.removeLayer(satellite);
//展示图层
satellite.show();
//移除
satellite.hide();
覆盖物
- 点标记
//渲染标记点
let marker = null
marker = new AMap.Marker({
position: [111.749180,40.842585],
offset: new AMap.Pixel(0, 0)
})
// 自定义点标记内容
const markerContent = document.createElement("div");
// 点标记中的文本
const markerSpan = document.createElement("span");
markerSpan.className = 'marker';
markerSpan.style.backgroundColor = '#1791fc'
markerSpan.innerHTML = '点标记'
markerContent.appendChild(markerSpan);
marker.setContent(markerContent); //更新点标记内容
marker.setMap(map);
-
矢量图形
(1)折线覆盖物 Polyline
(2)多边形覆盖物 Polygon
(3)圆形覆盖物 Circle
(4)矩形覆盖物 Rectangle
(5)椭圆形覆盖物 Ellipse
//多边形覆盖物 Polygon举例
const path = [
[111.749180,40.842585],
[110.749180,40.842585],
[110.749180,41.842585],
[111.749180,41.842585],
]
const polygon = new AMap.Polygon({
path,
strokeColor: '#1791fc',
strokeWeight: 3,
strokeOpacity: 1,
fillOpacity: 0.4,
fillColor: '#1791fc',
zIndex: 50,
bubble: true,
})
//将已有图层渲染到地图上
this.map.add([polygon]);
//自适应缩放
this.map.setFitView()
事件
//监听鼠标点击事件
this.map.on('click', (e) => {
const {lng, lat} = e.lnglat
//当前鼠标点击的经纬度
const position = [lng, lat]
//如果已经存在marker,更新数据
if (this.marker) {
this.marker.setPosition(position)
return
}
//初始化一个marker
this.marker = new AMap.Marker({
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
position,
offset: new AMap.Pixel(-13, -30)
})
this.marker.setMap(this.map);
})
几何计算
// 创建几何图层数据
export const getPolygonData = lnglatList => {
return {
type: "FeatureCollection",
features: [
{
type: "Feature",
id: 1043,
properties: {"_draw_type": "fill"},
geometry: {
type: "Polygon",
coordinates: [
lnglatList
]
},
}
]
}
}
//传入坐标数组计算两点之间距离
export const calculateDistance = lnglatList => {
const pointStart = new AMap.LngLat(lnglatList[0][0], lnglatList[0][1])
const pointEnd = new AMap.LngLat(lnglatList[1][0], lnglatList[1][1])
const distance = pointStart.distance(pointEnd).toFixed(2) || 0
return `标点距离:${distance} m`
}
//传入坐标数组计算封闭区域面积
export const calculateArea = lnglatList => {
const area = AMap.GeometryUtil.ringArea(lnglatList).toFixed(2) || 0
return `标点区域面积:${area} ㎡`
}
export default {
getPolygonData,
calculateDistance,
calculateArea
}
逆向地理编码方法
const geocoder = new AMap.Geocoder({
city: "呼和浩特市", //城市设为北京,默认:“全国”
});
geocoder.getLocation(address, (status, result) => {
if (status === 'complete' && result.geocodes.length) {
const lnglat = result.geocodes[0].location
console.log('根据地址转换经纬度:',lnglat);
this.marker.setPosition(lnglat);
this.map.add(this.marker);
this.map.setFitView(this.marker);
} else {
console.log('根据地址查询位置失败');
}
});
多边形编辑器
<template>
<div style="position: relative">
<div id="map-draw"></div>
<div class="input-card" style="width: 160px">
<button class="btn" @click="setCenterMarker" style="margin-bottom: 5px">开始标记中心点</button>
<button class="btn" @click="stopMarker" style="margin-bottom: 5px">结束标记中心点</button>
<button class="btn" @click="startDraw" style="margin-bottom: 5px" v-if="canDraw">开始标注图层</button>
<button class="btn" @click="stopDraw" style="margin-bottom: 5px">结束标注图层</button>
</div>
</div>
</template>
<script>
import AMapLoader from '@amap/amap-jsapi-loader';
export default {
name: "MapDraw",
data() {
return {
map: null,
center: [111.748814, 40.842127],
polygon: null,
canDraw: true,
currentPolygon: null,
polygonList: [],
}
},
mounted() {
this.initAMap();
},
methods: {
//结束绘制
stopDraw() {
if (this.polygon) {
this.polygon.close()
//保存当前标注图层数据
const params = {}
this.$https.fetchPut('服务端地址', params)
.then(data => {
//TODO 成功回调逻辑
})
.catch(err => {
console.log(err);
});
}
},
//开始绘制
startDraw() {
if (!this.canDraw) {
return
}
this.canDraw = false
this.polygon.setTarget();
this.polygon.open();
},
//获取平级网格
getGridList() {
this.$https.fetchGet('服务端地址', {})
.then(res => {
if (res.data.code === 200) {
res.data.data
.filter(gird => gird.calloutData)
.forEach(grid => {
const polygon = new AMap.Polygon({
path: JSON.parse(grid.calloutData),
strokeColor: grid.gridColor || '#1791fc',
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: grid.gridColor || '#1791fc',
zIndex: 50,
bubble: true,
})
if (Number(grid.gridId) !== Number(this.gridId)) {
this.polygonList.push(polygon)
} else {
this.currentPolygon = polygon
this.canDraw = false
this.marker = marker
// 吸附
this.polygon.addAdsorbPolygons([polygon])
//将已有图层渲染到地图上
this.map.add([polygon]);
//绑定双击事件
this.currentPolygon.on('dblclick', () => {
this.polygon.setTarget(this.currentPolygon);
this.polygon.open();
this.map.setFitView()
})
}
})
if (this.polygonList.length === 0) {
return
}
// 吸附
this.polygon.addAdsorbPolygons(this.polygonList)
//将已有图层渲染到地图上
this.map.add(this.polygonList);
//自适应缩放
this.map.setFitView()
}
})
.catch(err => {
console.log(err);
});
},
//初始化地图
initAMap() {
AMapLoader.load(this.$store.state.mapOption.option)
.then((AMap) => {
this.map = new AMap.Map("map-draw", {
viewMode: "3D",
zoom: 14,
zooms: [2, 22],
center: this.center,
});
//初始化一个多边形编辑器
this.polygon = new AMap.PolygonEditor(this.map);
//调用close之后触发该事件,target即为编辑后的覆盖物对象
this.polygon.on('end', (e) => {
this.currentPolygon = e.target._opts.path
// 双击当前图层可再次编辑
e.target.on('dblclick', () => {
this.polygon.setTarget(e.target);
this.polygon.open();
})
})
// 获取平级网格列表
this.getGridList()
})
}
}
}
</script>
<style scoped lang="less">
#map-draw {
padding: 0;
margin: 0;
width: 100%;
height: 600px;
}
.input-card {
display: flex;
flex-direction: column;
min-width: 0;
word-wrap: break-word;
background-color: #fff;
background-clip: border-box;
border-radius: .25rem;
width: 25rem;
border-width: 0;
border-radius: 0.4rem;
box-shadow: 0 2px 6px 0 rgba(114, 124, 245, .5);
position: absolute;
bottom: 1rem;
right: 1rem;
-ms-flex: 1 1 auto;
flex: 1 1 auto;
padding: 0.75rem 1.25rem;
}
.btn {
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid transparent;
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
background-color: transparent;
background-image: none;
color: #25A5F7;
border-color: #25A5F7;
padding: .25rem .5rem;
line-height: 1.5;
border-radius: 1rem;
-webkit-appearance: button;
cursor: pointer;
}
.btn:hover {
color: #fff;
background-color: #25A5F7;
border-color: #25A5F7
}
.btn:hover {
text-decoration: none
}
</style>