-
2021-09-23 13:56:22
接上一篇文章写到的百度地图基础功能, 本次聚合点功能基于上一篇的添加覆盖物, 不懂的可以先看看本人上一篇文章, 传送门2021-09-23 最全的百度地图API使用基础JS_m0_49031950的博客-CSDN博客1
1. 在引入百度地图的基础上, 再引入聚合点的包
<script type="text/javascript" src="https://api.map.baidu.com/library/TextIconOverlay/1.2/src/TextIconOverlay_min.js"></script> <script type="text/javascript" src="https://api.map.baidu.com/library/MarkerClusterer/1.2/src/MarkerClusterer_min.js"></script>
2.在覆盖物基础上, 添加聚合点代码
// 1.添加一个聚合点存放数组 var markersArr = [] this.setDate.map((item) => { marker = new BMapGL.Marker(new BMapGL.Point(经纬度1, 经纬度2, 经纬度3), { icon: myIcon, offset: { width: 0, height: 0 }, }); map.addOverlay(marker); markersArr.push(marker) // 2.存放聚合点 }); // 3.重点!!! 聚合代码主要就是以下这句 this.markerClusterer=new window.BMapLib.MarkerClusterer(map, {markers:markersArr});
在学会了基础的功能后, 加入聚合点的功能是非常简单的, 只是这个聚合样式调整目前我尝试还没有生效, 但基础功能已经满足目前开发所需, 有懂的大佬麻烦指点一二~
这次聚合功能主要参考以下大佬的文章,写得很详细↓百度地图聚合点new BMapLib.MarkerClusterer()用法及map.clearOverlays()不能清除聚合点问题_lianzhang861的博客-CSDN博客
感谢大佬们的分享!~~拜了个拜~
更多相关内容 -
百度地图 聚合点 优化源码
2018-10-10 10:23:25关于开发中基于百度地图做开发,添加maker标记点,官方提供的源码在pc端添加上千个点,页面拖动会出现卡顿,页面加载也会很慢,优化过的源码,本人亲测上万marker也还可以。 -
Android-Android百度地图聚合
2019-08-13 04:45:30Android百度地图聚合 -
高德地图聚合Marker
2016-12-17 17:31:22最近写一个关于高德地图Marker聚合的小项目,在网上找了很多,有很多大神已经写了很多demo,于是下载下来看了代码,但没有我想要的效果(但很有帮助)。主要是想实现(1)地图支持Marker刷新,而刷新后替换掉没用了... -
百度地图聚合标记,数量多会卡,优化版MarkerClusterer_min.js
2019-01-09 18:22:13调用百度地图聚合标记,数量大于1000的话,会很卡,但是引用此优化版MarkerClusterer_min.js,立刻就不卡了 -
ArcGIS APi结合天地图聚合效果的数据
2018-06-27 16:38:35该资源主要是ArcGIS API For JS结合天地图的加载并且并且实现散点聚合 -
android高德地图聚合demo
2018-02-02 13:15:26android版本高德地图聚合demo,实现自定义点聚合功能。 -
获取百度地图聚合点下面的相同数据
2020-05-08 17:26:50通过点击百度聚合点markerClusterer的时候画一个圆,然后判断重复的数据点是否在圆里面,然后获取重复的点的数据 -
谷歌地图 聚合marker例子
2014-08-19 11:18:27谷歌地图 大批量打点marker 聚合打点 例子,可以参考,国内可以打开。 -
地图点聚合
2018-12-24 13:35:45之前在项目中需要用到百度地图的点聚合,看了百度提供的demo之后,稍微读了一些源码就能达到需求了,所以并未深入解读源码。 最近有空就把百度实现点聚合的源码从里到外仔细研究了一遍受益良多,在此分享一下。 -
实现百度地图聚合抽稀
2021-04-04 05:23:08这是实现百度地图聚合抽稀,地图聚合抽稀,基于百度地图SDK3.1.1,做项目的时候碰到了一个问题,地图上的点过于密集,用户体验不好。所以找到了该方法解决,代码参考了网上的代码,那个版本比较老。 我基于百度地图3... -
MarkerClusterer_min.js,TextIconOverlay_min.js 百度地图聚合功能开发
2020-11-28 10:32:45MarkerClusterer_min.js,TextIconOverlay_min.js 百度地图聚合自定义聚合点样式必备js , 亲测可用, 刚实现相关功能 -
百度地图点聚合分区域聚合
2018-10-18 14:03:46百度地图,点聚合、点点击事件、聚合点击事件、分区域聚合 -
说一说Android的地图聚合
2021-06-02 21:13:28国际惯例,先上黄图:cluster.gif首先说说什么是聚合,如果你不怎么用地图的话,可能对聚合这个东西几乎没什么概念,聚合呢,其实就是将地图上过于密集的覆盖物集合到一块,当地图舒展开了,集合中的覆盖物又会分布...最近遇到一个需求,其中涉及到一些聚合的东西,给大家说说我的不成熟的小想法。国际惯例,先上黄图:
cluster.gif
首先说说什么是聚合,如果你不怎么用地图的话,可能对聚合这个东西几乎没什么概念,聚合呢,其实就是将地图上过于密集的覆盖物集合到一块,当地图舒展开了,集合中的覆盖物又会分布开,就是这么个效果。
再来说说为什么要聚合,说到底就是让交互变得更友善,没聚合之前,图上总共1400多个点,不能想象密集恐惧症的人看了会有什么感觉,反正我自己看着也毛毛的;再一个呢,这么多的点,图片加载渲染的时候难免会卡顿,聚合之后的话,会有效减少卡顿的现象。
其实在我用过的地图中,官方实现了聚合功能的只有百度地图,其他都得自己来实现了,OK,进入我们的正题,到底如何实现聚合呢?
说下我写的两种聚合的方法:
第一种:以地图上的某个点作为聚合点,以这个点的坐标为中心点,创建出一个Rect,再去计算在这个Rect中是否包含了其他的点,如果包含了,这些个点就合体成为了一个聚合点。
98ED363C-B79E-4B2D-ADCF-8B0EA0F15D24.png
好了,我们来写一个聚合类:
public class Cluster {
//聚合大小控制,就是控制Rect的宽高
private int bounds;
private PointF f;
private MapView mapView;
private List ps = new ArrayList();//用来存储该聚合内有多少个覆盖物,就是地图上的Overlay
public Cluster() {}
//新建的时候会扔一个覆盖物进来,如果没有聚合产生那么这个聚合就是原来的覆盖物
public Cluster(PointF f, MapView mapView, int bounds) {
this.f = f;
this.mapView = mapView;
this.bounds = bounds;
ps.add(f);
}
//返回一个方形的范围区域,用作判定聚合
public Rect getRect() {
float x = f.x;
float y = f.y;
//将地图的坐标转换成屏幕的坐标
float[] floats = mapView.convertMapXYToScreenXY1(x, y);
Rect rect = new Rect((int) floats[0], (int) floats[1], (int) (floats[0] + bounds), (int) (floats[1] + bounds));
return rect;
}
//如果被判定在聚合内,那么就将这个点加入聚合类中的集合
public void addPoints(PointF p) {
ps.add(p);
}
//当所有的覆盖物聚合计算完成后,次方法返回聚合的坐标
public PointF getPosition(){
if (ps.size() == 1) {
return f;
}
float x = 0;
float y = 0;
for (PointF p : ps) {
x += p.x;
y += p.y;
}
x = x / ps.size();
y = y / ps.size();
return new PointF(x,y);
}
}
接下来聚合的算法:
public void getCluster() {
clusters.clear();
newPoints.clear();
//遍历地图上所有的覆盖物进行聚合操作
for (PointF mark : marks) {
float[] floats1 = mapView.convertMapXYToScreenXY1(mark.x, mark.y);//地图上的点转换成屏幕坐标点
int width = mapView.getWidth();
int height = mapView.getHeight();
//计算出屏幕中的点,不在屏幕中的不用聚合
if (floats1[0] < 0 || floats1[1] < 0 || floats1[0] > width || floats1[1] > height) {
continue;
}
boolean isIn = false;//是否已经聚合
//如果没有的话就先创建一个聚合类扔进去
if (clusters.size() == 0) {
clusters.add(new Cluster(mark, mapView, 100));
} else {//有了聚合类就开始计算点是否在聚合内
for (Cluster cluster : clusters) {
float[] floats = mapView.convertMapXYToScreenXY1(mark.x, mark.y);
boolean isContian = cluster.getRect().contains((int) floats[0], (int) floats[1]);//是否在聚合内
if (isContian) {
cluster.addPoints(mark);
isIn = true;
break;
}
}
//如果不在那几个聚合点内的话,重新添加到一个新的聚合类中去
if (!isIn) {
clusters.add(new Cluster(mark, mapView, bounds));
}
}
}
//将聚合中的重新计算取出
for (Cluster cluster : clusters) {
newPoints.add(new PointF(cluster.getPosition().x,cluster.getPosition().y));
}
}
注释应该写的挺清楚的,还是那句话,写代码之前多想想你要什么,就往这个聚合类中添加什么,慢慢的这个类就会越来越健壮。
接下来第二种方法:
将整个屏幕分成N个Rect,分别计算在某个Rect中有多少个覆盖物,如果多于一个覆盖物的话,那么这个就是聚合,否则,就是一个覆盖物。
203BDB66-3DD2-4288-8456-EFEF14AA58B2.png
再来个聚合类:
public class MCluster {
public boolean isClick() {
return isClick;
}
public void setClick(boolean click) {
isClick = click;
}
private boolean isClick;//是否可以点击
private String PntName;
private String Unit;
private float Value;
public String getPntName() {
return PntName;
}
public void setPntName(String pntName) {
PntName = pntName;
}
public String getUnit() {
return Unit;
}
public void setUnit(String unit) {
Unit = unit;
}
public float getValue() {
return Value;
}
public void setValue(float value) {
Value = value;
}
//覆盖物集合
private List ps = new ArrayList();
private Rect rect;
public MCluster() {
}
public MCluster(Rect rect) {
this.rect = rect;
}
public void addPoint(PointF pointF){
ps.add(pointF);
}
//将集合清空
public void clear(){
ps.clear();
}
public Rect getRect(){
return rect;
}
//看这个聚合内是否有覆盖物
public boolean hasPoint(){
if (ps.size() == 0) {
return false;
}
return true;
}
//判断是否是聚合,如果集合中点数大于1说明是聚合了,否则不聚合
public boolean isCluster(){
if (ps.size() == 1) {
return false;
}
return true;
}
//计算坐标
public MyPoint getPosition(){
float x = 0;
float y = 0;
for (PointF p : ps) {
x += p.x;
y += p.y;
}
x = x / ps.size();
y = y / ps.size();
MyPoint myPoint = new MyPoint(x, y,isCluster(),PntName,Unit,Value,ps.size(),isClick());
return myPoint;
}
//得到聚合的数量
public int getSize(){
return ps.size();
}
}
其实大同小异。
划分聚合:
private void makeCluster() {
//以320像素密度为基础设置Rect的宽高为50像素
float base = 320;
int width1 = (int) SPUtils.get(mapView.getContext(), "width", -1);//屏幕的宽
int height1 = (int) SPUtils.get(mapView.getContext(), "height", -1);//屏幕的高
int density = (int) SPUtils.get(mapView.getContext(), "density", -1);//屏幕的像素密度
float scale = (density/base);
final float width = 50*scale;//Rect的宽高
int round = Math.round(width);
final int h = height1/round;
final int w = width1 / round;
//将屏幕划分成N个聚合区
for (int j = 0; j < h+1; j++) {
for (int i = 0; i < (w + 1); i++) {
mClusters.add(new MCluster( new Rect(i * round,j * round,i * round + round,j * round + round)));
}
}
}
接着看聚合的算法:
public void getNewCluster(){
//遍历所有的覆盖物
for (Points mark : marks) {
PointF pointF = mark.getPointF();
if (pointF == null) {
return;
}
float[] floats1 = mapView.convertMapXYToScreenXY1(pointF.x, pointF.y);//地图上的点转换成屏幕坐标点
int x = (int) floats1[0];
int y = (int) floats1[1];
int width = mapView.getWidth();
int height = mapView.getHeight();
//计算出屏幕中的点,不在屏幕中的不用聚合
if (x< 0 || y < 0 || x > width || y > height) {
continue;
}
//遍历所有的聚合
for (MCluster mCluster : mClusters) {
Rect rect = mCluster.getRect();
//在聚合内
if (rect.contains(x, y)) {
mCluster.addPoint(pointF);
mCluster.setClick(mark.isClick());
mCluster.setPntName(mark.getPntName());
mCluster.setUnit(mark.getUnit());
mCluster.setValue(mark.getValue());
break;
}
}
}
newPoints.clear();
for (MCluster mCluster : mClusters) {
if (mCluster.hasPoint()) {
newPoints.add(mCluster.getPosition());
}
}
//将聚合中的数据清除
for (MCluster mCluster : mClusters) {
mCluster.clear();
}
}
以上,哪里说的不对欢迎指正
-
高德地图自定义点聚合图片
2019-04-26 17:40:34Android 高德地图自定义点聚合marker图片及Overlay点击选中功能的代码实现及布局文件 -
一种简单的地图聚合算法
2019-01-04 17:48:34百度地图的聚合算法 这段百度算法的描述来自博客:https://blog.csdn.net/javine/article/details/51195014 总结如下: 百度地图把整个地球是按照一个平面来展开,把整个地球按照平面来展开之后,我们就能算出这个...百度地图的聚合算法
这段百度算法的描述来自博客:https://blog.csdn.net/javine/article/details/51195014
总结如下:
百度地图把整个地球是按照一个平面来展开,把整个地球按照平面来展开之后,我们就能算出这个地球平面的宽度,也就是世界宽度。
计算公式是这样的:256*(zoom^2) == worldWidth
其中zoom就是地图的层级,我们缩放地图也是根据zoom的变化来判断是放大还是缩小的。这样可以把不利于计算的经纬度position转换成我们熟悉的二维坐标point。
而一个二维坐标中有若干个点,把它们按照一个给定的distance来进行分组。
迭代所有的QuadItem,以此QuadItem为中心画一个框框,框框里面的点就算是一个cluster簇,
也就是可以聚合成一个点的QuadItems。框框的大小就是我们定义的可以执行聚合的距离。
当然,这话其实并不准确,会有些点同时被好多个框框给框住,那就算距离最小的那个cluster里面的点。/** * cluster算法核心 * @param zoom map的级别 * @return */ @Override public Set<? extends Cluster<T>> getClusters(double zoom) { final int discreteZoom = (int) zoom; final double zoomSpecificSpan = MAX_DISTANCE_AT_ZOOM / Math.pow(2, discreteZoom) / 256;//定义的可进行聚合的距离 final Set<QuadItem<T>> visitedCandidates = new HashSet<QuadItem<T>>(); //遍历QuadItem时保存被遍历过的Item final Set<Cluster<T>> results = new HashSet<Cluster<T>>(); //保存要返回的cluster簇,每个cluster中包含若干个MyItem对象 final Map<QuadItem<T>, Double> distanceToCluster = new HashMap<QuadItem<T>, Double>(); //Item --> 此Item与所属的cluster中心点的距离 final Map<QuadItem<T>, mapapi.clusterutil.clustering.algo.StaticCluster<T>> itemToCluster = new HashMap<QuadItem<T>, mapapi.clusterutil.clustering.algo.StaticCluster<T>>(); //Item对象 --> 此Item所属的cluster synchronized (mQuadTree) { for (QuadItem<T> candidate : mItems) {<span style="white-space:pre"> </span>//遍历所有的QuadItem if (visitedCandidates.contains(candidate)) {<span style="white-space:pre"> </span>//如果此Item已经被别的cluster框住了,就不再处理它 continue; } Bounds searchBounds = createBoundsFromSpan(candidate.getPoint(), zoomSpecificSpan);//这个就是我们说的,根据给定距离生成一个框框 Collection<QuadItem<T>> clusterItems; // search 某边界范围内的clusterItems clusterItems = mQuadTree.search(searchBounds); //从quadTree中搜索出框框内的点 if (clusterItems.size() == 1) { // 如果只有一个点,那么这一个点就是一个cluster,QuadItem也实现了Cluster接口,也可以当作Cluster对象 results.add(candidate); visitedCandidates.add(candidate); distanceToCluster.put(candidate, 0d); continue;<span style="white-space:pre"> </span>//并且结束此次循环 } mapapi.clusterutil.clustering.algo.StaticCluster<T> cluster = new mapapi.clusterutil.clustering.algo .StaticCluster<T>(candidate.mClusterItem.getPosition());//如果搜索到多个点,那么就以此item为中心创建一个cluster results.add(cluster); for (QuadItem<T> clusterItem : clusterItems) {<span style="white-space:pre"> </span>//遍历所有框住的点 Double existingDistance = distanceToCluster.get(clusterItem);//获取此item与原来的cluster中心的距离(如果之前已经被其他cluster给框住了) double distance = distanceSquared(clusterItem.getPoint(), candidate.getPoint());<span style="white-space:pre"> </span>//获取此item与现在这个cluster中心的距离 if (existingDistance != null) { // 判断那个距离跟小 if (existingDistance < distance) { continue; } //如果跟现在的cluster距离更近,则将此item从原来的cluster中移除 itemToCluster.get(clusterItem).remove(clusterItem.mClusterItem); } distanceToCluster.put(clusterItem, distance); //保存此item到cluster中心的距离 cluster.add(clusterItem.mClusterItem);<span style="white-space:pre"> </span>//将此item添加到cluster中 itemToCluster.put(clusterItem, cluster);<span style="white-space:pre"> </span>//建立item -- cluster 的map } visitedCandidates.addAll(clusterItems);//将所有框住过的点添加到已访问的List中。 } } return results; }
简化版的地图聚合算法
百度上面的聚合算法,基本上可以满足百分之九十九的需求。但是,经过测试,在一个很小的区域中密集聚合了1w个以上的点时,在android手机上就会出现内存溢出的情况。所以这时候就需要一个简单并且运算量较小的算法。
地图坐标化
虽然上面的算法不符合我们的要求,但是我们仍然可以获得一个思路,就是把地球展开成一个平面,将经纬度转换成我们熟识的xy二维坐标轴。
但是,为了节省移动端宝贵的内存和运算量,我们完全不需要建立整个世界的坐标系,而只需要建立我们手机屏幕所显示出来的地图的坐标系。如下图所示:
这样的建立坐标系以后,我们将屏幕的左下角看作0点,那么屏幕中任何一个点的相对坐标就是这个点的经纬度减去屏幕左下角那个点的经纬度。
点的聚合
在百度的算法中,可以看作会比较每两个点直接的距离。这样的话,画出来的聚合图虽然好看,但在数据量很大时,效率就比较低下。
所以我们如果对聚合的速度要求很高,但是聚合的效果要求不高的话。可以做这样一个处理。
我们将x轴分割为n份,y轴分割成m份。这样的话整个地图就会被分割成一个个的小方格,我们只需要计算每个方格中的包含的gps点数,即可。这样就完成了一个最基本的聚合。例如在上图中,我们将地图分割成了n*m份,天津所在的这个小方格内的聚合度就1,其他地方聚合度就是0。
如果这个时候我们在天津所在的这个方格内,再加一个点,这个方格的聚合度就变成了2。
现在点的数目增加多一点
我们来分割一下,横向三格,纵向6格
这样分割以后,出来的聚合效果就是
具体代码
mBaiduMap.setOnMapStatusChangeListener(new BaiduMap.OnMapStatusChangeListener() { @Override public void onMapStatusChangeStart(MapStatus mapStatus) { } @Override public void onMapStatusChangeStart(MapStatus mapStatus, int i) { } @Override public void onMapStatusChange(MapStatus mapStatus) { } @Override public void onMapStatusChangeFinish(MapStatus mapStatus) { try{ //清楚地图上的marker mBaiduMap.clear(); //左上角经纬度 Point pt = new Point(); pt.x = 0; pt.y = 0; LatLng llLeftTop = mBaiduMap.getProjection().fromScreenLocation(pt); //右下角经纬度 Point pty = new Point(); pty.x = mMapView.getWidth(); pty.y = mMapView.getHeight(); LatLng llRightBottom = mBaiduMap.getProjection().fromScreenLocation(pty); //屏幕中显示的经度的长度和纬度的长度 double mapWidth = llRightBottom.longitude - llLeftTop.longitude; double mapHeight = llLeftTop.latitude - llRightBottom.latitude; //将屏幕中地图分割的横向 格子数和 纵向格子数 int widthSize = 10; int heightSize = 20; //计算每个格子的经纬度的长度 double unitWidth = mapWidth / widthSize; double unitHeight = mapHeight / heightSize; //用来保存每个格子里面的点的数量 int[] pointSize = new int[widthSize * heightSize]; //计算每个分隔点内gps点的数量 for (MyItem b : myItemList) { LatLng latLng=b.getPosition(); //如果点在显示范围内 if (latLng.longitude > llLeftTop.longitude && latLng.longitude < llRightBottom.longitude && latLng.latitude > llRightBottom.latitude && latLng.latitude < llLeftTop.latitude) { //计算每个点,相对于左下角的经纬度 double relativeX = latLng.longitude - llLeftTop.longitude; double relativeY = latLng.latitude - llRightBottom.latitude; //计算出这个点,处于哪个格子 int x = (int) Math.floor(relativeX / unitWidth); int y = (int) Math.floor(relativeY / unitHeight); if (x < 0 || y < 0) { // LogUtil.e("relativeX:" + relativeX + "---------relativeY:" + relativeY); } pointSize[y * widthSize + x] = pointSize[y * widthSize + x] + 1; } } List<OverlayOptions> options = new ArrayList<OverlayOptions>(); //设置坐标点 BitmapDescriptor bitmap; //绘制每个格子和格子里点的数量 for (int y = 0; y < heightSize; y++) { for (int x = 0; x < widthSize; x++) { double lng = llLeftTop.longitude + x * unitWidth; double lat = llRightBottom.latitude + y * unitHeight; //如果格子里点的数量为0 ,则不绘制 if (pointSize[y * widthSize + x] == 0) { continue; } TextView textView = new TextView(MarkerClusterDemo.this); textView.setBackgroundColor(getResources().getColor(android.R.color.holo_red_light)); textView.setText(pointSize[y * widthSize + x] + ""); bitmap = BitmapDescriptorFactory.fromView(textView); LatLng point = new LatLng(lat, lng); OverlayOptions option1 = new MarkerOptions() .position(point) .icon(bitmap); options.add(option1); } } //在地图上批量添加 mBaiduMap.addOverlays(options); }catch (Exception e){ e.printStackTrace(); } }
-
高德地图 聚合效果
2020-11-22 13:37:54最近项目中遇到用高德制作地图,针对聚合的效果,将一下实现的一些思路。 高德的聚合使用的是AMap.MarkerClusterer,详细的参数设置和说明,可以参考官网的api,这边只根据自己的需求,贴上部分代码 效果:...最近项目中遇到用高德制作地图,针对聚合的效果,将一下实现的一些思路。
高德的聚合使用的是AMap.MarkerClusterer,详细的参数设置和说明,可以参考官网的api,这边只根据自己的需求,贴上部分代码效果:https://kaixin51.github.io/other/cluster.html
需求:在很小的层级时,需要聚合元素,显示这个图标中有多少个元素,单一元素的时候显示该元素,并根据是否预警设置闪烁的效果。
其中高德的闪烁效果实现大致有以下几种方式
1.用Marker的content 自定义一个闪烁效果
2.直接一个gif的图片做闪烁小狗
3.一个定时器自主控制闪烁
4.canvasLayer 去设计一个闪烁图层
这边打算用Marker的content属性来实现,因为聚合图层返回的对象就是一个个的Marker,所以考虑到方案的简便性还是选择了content下面贴上代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="text/javascript" src="https://webapi.amap.com/maps?v=2.0&key=你自己的高德key&plugin=AMap.GeoJSON"></script> <script type="text/javascript" src="js/jquery.3.5.1.js"></script> </head> <body> <div id="map" style="width: 100%;height:500px;"></div> </body> <script> var map = new AMap.Map('map', { zoom: 16,//级别 center: [119.9494600, 29.3449200],//中心点坐标 viewMode: '2D'//使用3D视图 }); let clusterLayer; $.ajax({ url: 'json/pool.json', //这里就是一组接口返回的数据对象,{status:0,message:[{longitude:121,latitude:31,projectName:'项目名称'}]} type: 'get', dataType: 'json', success: function (result) { if (result.status === 0) { let markers = []; result.message.forEach(element => { if (element.longitude && element.latitude) { markers.push({ lnglat: [element.longitude, element.latitude], // 点的经纬度 weight: 1, //权重高的将作为聚合的中心点 entity: element }) } }) let icon = 'image/三角形.png' let markerClusterOption = { gridSize: 100,// 聚合像素 maxZoom: 16, //当大到该层级后不再聚合 renderClusterMarker: function (data) { // 聚合点样式设置 data.marker.setIcon(icon) if (data.count > 1) { data.marker.setLabel({ content: data.count, direction: "right", // 在 direction 基础上的偏移量 offset: [-20, -30] }) } return data.marker }, renderMarker: function (data) { // 非聚合点样式 // 高德聚合图层中 非聚合点默认 setAnchor:top-left offset并不是(0,0)而是根据图片设置了一个特定的偏移,出现定位点不准确,请自行根据图片调整offset data.marker.setIcon(icon) if (data.data[0].entity.projectName === '测试1') { // console.log(data.marker) data.marker.setAnchor('top-left') // Anchor和offset 最好设置一下,不然点不在对应的位置,出现偏移 data.marker.setOffset(new AMap.Pixel(0, -16)) data.marker.setContent('<div class="marker-route"><div class="marker-title">' + data.data[0].entity.projectName + '</div><div><img class="breath_light" src="' + icon + '"/></div></div>') console.log(data.marker) } else { data.marker.setAnchor('top-left') // Anchor和offset 最好设置一下,不然点不在对应的位置,出现偏移 data.marker.setOffset(new AMap.Pixel(0, 0)) data.marker.setLabel({ content: data.data[0].entity.projectName, direction: "right", // 在 direction 基础上的偏移量 offset: [-20, -30] }) } data.marker.setExtData(data.data[0].entity) return data.marker } } map.plugin(["AMap.MarkerClusterer"], function () { clusterLayer = new AMap.MarkerClusterer(map, markers, markerClusterOption); }); // var marker = new AMap.Marker({ // position: new AMap.LngLat(120.0830600, 29.2075300), // icon: 'image/三角形.png' // }) // marker.setLabel({ // content: '测试', // direction: "right", // // 在 direction 基础上的偏移量 // offset: [-20, -30] // }) // marker.setMap(map) // console.log(marker) } } }) </script> <style> .amap-marker-label { border: none !important; background-color: inherit !important; color: black; } .marker-title { color: black; width: 100px; height: 20px; top:-32px; font-size: 12px; /*right:-40px;*/ /*position: absolute;*/ } .breath_light { opacity: 0.1; /* 不透明度 */ overflow: hidden; /* 背景色 */ /* margin: 25% auto; */ /* 外边距 */ /* IE10、Firefox and Opera,IE9以及更早的版本不支持 */ animation-name: breath; /* 动画名称 */ animation-duration: 700ms; /* 动画时长3秒 */ animation-timing-function: ease-in-out; /* 动画速度曲线:以低速开始和结束 */ animation-iteration-count: infinite; /* 播放次数:无限 */ /* Safari and Chrome */ -webkit-animation-name: breath; /* 动画名称 */ -webkit-animation-duration: 700ms; /* 动画时长3秒 */ -webkit-animation-timing-function: ease-in-out; /* 动画速度曲线:以低速开始和结束 */ -webkit-animation-iteration-count: infinite; /* 播放次数:无限 */ } @keyframes breath { from { opacity: 0.1; } /* 动画开始时的不透明度 */ 50% { opacity: 1; } /* 动画50% 时的不透明度 */ to { opacity: 0.1; } /* 动画结束时的不透明度 */ } @-webkit-keyframes breath { from { opacity: 0.1; } /* 动画开始时的不透明度 */ 50% { opacity: 1; } /* 动画50% 时的不透明度 */ to { opacity: 0.1; } /* 动画结束时的不透明度 */ } </style> </html>
-
开发那点事(十一)微信小程序地图聚合功能实现
2020-05-11 22:54:24公司项目需求要在微信小程序上实现地图marker点聚合的功能,百度苦寻无果,故自己实现。 核心思路 marker标签中的callout属性用来显示聚合点的数量 点击聚合点时,以聚合点为中心放大地图,不需要再次请求后台接口 ... -
完美解决百度地图聚合中的marker添加label后移动、放大缩小时label消失的问题
2013-05-27 17:38:21完美解决百度地图聚合中的marker添加label后移动、放大缩小时label消失的问题,添加获取已经聚合点位的接口! -
高德地图点聚合,点聚合点击事件,单点点击事件
2018-06-06 11:27:48高德地图点聚合,聚合点点击事件,一切效果都需要您自己的key值,单点点击事件,点聚合点击事件后信息窗体每个点添加点击事件。 -
高德地图聚合
2016-07-06 14:28:39高德地图聚合 -
百度地图聚合显示.zip
2019-11-20 11:32:08百度地图地区聚合显示房产数据。数据量较少,所以不是每一个区下面都有数据,只模拟造了少量数据,并且能显示所有行政边界。 -
vue+openlayer实现地图聚合效果和撒点效果
2021-09-09 13:14:54并且反馈都特别好的软件了,像之前的ol3, 风靡一时,地图实现也很简单,很实用,目前vue中使用地图也是非常多的,那么如果在vue中引入openlayer并且实现地图撒点效果,甚至是更深层的地图聚合效果呢,本文来分享下... -
高德地图点聚合效果
2017-08-16 09:56:28使用高德地图完成点聚合效果 -
安卓高德地图点聚合功能
2017-08-29 18:23:34最近需要实现地图的点聚合功能,由于刚开始项目中使用的是高德地图,查看Android高德地图的官方文档,发现没有这个功能,要自己实现了,下面把demo源码贴出来供大家参考! -
百度地图图片标注实现点聚合,并修改点聚合样式
2018-12-18 16:52:19修改聚合样式,需要在js文件中找到../assets开头的图片链接,改为自己的本地链接。需要注意的是,链接不需要加.jpg或.png,需要那种格式,可以将后面变量改了就可以。js文件默认会在链接地址后面拼接0.jpg或0.png,... -
百度地图 点聚合相关文件
2017-12-20 15:05:34百度地图点聚合可设置点聚合起始聚合点数量 mClusterManager.setMackSize(2); -
百度地图 自制点聚合实例
2018-01-31 10:32:19百度地图 自制点聚合实例,工厂化覆盖物,并实例每一个覆盖物到指定经纬度,自定覆盖物样式,引入聚合api。进行点聚合显示 -
高德地图聚合点,增加所有点击标记,点击后展示该聚合点下所有信息
2020-10-15 11:30:36高德地图聚合点,增加所有点击标记,点击后展示该聚合点下所有信息使用高德地图图片下面是部分代码,如有不懂,留言结束 使用高德地图 *1.首先去注册... -
地图聚合算法
2020-02-14 22:28:28一、为什么需要点聚合 在地图上查询结果通常以标记点的形式展现,但是如果标记点较多,不仅会大大增加客户端的渲染时间,让客户端变得很卡,而且会让人产生密集恐惧症(图1)。为了解决这一问题,我们需要一种手段...