openlayers 添加视口范围内的矢量图层, 删除视口外的图层

openlayers 添加视口范围内的矢量图层, 删除视口外的图层

import GeoJSON from 'ol/format/GeoJSON';
import { Vector as VectorLayer } from 'ol/layer';
import { Vector as SourceVec, Cluster, OSM, TileArcGISRest, TileWMS } from 'ol/source';
import { Style, Icon, Fill, Stroke, Text, Circle as CircleStyle } from 'ol/style';
import 'ol/ol.css';
import { createEmpty, extend, containsExtent, intersects } from 'ol/extent';


  /**
   * 添加视口范围内的矢量图层, 删除视口外的图层
   * @param {*} map
   * @param {*} dataList 数据列表 格式: [{id: '',layerName: '', geojson: null, }]
   */
  addVectorLayersFollowingViewport(map, dataList) {
    let inlist = [];        // 在视口内的图层
    let addList = [];       // 需要新加的图层
    let outNamelist = [];   // 在视口外的图层

    // 获取当前视口范围
    const viewportExtent = map.getView().calculateExtent(map.getSize());
    // 所有图层
    var layers = map.getLayers().getArray();

    // 找出视口内/外的图层
    for (let i = 0; i < dataList.length; i++) {
      const element = dataList[i];
      if (element.geojson) {
        const format = new GeoJSON();
        const features = format.readFeatures(element.geojson, {
          featureProjection: map.getView().getProjection(),
        });
        const totalExtent = createEmpty();
        features.forEach((feature) => {
          extend(totalExtent, feature.getGeometry().getExtent());
        });
        const isInViewport = intersects(viewportExtent, totalExtent);
        if (isInViewport) {
          inlist.push(element);
        } else {
          outNamelist.push(element.layerName);
        }
      }
    }

    // 找出地图上现在不存在, 需要新加的图层
    for (let i = 0; i < inlist.length; i++) {
      const element = inlist[i];
      for (let j = 0; j < layers.length; j++) {
        const layer = layers[j];
        if (layer.get('name') != element.layerName) {
            addList.push(element);
        }
      }
    }

    // 添加图层
    if (addList.length > 0) {
        addList.forEach((element) => {
        if (element.geojson) {
            let vectSec = new SourceVec({
              features: new GeoJSON({
                featureProjection: 'EPSG:4326',
              }).readFeatures(element.geojson),
              format: new GeoJSON(),
              wrapX: true,
            });

            let layer = new VectorLayer({
              source: vectSec,
              name: element.layerName,
              style: function (feature, resolution) {
                return new Style({
                  stroke: new Stroke({
                    color: '#ff0000',
                    width: 3,
                  }),
                  fill: new Fill({
                    color: '#ff0000',
                  }),
                  text: new Text({
                    font: '12px 微软雅黑',
                    placement: 'line',
                    text: feature.get('NAME'),
                    fill: new Fill({
                      color: '#fff',
                    }),
                    stroke: new Stroke({
                      color: '#ff0000',
                      width: 3,
                    }),
                    overflow: true, 
                  }),
                });
              },
            });
            map.addLayer(layer);
        } 
      });
    }

    // 删除视口外的图层
    if (outNamelist.length > 0) {
      for (let i = 0; i < layers.length; i++) {
        const layer = layers[i];
        if (outNamelist.includes(layer.get('name'))) {
          map.removeLayer(layer);
        }
      }
    }
  }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码工人笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值