使用turf.js和openlayers配合生成等值面

turf.js官网:https://turfjs.org/   中文网:https://turfjs.fenxianglu.cn/

1.npm安装turf.js:npm install @turf/turf

2.引入:

import Point from 'ol/geom/Point';
import Feature from 'ol/Feature';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import { Stroke, Style, Icon, Text as TextStyle, Circle as CircleStyle, Fill } from 'ol/style.js';
import Select from 'ol/interaction/Select';
import { click, pointerMove } from 'ol/events/condition.js';
import GeoJSON from 'ol/format/GeoJSON';
// import {featureCollection,interpolate,isobands,flatten,randomPoint,bbox,featureEach,buffer,intersect} from '@turf/turf';
import * as turf from '@turf/turf'

3.需要的数据:点数据:包括点的x,y坐标和一个用来差值的字段值,面数据用于边界修剪。如果不进行边界的修剪生成的等值面就是点集的最大边界作为边界。

        let features: any = data.map(i => {//从data中获取有效数据生成geojson格式的对象。这里的data是一个对象的数组,这个对象中包含属性long(即x),lat(即y),drop(即差值字段)
          return {
            type: 'Feature',
            properties: {
              value: i.drop
            },
            geometry: {
              type: 'Point',
              coordinates: [i.long, i.lat]
            }
          }});
 
let points= turf.featureCollection(features);//根据上面的geojson数组生成一个feature集合
        let interpolate_options: any = {//设置生成网格的参数
          gridType: 'points',//使用的几何数据类型
          property: 'value',//插值使用的字段
          units: 'degrees',//横纵坐标的单位
          weight: 5//插值字段的值的权重
        };
        let grid = turf.interpolate(points, 0.01, interpolate_options);//生成网格,0.01是网格的大小
 
 let isobands_options = {//根据上面的网格值生成等值面的参数
          zProperty: 'value',//同样表示插值的字段名
          breaksProperties: [//设置分段后各个段使用的颜色
            { fill: 'rgba(240,255,255,0.8)'},
            { fill: 'rgba(144,238,144,0.8)'},
            { fill: 'rgba(144,238,144,0.8)'},
            { fill: 'rgba(52,101,255,0.8)'},
            { fill: 'rgba(255,255,1,0.8)'},
            { fill: 'rgba(254,153,0,0.8)'},
            { fill: 'rgba(218,46,42,0.8)'},
          ]
        };
        let isobandData = turf.isobands(//根据上面的网格生成等值面
          grid,
          [-10,-5,0, 10,30,50,1000],//根据上面的插值字段的值来进行分段的依据,即这个中间的每一段就设置为对应上面设置的颜色
          isobands_options
        );
//这里我们就可以将isobandData这个数据用openlayers生成图层加载到地图上了:
  let vectorSource = new VectorSource({
          features: new GeoJSON().readFeatures(isobandData ),
        });
        let vectorLayer = new VectorLayer({
          source: vectorSource,
          style: (feature) => {
            return new Style({
              fill: new Fill({
                color: feature.values_.fill,
              }),
            });
          },
        });
        this.map.addLayer(vectorLayer);

//我们也可以在将上面生成的等值面再用一个我们的边界进行裁剪

let intersectionFeatures: any = [];
let boundaries = turf.flatten(bounderyJson);//bounderyJson是一个面类型的按照geojson的格式生成的一个对象作为边界来进行裁剪,你可以自己按照geojson的字符串格式组织好string再用JSON.parse();方法生成对象。这个geojson的字符串可以直接使用wfs返回的数据。
        isobandData.features.forEach(function (layer1) {//遍历裁剪
          boundaries.features.forEach(function (layer2:any) {
            let intersection = null;
            try {
              intersection = turf.intersect(layer1, layer2);
            } catch (e) {
              layer1 = turf.buffer(layer1, 0);
              intersection = turf.intersect(layer1, layer2);
            }
            if (intersection != null) {
              intersection.properties = layer1.properties;
              intersection.id = Math.random() * 100000;
              intersectionFeatures.push(intersection);
            }
          });
        });

        let intersection = turf.featureCollection(intersectionFeatures);//根据裁剪后的future生成可用的future集合,然后就可以将这个集合作为geojson的方式用openlayers加载到地图上了
//加载到地图上的方式和上面加载未裁剪的等值面图一致,这里就先注释掉了
 // let vectorSource = new VectorSource({
 //         features: new GeoJSON().readFeatures(intersection),
 //       });
 //       let vectorLayer = new VectorLayer({
 //         source: vectorSource,
 //         style: (feature) => {
 //           return new Style({
 //             fill: new Fill({
 //               color: feature.values_.fill,
 //             }),
 //           });
 //         },
 //       });
 //       this.map.addLayer(vectorLayer);
posted @ 2021-03-25 18:22  maycpou  阅读(1605)  评论(0编辑  收藏  举报