高德地图聚合点实现:点位热更新与点击交互
创作时间:
作者:
@小白创作中心
高德地图聚合点实现:点位热更新与点击交互
引用
CSDN
1.
https://blog.csdn.net/2302_78685420/article/details/144710759
本文将详细介绍如何使用高德地图API实现聚合点功能,包括点位热更新和点击交互。通过本文,你将学习到如何通过NPM安装Loader,设置key和安全密钥,并掌握完整的代码实现方法。
初始化高德地图
首先,需要通过NPM安装高德地图的Loader:
npm i @amap/amap-jsapi-loader --save
然后在JavaScript中加载地图:
<script setup>
import AMapLoader from "@amap/amap-jsapi-loader";
let map = null; //地图实例
onMounted(() => {
window._AMapSecurityConfig = {
securityJsCode: "你申请的安全密钥",
};
AMapLoader.load({
key: "替换为你申请的 key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
})
.then((AMap) => {
// 设置地图容器id
map = new AMap.Map("container", {
viewMode: "2D", // 是否为3D地图模式
zoom: 8, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
})
.catch((e) => {
console.log(e);
});
});
</script>
聚合点样式示例
聚合点及热更新完整代码:
HTML部分
<template>
<view>
<view id="container"></view>
</view>
</template>
CSS部分
<style lang="less" scoped>
#container {
width: 100%;
height: 100%;
}
</style>
JavaScript部分
<script setup>
import AMapLoader from "@amap/amap-jsapi-loader";
import { ref,onMounted,onUnmounted,watch,defineEmits } from "vue";
// 组件传参聚合点实例
const props = defineProps({
points: {
type: Array,
//示例代码聚合点位变量规则
default: () => [
{
lnglat: ["116.506621867519", "39.925077049391"],
building: "晨光家园",
district: "朝阳区",
city: "北京",
}
],
},
});
// 注册组件暴露方法
const emits = defineEmits(['pointsClick'])
let map = null; //地图实例
let indexCluster; //聚合点实例
//监听点位变化进行点位热更新
watch(
() => props.points,
(newDataArr) => {
points.value = newDataArr;
if (map) {
loadIndexCluster(newDataArr);
}
}, {
immediate: false,
}
);
onMounted(() => {
window._AMapSecurityConfig = {
securityJsCode: "你申请的安全密钥",
};
AMapLoader.load({
key: "替换为你申请的 key", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: ["AMap.Scale"], //需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
})
.then((AMap) => {
// 设置地图容器id
map = new AMap.Map("container", {
viewMode: "2D", // 是否为3D地图模式
zoom: 8, // 初始化地图级别
center: [116.397428, 39.90923], // 初始化地图中心点位置
});
map.plugin(["AMap.IndexCluster"], function() {
loadIndexCluster(points.value); // 初始加载聚合点
});
})
.catch((e) => {
console.log(e);
});
});
//定义点聚合规则变量
let clusterIndexSet = {
//城市层级
city: {
minZoom: 2,
maxZoom: 10,
},
//区/县层级
district: {
minZoom: 10,
maxZoom: 12,
},
//具体标点层级
building: {
minZoom: 12,
maxZoom: 22,
},
};
//聚合点样式
const _renderClusterMarker = function(context) {
let clusterCount = context.count; //聚合点内点数量
let clusterData = context.clusterData; //聚合点数组
let mainKey = context.index.mainKey; //聚合点对应索引
let constData = clusterData[0][mainKey];//当前层级(市/区)展示名
// 构建聚合点的显示内容
let content;
if (mainKey == "city") {
//城市样式
content = `
<div>
${constData}<br>
${clusterCount > 1 ? clusterCount : ""}${clusterCount > 1 ? "家" : ""}
</div>`;
} else if (mainKey == "district") {
//区样式
content = `
<div>
${constData}<br>
${clusterCount > 1 ? clusterCount : "1"}${clusterCount > 1 ? "家" : ""}
</div>`;
} else {
//区样式
let name = clusterData[0].entName || clusterData[0].name;
content = `
<div style="position: relative;">
<img style="width:20px; height: 24px;" src="" alt="" />
<div>${name}</div>
</div>`;
}
// 自定义点击事件
context.marker.on("click", function(e) {
// touchend 移动端点击事件;mouseup pc点击
let clickType = e.originEvent.type;
// 兼容pc端、移动端判断
if (clickType == "touchend" && getDeviceType() == "Mobile") {
// 移动端
if (clusterData.length != 0 && mainKey == "building") {
setTimeout(() => {
emits('pointsClick', clusterData)//向父组件传递点位信息
}, 100)
}
} else if (clickType == "mouseup" && getDeviceType() == "Desktop") {
// pc端
setTimeout(() => {
emits('pointsClick', clusterData)//向父组件传递点位信息
}, 100)
}
});
context.marker.setContent(content);
};
// 聚合点图层热更新调用
const loadIndexCluster = (newPoints) => {
if (indexCluster) {
// 销毁现有的 IndexCluster 实例
indexCluster.setMap(null);
indexCluster = null;
}
indexCluster = new AMap.IndexCluster(map, newPoints, {
renderClusterMarker: _renderClusterMarker, // 自定义聚合点样式
clusterIndexSet: clusterIndexSet, // 聚合规则
});
};
// 判断当前设备类型
function getDeviceType() {
const userAgent = navigator.userAgent;
// 判断是否是移动设备(手机或平板)
if (
/Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
userAgent
)
) {
return "Mobile";
}
// 默认是电脑
return "Desktop";
}
onUnmounted(() => {
map?.destroy();//释放内存销毁实例
});
</script>
注意事项
- 该项目样式简单直接采用模板字符串插入dom,样式复杂的建议写好点位样式获取dom节点;
- 点击事件加延迟避免触发/影响父组件遮罩点击事件,可采用preventDefault()(e.originEvent.preventDefault();)方法替换定时器延迟调用;
热门推荐
北京安定医院专家解析:青少年常见心理问题应对策略
世界精神卫生日:关注青少年心理健康
专家支招:如何应对青少年心理健康挑战
康奈尔大学最新研究:如何缓解青少年学业压力?
医院洁净手术部建筑技术规范推荐:手术室卫生标准解析
成华区开展“成都烟火气文化体验”活动 海外人士沉浸式感受传统文化魅力
重庆巴南小镇上演系列非遗活动迎新春
体检报告中的“动脉硬化”是怎么回事?
跳投哥能否复制疯狂小杨哥的带货帝国?
《哪吒》和《大耳朵图图》:如何选优秀动画配音?
蒜香烤鸡翅:美味与营养的完美结合!
小瑞同学教你做葱油饼,亲子互动超有趣!
自制葱油饼最佳配料大揭秘!
葱油饼这样吃才健康!
葱油饼DIY大赛:谁家的葱油饼最好吃?
诺奖荐读 | 提升文学素养,从这7本诺奖好书开始
章莉莉:用设计创新让非遗融入现代生活
东方朔的灯谜智慧:元宵节猜灯谜大挑战!
潮阳灯谜协会教你职场智慧:从猜谜到团队协作的创新实践
元宵节猜灯谜,助你心灵放松!
手肿是什么原因引起的
杜甫笔下青松:坚韧不拔的精神象征
孔子《论语》里的青松智慧
医院手术室卫生标准:国标权威解读与实践指南
快速康复护理:现代医疗护理的新趋势
云南自驾游:怒江峡谷 vs 民国范儿,你Pick哪条线?
秋高气爽!云南自驾游最佳时机揭秘
大理丽江香格里拉,自驾游打卡最美路线!
云南自驾游必备:车辆检查与保养全攻略
伴侣改造计划:磨合还是折磨?