更新记录

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

两种模式互斥显示,避免聚合圆点与小区标签叠加。

网格聚合算法

  1. 根据当前 scale 计算网格步长 gridStep
    • scale ≥ 10 → 0.08°
    • scale ≥ 8 → 0.10°
    • 其他 → 0.14°
  2. 将每个小区的经纬度映射到网格 key:floor(lat/step)_floor(lng/step)
  3. 同一网格内的小区合并为一个聚合点,位置取几何中心
  4. 聚合数字 = 该区域内小区个数(非房间总数)

四档配色(聚合圆点)

按聚合区域内小区个数分档:

档位 小区数 颜色 圆点尺寸
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

接入真实接口

  1. 将接口返回的小区列表转为组件要求的 communities 格式
  2. 替换 getCommunityRooms 为接口请求(可在组件内改造或通过 community-select 事件在页面层处理)
  3. 通过 @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

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

暂无用户评论。