type
status
date
slug
summary
tags
category
icon
password
Edited
Oct 19, 2024 03:14 AM
Created
Oct 10, 2024 06:59 AM
对于百度地图的基本使用的话,可以看一下其官方文档, 本文着重讲解关于
Marker
标注的使用以及点聚合并结合到地图各省的聚合实现 。这里会使用到
react-bmapgl
这个库,其是百度地图的 React 封装库,详细使用可以参考其官方文档 。 使用方式和 API 基本和原生一致,只是将控件转换成了组件以及 API 转换成了属性,内部最终还是调用原生的 API 实现。
最终实现效果展示:
前置
先从简单的开始,先看看最简单的
Marker
使用。数据如下,包括一些基本信息:经纬度、省份代码、名称;后续都会使用该数据进行 Marker 操作。
再来看看地图组件的实现
效果如下:
Map 组件上的 API 属性可以参考以下链接的类参考:
点聚合方案
接下来,我们来看看点聚合。
百度地图本身是不支持点聚合功能的,这里的实现来自扩展内容;我找到了两种实现方式,可以分为两类,简单使用和复杂使用。
MarkerClusterer(简单使用)
官方 Demo:
类参考:
这种方式,只是简单的实现点聚合,或者是解决加载大量点要素到地图上产生覆盖现象的问题,并提高性能。
这个在网上有很多实现,并利用它去修改源码实现的一些参考。
但是,这种方式的可扩展性很大,它只有两个源文件,完全可以下下来自行修改其内容,根据自己的需求去调整,但整体来说,过于复杂,只适合简单使用。
@bmapgl-plugin/cluster
(复杂使用)
官方 Demo:
这种方式的配置相对来说比较复杂,但功能齐全。
这个我没咋在网上看到使用的方式,好不容易才找到的一个 Demo。文档也没有找到,最后在 npm 上找到该库的一个简单示例。
我拿 Demo 中的实现简单做个说明:
着重来看一下后面四个属性,一个个来详细分析一下:
clusterType
[minZoom, maxZoom, type, other]
通过 Demo 其实也可以看出来,在不同的放大系数下,呈现的聚合效果是不一样的。
[3, 11, Cluster.ClusterType.ATTR_REF, 'city']
拿这个解释:在放大系数为 3~11 之间的时候,聚合类型为 ATTR_REF
,也就是点位上面的属性进行判断,后面跟着的就是进行聚合分类的属性 city
。同理,
[13, null, Cluster.ClusterType.DIS_PIXEL, 64]
就是 13~∞ 放大系数下,根据距离进行聚合。同时,也可以看到在聚合范围之外的一个 Marker 显示为原本的 Marker 了。
getHTMLDOM
的话,就是对实际渲染 DOM 的样式操作,下面在实际案例中再具体讲解。
pointTransformer
就是将数据转换成 Cluster 能识别的数据。
新版地图主题
这里额外说明一下,如何在百度地图中修改其主题,可以看这个文档
将其主题的 JSON 文件给下载下来。
然后在代码中进行绑定即可:
实践
接下来,我们把使用
@bmapgl-plugin/cluster
来完成点聚合操作。因为
@bmapgl-plugin/cluster
的原因,我们再使用组件的方式去添加 Marker 了。所以只能在初始化的时候去做了。
简单示例:
效果如下:
省份划分
接下来,我们来实现按省份进行点聚合。
要实现这种方式,首先,我们需要把
clusterMinPoints
设为 1,因为这时候我们不是通过点之间的位置差来聚合了,而是需要根据放大比例在进行判断了。这里就需要用到之前提到的 clusterType
了。以一开始提供的
markerList
为例,将他进行省级划分。忘了里面参数含义的可以向上再看一下。
[9, null, Cluster.ClusterType.DIS_PIXEL, 0]
这里是对9以后的放大系数不做聚合处理,这样聚合节点实际上就是一个个 Marker
,只是被包装成了 Cluster
。接着,再重写一下
Cluster
的 DOM,显示出对应的省份信息。利用
renderClusterStyle
重写 DOM 渲染逻辑。getHTMLDOM
会提供一个当前 Cluster 的 context
,能获取聚合的一些相关信息。然后根据提供的信息,返回一个 DOM 即可。
province
省份名词在文章结尾提供。
这里要注意一下,我们需要把之前的
clusterMinPoints
变为 1,因为现在是按照省份划分,一个点也要显示,只有放大到一定系数后,才现在最终点位。效果如下:
但这里会有一个问题,就是需要将
clusterMinPoints
设为 1 了,但都是聚合节点了,那怎么找到 Cluster
对应的 Marker
呢。可以利用前面进行分级的
ClusterType
进行判断,是省份的聚合点还是改还原回去。那么剩下了的就是大于9(放大系数)的Cluster,其对应一个 Marker。
这里如果做额外的聚合处理的话,其实也可以,如[9, null, Cluster.ClusterType.DIS_PIXEL, 64]
那么就需要在下面的getHTMLDOM
中,除了对以上两个clusterType
做处理的前提下,还需要多判断一个放大系数大于9以后的聚合数量,确定Cluster
里面包含几个Marker
,再做对应处理。
现在只需要处理一个问题,就是如何获取
Cluster
下对应的 Marker
。Cluster
内部提供了两个方法:但是,没有说明文档,经过测试的结果来看,是
父Cluster
获取 子Cluster
的,没办法获取到 Cluster
下的 Marker
。所以,后面就只能通过最暴力的方式,进行经纬度匹配,得出对应的
Marker
。结合上面的,修改
getHTMLDOM
:效果如下:
对于 DOM 中
Cluster
和 Marker
的样式,不给具体的代码了,可以根据自身的需求去设计,也就是简单的 HTML + CSS 操作。矫正省份显示位置
还有个属性,我们还没讲:
clusterDictionary
,用来修改 Cluster
显示位置。我们需要根据省份进行设置,所以,我们需要获取所有省份经纬度的信息。
我们只需要对
ClusterType.ATTR_REF
做处理,函数会给一个 type
和 key
(provinceCode
)来进行后续判断。provinceWithCenter
省份中心经纬度在文章结尾提供。
省份数据
省份代码
省份中心经纬度
到这里,地图整体的功能就差不多了。
如果像对 Marker 做事件操作的话,可以通过 cluster 提供的方法:
比如点击跳出弹窗,跳转等等操作…
更多在地图上的绘制操作,可以看这个文档
- 作者:JinSo
- 链接:https://jinso365.top/article/11bcee95-0faf-805e-905c-e15eb7415194
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。