openlayer 图层绘制成多种颜色的一个图层

技术栈:

因为是旧项目的优化功能,这里主要介绍实现思路。技术栈:openlayer 6.5^、jquery、layui组件。

背景:

在创建一个地图对象后,如何创建此处省略。这里主要讲解如何根据接口的数据来把水深测量时间的图层根据不同的条件(测量时间差)渲染成不同颜色。包括:一年以内【绿色】、1~2年【黄色】、2~3年【橘色】、3年以上【红色】

实现效果:

主要实现思路:

1.测量时间图层的初始化绘制就需要根据不同时间差,绘制不同的featrue。然后,layer.getSource().addFeature(feature)添加到此图层。

2.图层控件的颜色,要跟图层绘制的颜色保持一致。

3.图层控件能够控制相应图层的开关。

一、初始化测量时间的图层

 (1).根据接口绘制图层

核心思路:

写在前面,因为这是优化功能,之前的接口设计没有设计成根据不同的时间差返回对应的数据,接口不接受参数,接口返回的结果也没有按照时间差进行分组。而是一股脑的返回所有查询到的结果数组resData。

前端需要做的工作,

1.根据接口返回的数据,计算时间差,根据不同时间差给结果数组resData的每一个对象新增字段color、minVal、maxVal、isBoolean = true(默认渲染);

2.根据4种颜色分组,并分别添加上同组的索引值,之后会用到这个索引值,(会根据这个索引值查找到同组的所有对象,将其isBoolean更改为false,意为这组颜色的要素不渲染)

3.使用一个全局变量来存储这个originalData未筛选的数据,之后图层控件控制图层开关的时候会用带这个originalData,(会根据这个值,保证图层控件的开关更改的都是未筛选的初始化数据originalData)

封装方法:

  /**
   * 1.创建图层,根据不同时间差
   * 测量时间面
   */
  InitMeasuringTimePlane: function () {
    $.post('enavapi/data/basedata/getWaterDepthMeasurementLayer',{}, function (data) {
      if (data.code == 200 && data.data.length > 0) {
        var data = data.data
        var rootLayer = MAPutils.getLayerByTitle("测量时间");
        //计算时间差
        // 格式化当前日期
        let formattedDate = moment().format('YYYY-MM-DD HH:mm:ss');
        rootLayer.getSource().clear();
        $.each(data, function (i, v) {
          var color = MAPutils.getFormatColor(v.surend,formattedDate).color;
          var minVal = MAPutils.getFormatColor(v.surend,formattedDate).minVal;
          var maxVal = MAPutils.getFormatColor(v.surend,formattedDate).maxVal;
          v.color = color
          v.minVal = minVal
          v.maxVal = maxVal
          v.isBoolean = true
          MAPutils.drawVectorFeature(rootLayer, {
            geom: v.geom,
            id: v.guid,
            kv: {
              // markType: "shoalWaterLayer",
              data: v,
              layerType: 'MeasuringTimePlaneLayer'
            },
            style: new ol.style.Style({
              fill: new ol.style.Fill({
                color: [200, 200, 200,0.4]
              }),
              stroke: new ol.style.Stroke({
                color: color,
                width:3
              }),
            }),
          });

        });
        let groupedData = _.groupBy(data, 'color')
        let index = 0;
        // 遍历每个分组并添加索引值
        for (let groupKey in groupedData) {
          let group = groupedData[groupKey];
          for (let i = 0; i < group.length; i++) {
            group[i].index = index;
          }
          index++;
        }
        let originalData = _.flatMap(groupedData, group => group);
        MAPutils.measureTimeAllData =  originalData//未筛选的图层数据;用一个全局变量存储
      }

    });

  },

以上方法有调用到下面封装的方法,

其它,

  • 使用到封装好的图层绘制方法,如下:
  /**
   * 绘制图层
   * @param _title 图层title
   * @param object 必须包含geom字段
   * 达到效果:给对应的layer图层添加上featrue要素,已达到绘制图层的效果
   */
  drawVectorFeature: function (layer, object) {
    var geom = new ol.format.WKT().readGeometry(object.geom, {
      dataProjection: 'EPSG:4326',    // 设定数据使用的坐标系
      featureProjection: 'EPSG:3857' // 设定当前地图使用的feature的坐标系
    });
    var feature = new ol.Feature({
      geometry: geom
    });
    object.id && feature.setId(object.id);
    object.style && feature.setStyle(object.style);
    // kv值,调用set方法
    var obj = object.kv;
    if (obj) {
      Object.getOwnPropertyNames(obj).forEach(function (key) {
        feature.set(key, obj[key]);
      });
    }
    layer.getSource().addFeature(feature);
    return feature;
  },
  • 使用封装好的计算时间差的方法,如下:
getFormatColor: function (currentTime,parentTime) {
    //计算时间差
    var color=''
    var minVal=0
    var maxVal=0
    var a = moment(parentTime);
    var b = moment(currentTime);
    var timeDiff =  a.diff(b, 'years', true); // 1.75
    switch (true) {
      case _.inRange(timeDiff, 0, 1):
        color =  "rgba(1,255,1,.7)"
        minVal = 0
        maxVal = 1
        break;
      case _.inRange(timeDiff, 1, 2):
        color = "rgba(255,255,0,.7)"
        minVal = 1
        maxVal = 2
        break;
      case _.inRange(timeDiff, 2, 3):
        color =  "rgba(255,192,0,.7)"
        minVal = 2
        maxVal = 3
        break;
      case _.inRange(timeDiff, 3, 100):
        color = "rgba(214,20,21,.7)"
        minVal = 3
        maxVal = 100
        break;
      default:
        color = 'pink'
        break;
    }
    return {color,minVal,maxVal}
  },

 写到这儿,图层绘制不同颜色便完成了,以下是加了控制事件。。。

 二、图层控件的静态布局

(1).根据已封装好的图层控制文件LayerControl.js文件,绘制图层控制组件。(定制化)

layerControl.js如下:

图层控件的渲染:

jqury创建标签元素并设置选中样式,默认:初始化图层都渲染,初始化图层控件都选中,通过点击图层控件控制对应图层的关闭或者打开。

三、图层控件控制图层的开关

核心思路:

在上面我们有说到一个变量isBoolean值,这里有用到。我们说的图层控件控制图层的开关,简单一点可以通过发起带参数的网络请求,根据接口的返回结果进行图层的重新绘制(但是因为这次是项目优化,接口没有变,所以前端需要多做功夫,这就用到了第2种解决方式)。

第2种解决方式:根据初始化创建图层的时候,我们对接口返回的数据进行添加字段的处理,我们添加的字段包括:color、minVal、maxVal、isBoolean = true(默认渲染)。并且把处理后的数据用一个originalData全局变量保存了起来,这里有用到。

封装方法:

  // 测量时间的点击事件
  _getSelectMeasureTime: function () {
    $('body').on('click', '.mt-sub-level2-group .' + MultiMarkShip.SUB_LEVEL2_SWITCHER, function () {
      // 切换样式
      var $this = $(this)
        checked = !$this.hasClass(MultiMarkShip.SUB_SELECTED_CLASS)
        _index = $this.attr('index')
        confDetails = CONFIG.initLayer.find(function (itme) { return itme.title === '测量时间' })
      $this.toggleClass(MultiMarkShip.SUB_SELECTED_CLASS)
      let filteredObjects = _.filter(confDetails.children, obj => obj.index == _index);
      _.forEach(filteredObjects, obj => {
          obj.notCreate = !checked;
      });

      if (checked) {
        $this.css({
          color: $this.attr('fontcolor'),
          background: $this.attr('bgcolor'),
        })
      } else {
        $this.css({
          color: '#999',
          background: '#ddd',
        })
      }
      var oldDataList = MAPutils.measureTimeAllData
      //筛选有效Features
      var newDataList = oldDataList.map(function (item,index) {
        if(item.index == _index){
          item.isBoolean = !item.isBoolean
        }
        return item
      })
      var rootLayer = MAPutils.getLayerByTitle("测量时间");
      //重新绘制
      MAPutils.getLayerByTitle("测量时间").getSource().clear();
      $.each(newDataList, function (index, item) {
        if(item.isBoolean == true) {
            var v = item
            MAPutils.drawVectorFeature(rootLayer, {
              geom: v.geom,
              id: v.guid,
              kv: {
                // markType: "shoalWaterLayer",
                data: v,
                layerType: 'MeasuringTimePlaneLayer'
              },
              style: new ol.style.Style({
                fill: new ol.style.Fill({
                  color: [200, 200, 200,0.4]
                }),
                stroke: new ol.style.Stroke({
                  color: v.color,
                  width:3
                }),
              }),
            });
        }
      });

    })
  },

这是一个视频录屏演示效果,

测量时间

下一篇:下一篇,创建图层后,之后如何点击图层并通过点击图层拿到数据,拿到此数据在发起网络请求等操作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值