uniapp自带的map地图组件功能有限,并且适配性实在让人苦恼,高德地图想对成熟稳定且功能比自带map组件完善很多,但是使用较为麻烦,以下是我在uniapp使用高德地图的一些见解和技巧。
可以直接看最后的全部代码,复制粘贴到HBuilder里面,修改key和秘钥即可使用。
页面效果
1.到高德开发平台申请key和安全秘钥
高德开发平台地址 : 我的应用 | 高德控制台 (amap.com)
先创建新应用,应用名称和应用类型根据自己情况来即可
添加新的key应用,这里的需要填写key名称以及选择服务平台,名称自己填即可,服务平台选择web端(js API),点击提交按钮后再列表中可以看到刚刚创建的key。
2.引入npm包
高德使用说明官网: JS API 结合 Vue 使用-基础-进阶教程-地图 JS API 2.0|高德地图API (amap.com)
在项目目录下执行NPM命令,安装Loader
npm i @amap/amap-jsapi-loader --save
3.页面引入高德地图包
安装完成之后在页面引入JS API loader
import AMapLoader from '@amap/amap-jsapi-loader';
4.绑定key值,创建地图
到这里其实就已经能看到地图了
<template>
<view id="container" class=""></view>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
export default {
name: "map-view",
mounted() {
this.initAMap();
},
unmounted() {
this.map?.destroy();
},
methods: {
initAMap() {
AMapLoader.load({
key: "你的key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
})
.then((AMap) => {
this.map = new AMap.Map("container", {
// 设置地图容器id
viewMode: "3D", // 是否为3D地图模式
zoom: 11, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
})
.catch((e) => {
console.log(e);
});
},
},
data() {
return {
map: undefined
}
}
};
</script>
<style scoped>
#container {
width: 100%;
height: 100vh;
}
</style>
5.准备点聚合数据
lnglat为经纬度信息字段。
weight字段为可选参数,表示权重值,以权重高的点为中心进行聚合。
id是留给我们自己用的,在点击时好区分点的是哪一个标记。
[
{id:1, weight: 8, lnglat: ["116.506647", "39.795337"] },
{id:2, weight: 8, lnglat: ["116.843352", "40.377362"] },
{id:3, weight: 1, lnglat: ["116.637122", "40.324272"] },
{id:4, weight: 1, lnglat: ["116.105381", "39.937183"] },
{id:5, weight: 1, lnglat: ["116.653525", "40.128936"] }
]
6.准备点聚合样式
数组元素分别对应聚合量在1-10,11-100,101-1000…的聚合点的样式,当开发者设置聚合样式少于实际叠加的点数,未设置部分按照系统默认样式显示。
[
{
//聚合量在1-10时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/blue.png", //图标显示图片的地址
size: new AMap.Size(32, 32), //图标显示图片的大小
offset: new AMap.Pixel(-16, -16), //图标定位在地图上的位置相对于图标左上角的偏移值
textColor: "#fff", //文字的颜色
},
{
//聚合量在11-100时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/green.png",
size: new AMap.Size(32, 32),
offset: new AMap.Pixel(-16, -16),
textColor: "#fff",
},
{
//聚合量在101-1000时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/orange.png",
size: new AMap.Size(36, 36),
offset: new AMap.Pixel(-18, -18),
},
]
7.添加点聚合方法
mapObj地图对象
points为点聚合数据
style为点聚合样式
mapObj.plugin(["AMap.MarkerCluster"], () => {
cluster = new AMap.MarkerCluster(mapObj, this.points, {
styles: styles,
});
cluster.on("click", (e) => { //给每一个点位增加点击事件
this.ClockMarker(e)
});
})
全部代码
8.添加行政区域高亮
获取行政区域数据要配置秘钥,直接通过放到window里面
window._AMapSecurityConfig = {
securityJsCode: "你的安全秘钥",
};
这里是获取行政区域数据和渲染的地方
drawBounds() {
var that = this
//加载行政区划插件
if (!this.district) {
//实例化DistrictSearch
var opts = {
subdistrict: 0, //获取边界不需要返回下级行政区
extensions: 'all', //返回行政区边界坐标组等具体信息
level: 'district' //查询行政级别为 市
};
this.district = new AMap.DistrictSearch(opts);
}
// 获这里写你要获取的城市名称
let keywords = '北京市'
this.district.search(keywords, (status, result) => {
if (!result || !result.districtList || !result.districtList[0]) {
log.warn('请正确填写名称或更新其他名称');
return
}
var bounds = result.districtList[0].boundaries;
if (bounds) {
//生成行政区划polygon
for (var i = 0; i < bounds.length; i += 1) { //构造MultiPolygon的path
bounds[i] = [bounds[i]]
}
let polygon = new AMap.Polygon({
strokeWeight: 1,
path: bounds,
fillOpacity: 0.4,
fillColor: '#80d8ff',
strokeColor: '#0091ea'
});
that.map.add(polygon)
that.map.setFitView(polygon); //视口自适应
}
});
}
全部代码
<template>
<view id="container" class=""></view>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
window._AMapSecurityConfig = {
securityJsCode: "你的安全秘钥",
};
export default {
name: "map-view",
mounted() {
this.initAMap();
},
unmounted() {
this.map?.destroy();
},
methods: {
initAMap() {
let that = this
AMapLoader.load({
key: "你的key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.DistrictSearch"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
})
.then((AMap) => {
that.map = new AMap.Map("container", {
// 设置地图容器id
viewMode: "3D", // 是否为3D地图模式
zoom: 11, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
// 地图加载完成调用
that.map.on('complete', () => {
console.log('地图加载完成');
that.styles = [{
//聚合量在1-10时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/blue.png", //图标显示图片的地址
size: new AMap.Size(32, 32), //图标显示图片的大小
offset: new AMap.Pixel(-16, -16), //图标定位在地图上的位置相对于图标左上角的偏移值
textColor: "#fff", //文字的颜色
},
{
//聚合量在11-100时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/green.png",
size: new AMap.Size(32, 32),
offset: new AMap.Pixel(-16, -16),
textColor: "#fff",
},
{
//聚合量在101-1000时,聚合点的样式
url: "//a.amap.com/jsapi_demos/static/images/orange.png",
size: new AMap.Size(36, 36),
offset: new AMap.Pixel(-18, -18),
},
]
that.SetMarkerCluster()
that.drawBounds()
});
})
.catch((e) => {
console.log(e);
});
},
ClockMarker(e) {
// cluster:点击的聚合点对象
// lnglat:点击的位置点坐标
// target:点聚合插件对象
// marker:点击的聚合点所包含的点对象
// 获取当前点击对象里面的标记
let clusterData = e.clusterData
// 获取当前点击的标记,这个地方一直都会有一个,根据points数组里面的weight权限值
let data = e.cluster.p
// 如果只有一个了就说明已经点击到标签
if (clusterData.length <= 1) {
console.log(data.id);
} else {
// 证明还是聚合状态,通过方法放大视图
let zoom = this.map.getZoom()
zoom += 2
this.map.setZoomAndCenter(zoom, [data.lnglat.lng, data.lnglat.lat], true, 300000)
}
},
SetMarkerCluster() {
this.map.plugin(["AMap.MarkerCluster"], () => {
console.log(this.points);
console.log(this.styles);
let cluster = new AMap.MarkerCluster(this.map, this.points, {
styles: this.styles,
});
cluster.on("click", (e) => { //给每一个点位增加点击事件
this.ClockMarker(e)
});
})
},
drawBounds() {
var that = this
//加载行政区划插件
if (!this.district) {
//实例化DistrictSearch
var opts = {
subdistrict: 0, //获取边界不需要返回下级行政区
extensions: 'all', //返回行政区边界坐标组等具体信息
level: 'district' //查询行政级别为 市
};
this.district = new AMap.DistrictSearch(opts);
}
// 获这里写你要获取的城市名称
let keywords = '北京市'
this.district.search(keywords, (status, result) => {
if (!result || !result.districtList || !result.districtList[0]) {
log.warn('请正确填写名称或更新其他名称');
return
}
var bounds = result.districtList[0].boundaries;
if (bounds) {
//生成行政区划polygon
for (var i = 0; i < bounds.length; i += 1) { //构造MultiPolygon的path
bounds[i] = [bounds[i]]
}
let polygon = new AMap.Polygon({
strokeWeight: 1,
path: bounds,
fillOpacity: 0.4,
fillColor: '#80d8ff',
strokeColor: '#0091ea'
});
that.map.add(polygon)
that.map.setFitView(polygon); //视口自适应
}
});
}
},
data() {
return {
district: undefined,
map: undefined,
points: [{
id: 1,
weight: 8,
lnglat: [116.397428, 39.90923]
},
{
id: 2,
weight: 8,
lnglat: [116.317428, 39.90523]
},
{
id: 3,
weight: 1,
lnglat: [116.327428, 39.81523]
},
],
styles: []
}
}
};
</script>
<style scoped>
#container {
width: 100%;
height: 100vh;
}
</style>