【前端小记】--OpenLayers--1.点位图层动态聚合展示

需求描述

在地图上实现一个点位的图层展示,但是有的时候地图上的点位非常多,而且有些经纬度非常接近,导致地图上的点位展示非常密集,这个时候,如果直接在地图上展示所有点位就会降低用户的视觉体验,而且也容易卡顿,如下图所示:
在这里插入图片描述

解决思路

针对以上这种情况的的出现,OpenLayers给出了一个解决办法——聚类。
通常情况,我们在给地图添加图层时,会new一个VectorSource作为数据源,而聚类实际上就是把new的VectorSource作为聚类地一个属性source,再去new一个Cluster作为图层的数据源

具体实现

点位保持聚类展示

import Feature from 'ol/Feature';
import Map from 'ol/Map';
import Point from 'ol/geom/Point';
import View from 'ol/View';
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style,
  Text,
} from 'ol/style';
import {Cluster, OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {boundingExtent} from 'ol/extent';

const distanceInput = document.getElementById('distance');
const minDistanceInput = document.getElementById('min-distance');

//模拟一些地图上的点位
const count = 20000;
const features = new Array(count);
const e = 4500000;
for (let i = 0; i < count; ++i) {
  const coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
  features[i] = new Feature(new Point(coordinates));
}

//设置地图的数据源
const source = new VectorSource({
  features: features,
});

//把数据源转化成聚类模式下的数据源
const clusterSource = new Cluster({
  distance: 100,
  source: source,
});

const styleCache = {};
const clusters = new VectorLayer({
  source: clusterSource,
  style = function (feature) {
      //size表示在聚类的点位上展示集合的点位数量
      let size = feature.get('features').length;
      let style = new Style({
          image: new Circle({
            radius: 15,
            fill: new Fill({
              color: 'orange',
            }),
          }),
          text: new Text({
            text: size.toString(),
            font: 'normal 12px Arial',
            fill: new Fill({
              color: '#000',
            }),
          }),
        });
      return style;
    };
});

const raster = new TileLayer({
  source: new OSM(),
});

const map = new Map({
  layers: [raster, clusters],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2,
  }),
});

点位在聚类只有一个点时展示后端返回的图标

import Feature from 'ol/Feature';
import Map from 'ol/Map';
import Point from 'ol/geom/Point';
import View from 'ol/View';
import {
  Circle as CircleStyle,
  Fill,
  Stroke,
  Style,
  Text,
} from 'ol/style';
import {Cluster, OSM, Vector as VectorSource} from 'ol/source';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import {boundingExtent} from 'ol/extent';

const distanceInput = document.getElementById('distance');
const minDistanceInput = document.getElementById('min-distance');

//模拟一些地图上的点位
const count = 20000;
const features = new Array(count);
const e = 4500000;
for (let i = 0; i < count; ++i) {
  const coordinates = [2 * e * Math.random() - e, 2 * e * Math.random() - e];
  features[i] = new Feature(new Point(coordinates));
}

//设置地图的数据源
const source = new VectorSource({
  features: features,
});

//把数据源转化成聚类模式下的数据源
const clusterSource = new Cluster({
  distance: 100,
  source: source,
});

const styleCache = {};
const clusters = new VectorLayer({
  source: clusterSource,
  style = function (feature) {
      //size表示在聚类的点位上展示集合的点位数量
      let size = feature.get('features').length;
      let style;
      // 此刻的判断就是实现需求的关键点,当聚类只有一个点时,即size=1,显示后端返回的图标,多个点时显示聚类
      if (size == 1) {
      //由于聚类不同于普通点位图层,一个f中有很多点位,所以必须要遍历f去拿到单个的f
        feature.get('features').forEach((value, index) => {
          style = new Style({
            image: new Icon({
              src: value.get('obj').industry_type_icon,
            }),
          });
        });
      } else {
        style = new Style({
          image: new Circle({
            radius: 15,
            fill: new Fill({
              color: 'orange',
            }),
          }),
          text: new Text({
            text: size.toString(),
            font: 'normal 12px Arial',
            fill: new Fill({
              color: '#000',
            }),
          }),
        });
      }
      return style;
    };
});

const raster = new TileLayer({
  source: new OSM(),
});

const map = new Map({
  layers: [raster, clusters],
  target: 'map',
  view: new View({
    center: [0, 0],
    zoom: 2,
  }),
});

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值