更新记录
1.0.0(2026-06-15) 下载此版本
基于 uni-app 的地图点聚合方案,支持 H5(Web) 与 微信小程序。放大地图后展示小区胶囊标签,缩小后自动聚合为四色圆点,点击可查看聚合区域内的小区列表或单个小区的房间信息。
平台兼容性
小区地图 · 点聚合组件
基于 uni-app 的地图点聚合方案,支持 H5(Web) 与 微信小程序。放大地图后展示小区胶囊标签,缩小后自动聚合为四色圆点,点击可查看聚合区域内的小区列表或单个小区的房间信息。
功能概览
| 功能 | 说明 |
|---|---|
| 点聚合 | 缩放级别 < 15 时,按网格将邻近小区合并为聚合圆点 |
| 小区标签 | 缩放级别 ≥ 15 时,展示白底胶囊 小区名 (房间数) |
| 四档配色 | 蓝 / 绿 / 橙 / 红,圆点大小与颜色随聚合内小区数量变化 |
| 点击交互 | 点击聚合点 → 小区列表;点击小区标签 → 房间列表 |
| 性能优化 | 视野裁剪、结果缓存、防抖刷新、房间懒加载 |
| 跨端适配 | H5 滚轮缩放;小程序自定义顶栏、缩放回弹修复 |
平台支持
| 平台 | 状态 | 说明 |
|---|---|---|
| H5(Web) | ✅ | 需配置腾讯地图 Key;支持鼠标滚轮缩放 |
| 微信小程序 | ✅ | 需配置 appid 与定位权限;内置顶栏避开胶囊按钮 |
| App | ⚠️ | 已预留地图模块,需自行打包验证 |
快速开始
1. 环境要求
- HBuilderX 或 uni-app CLI
- Node.js(仅生成聚合图标时需要)
2. 地图 Key 配置
在 manifest.json 中配置腾讯地图 Key(H5 与 App 必需):
"h5": {
"sdkConfigs": {
"maps": {
"tencent": {
"key": "你的腾讯地图Key"
}
}
}
}
微信小程序使用原生 <map> 组件,无需额外地图 Key,但需在 manifest.json → mp-weixin 填写 appid,并开启定位权限说明。
3. 运行项目
| 目标平台 | 操作 |
|---|---|
| H5 | HBuilderX → 运行 → 运行到浏览器 |
| 微信小程序 | HBuilderX → 运行 → 运行到小程序模拟器 → 微信开发者工具 |
4. 生成聚合图标(首次或修改样式后)
聚合圆点使用预渲染 PNG 图标(1–99 数字),执行:
npm run gen:markers
输出目录:static/markers/nums/
组件使用
地图功能封装在 components/community-map/community-map.vue,页面只需传入数据即可。
<template>
<view class="page">
<community-map
title="小区地图"
:communities="communities"
:center="center"
/>
</view>
</template>
<script>
import { BEIJING_CENTER, communities } from '@/data/beijing-communities.js'
import CommunityMap from '@/components/community-map/community-map.vue'
export default {
components: { CommunityMap },
data() {
return {
communities,
center: BEIJING_CENTER
}
}
}
</script>
<style scoped>
.page {
width: 100%;
height: 100vh;
overflow: hidden;
}
</style>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
title |
String | 小区地图 |
小程序顶部标题 |
communities |
Array | [] |
小区数据列表 |
center |
Object | 北京中心 | { latitude, longitude, name? } |
initialScale |
Number | 10 |
初始缩放级别(5–18) |
minScale |
Number | 5 |
最小缩放 |
maxScale |
Number | 18 |
最大缩放 |
mapId |
String | communityMap |
地图实例 ID,多实例时须唯一 |
showNavbar |
Boolean | true |
是否显示小程序顶栏 |
showLegend |
Boolean | true |
是否显示四档图例 |
showLocate |
Boolean | true |
是否显示定位按钮 |
showZoomControls |
Boolean | true |
是否显示 ± 缩放按钮 |
showTip |
Boolean | true |
小区模式下是否显示底部提示 |
tipText |
String | 点击小区标签查看房间 |
底部提示文案 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
community-select |
community |
选中某个小区(含 rooms) |
cluster-select |
cluster |
选中某个聚合区域 |
panel-close |
— | 关闭底部面板 |
scale-change |
scale |
缩放级别变化 |
mode-change |
'cluster' \| 'community' |
显示模式切换 |
小区数据格式
{
id: 1, // 唯一 ID,用作 marker id
name: '阳光花园朝阳1期',
district: '朝阳区',
address: '北京市朝阳区12号',
latitude: 39.9219,
longitude: 116.4435,
roomCount: 120 // 房间总数(用于标签展示与配色)
}
房间数据通过 getCommunityRooms(community) 按需生成,无需预置在 communities 中。
点聚合原理
显示模式切换
缩放级别 scale
│
├─ scale < 15 → cluster 模式(仅聚合圆点)
│
└─ scale ≥ 15 → community 模式(仅小区胶囊标签)
阈值定义在 utils/map-cluster.js:
export const ZOOM_COMMUNITY_THRESHOLD = 15
两种模式互斥显示,避免聚合圆点与小区标签叠加。
网格聚合算法
- 根据当前
scale计算网格步长gridStep:- scale ≥ 10 → 0.08°
- scale ≥ 8 → 0.10°
- 其他 → 0.14°
- 将每个小区的经纬度映射到网格 key:
floor(lat/step)_floor(lng/step) - 同一网格内的小区合并为一个聚合点,位置取几何中心
- 聚合数字 = 该区域内小区个数(非房间总数)
四档配色(聚合圆点)
按聚合区域内小区个数分档:
| 档位 | 小区数 | 颜色 | 圆点尺寸 |
|---|---|---|---|
| 蓝 | 1–4 | #5AB4FF |
44px |
| 绿 | 5–8 | #2ECC71 |
50px |
| 橙 | 9–12 | #FF9F43 |
56px |
| 红 | 13+ | #FF5252 |
62px |
配置位于 utils/marker-tier.js,图标由 scripts/generate-markers.js 预渲染生成。
小区胶囊标签
放大后每个小区显示为白底圆角标签:小区名 (房间数)
- 使用
label而非callout(H5 上 callout 点击不触发markertap) - 文字颜色按房间数四档配色(与聚合分档规则相同)
交互说明
| 操作 | 聚合模式 | 小区模式 |
|---|---|---|
| 双指/滚轮缩放 | 切换聚合密度 | 切换为聚合或继续放大 |
| 拖动地图 | 不刷新 marker(性能优化) | 刷新视野内 marker |
| 点击聚合圆点 | 弹出聚合区域小区列表 | — |
| 点击小区标签 | — | 弹出房间列表 |
| 点击定位按钮 | 回到初始中心与缩放级别 | 同左 |
| 点击 ± 按钮 | 手动缩放 | 同左 |
拖动或缩放过程中不会触发 marker 点击,避免误触。
性能优化
| 策略 | 说明 |
|---|---|
| 视野裁剪 | 小区模式下仅渲染当前视野内 marker,最多 120 个 |
| 距离优先 | 超出上限时按与地图中心距离排序,优先显示最近的小区 |
| 结果缓存 | 相同模式 + 缩放 + 视野的 marker 结果缓存,最多 24 条 |
| 防抖刷新 | marker 更新延迟 120ms,减少频繁重绘 |
| 房间懒加载 | 点击小区时才生成房间列表,带内存缓存 |
| 聚合模式拖动 | 拖动时不重新计算聚合点 |
相关常量(utils/map-perf.js):
MAX_COMMUNITY_MARKERS = 120 // 单屏小区 marker 上限
MAX_CLUSTER_LIST = 80 // 聚合面板列表上限
项目结构
nny-map/
├── components/
│ └── community-map/
│ └── community-map.vue # 地图组件(UI + 交互 + 生命周期)
├── data/
│ └── beijing-communities.js # Mock 数据与房间懒加载
├── utils/
│ ├── map-cluster.js # 点聚合核心逻辑
│ ├── marker-style.js # marker / label 样式
│ ├── marker-tier.js # 四档配色规则
│ ├── map-perf.js # 视野裁剪与性能常量
│ └── map-scale-watcher.js # H5 缩放轮询(仅 Web)
├── static/markers/
│ ├── anchor.png # 小区 invisible 锚点图标
│ └── nums/ # 聚合圆点 1–99.png
├── scripts/
│ └── generate-markers.js # 聚合图标生成脚本
└── pages/index/index.vue # 示例页面
平台差异说明
H5(Web)
- 使用腾讯地图 JS SDK,须在
manifest.json → h5.sdkConfigs.maps.tencent配置 Key - 支持鼠标滚轮缩放(组件内监听
wheel事件) - 使用
createScaleWatcher轮询缩放级别,辅助检测滚轮缩放 - 无系统顶栏,
legend使用safe-area-inset-top适配刘海屏
微信小程序
- 使用原生
<map>组件 pages.json设置navigationStyle: "custom",组件内自动计算状态栏 + 胶囊高度- 缩放回弹修复:手势缩放时只更新内部
currentScale,不回写:scale绑定;仅按钮/定位操作才同步绑定属性 - 小程序不使用缩放轮询,仅依赖
@regionchange事件 - 页面设置
disableScroll: true,防止页面滚动干扰地图手势 - 监听
@markertap/@labeltap响应点击
自定义与扩展
调整 mock 数据量
修改 data/beijing-communities.js:
export const MOCK_COMMUNITY_COUNT = 180 // 改为你需要的数量
修改聚合阈值
修改 utils/map-cluster.js:
export const ZOOM_COMMUNITY_THRESHOLD = 15 // 调大 = 更晚显示小区标签
修改四档配色
编辑 utils/marker-tier.js 中的 CLUSTER_COUNT_TIERS,然后重新执行:
npm run gen:markers
接入真实接口
- 将接口返回的小区列表转为组件要求的
communities格式 - 替换
getCommunityRooms为接口请求(可在组件内改造或通过community-select事件在页面层处理) - 通过
@community-select/@cluster-select监听用户操作,对接业务逻辑
常见问题
H5 地图空白
检查 manifest.json 中腾讯地图 Key 是否正确,且 Key 已开通 Web 端(JavaScript API) 权限。
小程序缩放后地图弹回去
已通过「绑定属性与内部状态分离」修复。若仍出现,确认未在 regionchange 中手动写回 :latitude / :longitude / :scale。
点击小区标签无反应
- 小区模式使用
label展示,需监听@labeltap(组件已处理) - 缩放后 150ms 内的点击会被忽略,防止误触
聚合图标显示异常
重新生成图标:npm run gen:markers,确保 static/markers/nums/ 下存在 1.png ~ 99.png。
图例被顶部遮挡(小程序)
组件已根据胶囊按钮位置计算 topInset,图例自动下移到导航栏下方。可通过 showNavbar 控制顶栏显示。
技术栈
- uni-app(Vue 3)
- 腾讯地图(H5 SDK / 小程序原生 map)
- Canvas 预渲染聚合图标
License
ISC

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 6
赞赏 0
下载 12250236
赞赏 1922
赞赏
京公网安备:11010802035340号