Openlayers克里金插值计算等值面与图层裁剪

Openlayers克里金插值计算等值面与图层裁剪

计算等值面

      let WFSVectorSource = new VectorSource();
      let WFSVectorLayer = new VectorLayer({
        source: WFSVectorSource,
      });
      map.addLayer(WFSVectorLayer);
      //构造面数据
      for (let i = 0; i < pointArr.length; i++) {
        let feature = new Feature({
          geometry: new Point([pointArr[i].lgtd, pointArr[i].lttd]),
          value: pointArr[i].z,
        });
        feature.setStyle(
          new olStyle({
            image: new Circle({
              radius: 6,
              fill: new olstyleFill({ color: "#00F00000" }),
            }),
          })
        );
        WFSVectorSource.addFeature(feature);
      }
      let extent = WFSVectorLayer.getSource().getExtent();
      WFSVectorSource.forEachFeatureIntersectingExtent(extent, (feature) => {
        that.selectedFeatures.push(feature);
      });

通过克里金插值计算

 var that = this;
      let values = [],
        lngs = [],
        lats = [];
      that.selectedFeatures.forEach((feature) => {
        values.push(feature.values_.value);
        lngs.push(feature.values_.geometry.flatCoordinates[0]);
        lats.push(feature.values_.geometry.flatCoordinates[1]);
      });
      let variogram = kriging.train(
        values,
        lngs,
        lats,
        params.krigingModel,
        params.krigingSigma2,
        params.krigingAlpha
      );
      let polygons = [];
      polygons.push([
        [extent[0], extent[1]],
        [extent[0], extent[3]],
        [extent[2], extent[3]],
        [extent[2], extent[1]],
      ]);
      let grid = kriging.grid(polygons, variogram, (extent[2] - extent[0]) / 500);
      let dragboxExtent = extent;

      if (that.vectorLayer !== null) {
        map.removeLayer(that.vectorLayer);
      }
      var vectorSource = new VectorSource();
      that.vectorLayer = new VectorLayer({
        zIndex: 10,
        source: vectorSource,
        opacity: 0.7,
        style: function (feature) {
          var style = new olStyle({
            fill: new olstyleFill({
              color:
                params.colors[
                  Math.round(parseFloat(feature.get("value").split("-")[1]) * 17)
                ],
            }),
          });
          return style;
        },
      });
      //使用turf渲染等值面/线
      let fc = that.gridFeatureCollection(
        grid,
        [extent[0], extent[2]],
        [extent[1], extent[3]]
      );
      var collection = turf.featureCollection(fc);
      var breaks = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0];
      var isobands = turf.isobands(collection, breaks, { zProperty: "value" });
      function sortArea(a, b) {
        return turf.area(b) - turf.area(a);
      }
      //按照面积对图层进行排序,规避turf的一个bug
      isobands.features.sort(sortArea);
      var polyFeatures = new GeoJSON().readFeatures(isobands, {
        featureProjection: "EPSG:4326",
      });
      vectorSource.addFeatures(polyFeatures);

      map.addLayer(that.vectorLayer);

最后裁剪面

如果使用官网裁剪效果会直接连底图一起被裁剪,所以这里使用canvas裁剪

      var fea = new GeoJSON().readFeatures(polygon);
      that.vectorLayer.on("prerender",  (event) => {
        that.clip(event, fea[0]);
      })
      that.vectorLayer.on("postrender", (event) => {
        let ctx = event.context;
        ctx.restore();
      });
      var viewState = frameState.viewState;
      var center = viewState.center;
      var resolution = viewState.resolution;
      var rotation = viewState.rotation;
      var pixelRatio = frameState.pixelRatio;
      var size = frameState.size;
      var size1 = map.getSize();
      var offsetX = Math.round((pixelRatio * size[0]) / 2);
      var offsetY = Math.round((pixelRatio * size[1]) / 2);
      var pixelScale = pixelRatio / resolution;
      for (var i = 0, cout = coords.length; i < cout; i++) {
        var xLen = Math.round((coords[i][0] - center[0]) * pixelScale);
        var yLen = Math.round((center[1] - coords[i][1]) * pixelScale);
        var x = offsetX;
        var y = offsetY;
        if (rotation) {
          x = xLen * Math.cos(rotation) - yLen * Math.sin(rotation) + offsetX;
          y = xLen * Math.sin(rotation) + yLen * Math.cos(rotation) + offsetY;
        } else {
          x = xLen + offsetX;
          y = yLen + offsetY;
        }
        if (i == 0) {
          canvas.moveTo(x, y);
        } else {
          canvas.lineTo(x, y);
        }
      }
      canvas.closePath();

最后是效果图

克里金插值效果(未裁剪)

Openlayers克里金插值计算等值面与图层裁剪_第1张图片

克里金插值效果(裁剪后)
Openlayers克里金插值计算等值面与图层裁剪_第2张图片

你可能感兴趣的:(openlayers,前端,javascript)