四章-33-地震信息的要素聚合

2020-04-21  本文已影响0人  彩云飘过

本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers 5.3.x api。

源码 见 1033.html ,对应的 官网示例 https://openlayers.org/en/latest/examples/cluster.html

https://openlayers.org/en/latest/examples/earthquake-clusters.html?q=Cluster

https://openlayers.org/en/latest/examples/earthquake-custom-symbol.html?q=Style

image.png image.png
<!DOCTYPE html>
<html>

<head>
  <title>地震信息的要素聚合</title>
  <link rel="stylesheet" href="../include/ol.css" type="text/css">
  <link rel="stylesheet" href="../include/bootstrap.css" type="text/css">
  <script src="../include/ol.js"></script>


</head>

<body>

  <div id="map" class="map"></div>

  <script>
    var earthquakeFill = new ol.style.Fill({
      color: 'rgba(255, 153, 0, 0.8)'
    });
    var earthquakeStroke = new ol.style.Stroke({
      color: 'rgba(255, 204, 0, 0.2)',
      width: 1
    });
    var textFill = new ol.style.Fill({
      color: '#fff'
    });
    var textStroke = new ol.style.Stroke({
      color: 'rgba(0, 0, 0, 0.6)',
      width: 3
    });
    var invisibleFill = new ol.style.Fill({
      color: 'rgba(255, 255, 255, 0.01)'
    });

    //生成普通地震点的标记样式
    function createEarthquakeStyle(feature) {

      var name = feature.get('name');
      var magnitude = parseFloat(name.substr(2));
      var radius = 5 + 20 * (magnitude - 5);

      return new ol.style.Style({
        geometry: feature.getGeometry(),
        image: new ol.style.RegularShape({
          radius1: radius,
          radius2: 3,
          points: 5,
          angle: Math.PI,
          fill: earthquakeFill,
          stroke: earthquakeStroke
        })
      });
    }

    var maxFeatureCount;
    var vector = null;

    //计算聚合标记的半径大小
    var calculateClusterInfo = function (resolution) {
      maxFeatureCount = 0;
      var features = vector.getSource().getFeatures();
      var feature, radius;
      for (var i = features.length - 1; i >= 0; --i) {
        feature = features[i]; //获取单个聚合分组后的要素
        var originalFeatures = feature.get('features'); //获取原始的要素数组
        
        var extent = ol.extent.createEmpty(); //要素所占空间范围的大小
        var j = (void 0), jj = (void 0);
        for (j = 0, jj = originalFeatures.length; j < jj; ++j) {
          ol.extent.extend(extent, originalFeatures[j].getGeometry().getExtent());
        }
        maxFeatureCount = Math.max(maxFeatureCount, jj);
        radius = 0.25 * (ol.extent.getWidth(extent) + ol.extent.getHeight(extent)) /
          resolution;
        feature.set('radius', radius);//单个聚合分组后的要素  设置自定义半径大小
      }
    };

    var currentResolution;

    function styleFunction(feature, resolution) {
      if (resolution != currentResolution) {
        //分辨率发生了变化,重新计算聚合标记的大小
        calculateClusterInfo(resolution);
        console.log("currentResolution:"+currentResolution);
        console.log("resolution"+resolution);
        currentResolution = resolution;
      }

      var style;
      var size = feature.get('features').length;
      if (size > 1) {
        style = new ol.style.Style({
          //画圆
          image: new ol.style.Circle({
            radius: feature.get('radius'),
            fill: new ol.style.Fill({
              color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
            })
          }),
          //标记数量
          text: new ol.style.Text({
            text: size.toString(),
            fill: textFill,
            stroke: textStroke
          })
        });
      } else {
        //针对单个feature
        var originalFeature = feature.get('features')[0];
        style = createEarthquakeStyle(originalFeature);
      }
      return style;
    }

   //当鼠标移动到聚合点时
    function selectStyleFunction(feature) {
      var styles = [new ol.style.Style({
        image: new ol.style.Circle({
          radius: feature.get('radius'),
          //当选择到某个聚合点时,将其置为几乎透明
          fill: invisibleFill
        })
      })];
      //生成聚合点内的要素的样式
      var originalFeatures = feature.get('features');
      var originalFeature;
      for (var i = originalFeatures.length - 1; i >= 0; --i) {
        originalFeature = originalFeatures[i];
        styles.push(createEarthquakeStyle(originalFeature));
      }
      return styles;
    }

    vector = new ol.layer.Vector({
      source: new ol.source.Cluster({
        distance: 40,
        source: new ol.source.Vector({
          url: '../data/2012_Earthquakes_Mag5.kml',
          format: new ol.format.KML({
            extractStyles: false
          })
        })
      }),
      style: styleFunction
    });

    var raster = new ol.layer.Tile({
      source: new ol.source.Stamen({
        layer: 'toner'
      })
    });

    var map = new ol.Map({
      layers: [raster, vector],
      interactions: ol.interaction.defaults().extend([new ol.interaction.Select({
        condition: function (evt) {
          return evt.type == 'pointermove';
        },
        style: selectStyleFunction
      })]),
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 2
      })
    });

    
  </script>
</body>

</html>
上一篇下一篇

猜你喜欢

热点阅读