源码分析之Openlayers中的Feature矢量要素渲染源码分析

访问Openlayers网站(https://jinuss.github.io/Openlayers_map_pages/,网站是基于Vue3 + Openlayers,里面有大量的实践和案例。觉得还不错,可以在这里插入图片描述 给个小星星Star,鼓励一波 https://github.com/Jinuss/OpenlayersMap哦~

概述

在这里插入图片描述

在前面提到了 Openlayers 中的矢量几何图形的渲染指令集部分,关于这些构建绘制指令集的类CanvasBuilderGroup类,可以参考这篇文章源码分析之Openlayers中BuilderGroup类。顾名思义,CanvasBuilderGroup类就是一组管理各种几何图形指令集的构造器的集合,该类会在矢量图层VectorLayer.jssrc\ol\renderer\canvas\VectorLayer.js)和矢量瓦片图层VectorTileLayer.jssrc\ol\renderer\canvas\VectorTileLayer.js)中被实例化,然后依据feature去构建指令集。

本文将以VetorLayer.js为例,讲解一个feature时如何生成指令集的过程。

源码分析

CanvasVectorLayerRenderer

CanvasVectorLayerRenderer类即VectorLayer.js,用于构建矢量图层的渲染器,它继承于CanvasLayerRenderer类,关于CanvasLayerRenderer类,可以参考这篇文章源码分析之Openlayers渲染篇CanvasLayerRenderer类

CanvasVectorLayerRenderer类的中的prepareFrame方法会在Layer类中的render方法被调用,而Layer类是BaseVectorLayer类的父类,关于它们的介绍,分别可以参考这两篇文章源码分析之Openlayers图层基类BaseLayer介绍源码分析之Openlayers中的核心基类Layer类介绍.而render方法会在Map的渲染器CompositeMapRenderer类里的renderFrame方法中被调用。总结一下就是prepareFrame方法会在地图渲染时被调用,

  • prepareFrame方法

prepareFrame方法中关于feature部分的代码如下:

class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
   
   
  prepareFrame(frameState) {
   
   
    const replayGroup = new CanvasBuilderGroup(
      getRenderTolerance(resolution, pixelRatio),
      extent,
      resolution,
      pixelRatio
    );

    const render = (feature, index) => {
   
   
      let styles;
      const styleFunction =
        feature.getStyleFunction() || vectorLayer.getStyleFunction();
      if (styleFunction) {
   
   
        styles = styleFunction(feature, resolution);
      }
      if (styles) {
   
   
        const dirty = this.renderFeature(
          feature,
          squaredTolerance,
          styles,
          replayGroup,
          userTransform,
          this.getLayer().getDeclutter(),
          index
        );
        ready = ready && !dirty;
      }
    };

    const features = vectorSource.getFeaturesInExtent(userExtent);

    for (let i = 0, ii = features.length; i < ii; ++i) {
   
   
      render(features[i], i);
    }

    const replayGroupInstructions = replayGroup.finish();
  }
}

prepareFrame方法会实例化CanvasBuilderGroup类,实例对象relayGroup表示一组待渲染的绘制命令集合,是图形绘制命令的载体。它用于管理和优化图形的渲染过程,将多个渲染步骤组合在一起,避免重复计算,可以提高渲染效率。然后定义了一个局部函数render

  • render函数

render函数接受两个参数featureindex,这里的feature就是Feature类的一个实例,关于Feature类,可以参考这篇文章源码分析之Openlayers中Feature特征render方法内部会先判断feature是否定义了样式函数styleFunction,若没有定义,则使用矢量图层vectorLayer的默认样式函数,然后执行styleFunction(feature,resolution)语句,返回结果作为styles,这一步也就是每当地图更新时,feature或者layerstyleFunction会被调用,可以获取地图实时的分辨率resolution;然后判断,若styles存在,则调用内部方法this.renderFeature方法。

prepareFrame方法通过图层源获取用户可见范围内的features,然后遍历features,去调用上面定义的局部函数render

最后调用replayGroup.finish方法获取需要绘制features的绘制指令集和碰撞检测指令集等。

下面介绍下this.renderFeature方法,该方法也是在CanvasVectorLayerRenderer类中定义的一个内部方法。
其实现如下:

  • renderFeature方法
class CanvasVectorLayerRenderer extends CanvasLayerRenderer {
   
   
  renderFeature(
    feature,
    squaredTolerance,
    styles,
    builderGroup,
    transform,
    declutter,
    index
  ) {
   
   
    if (!styles) {
   
   
      return false;
    }
    let loading = false;
    if (Array.isArray(styles)) {
   
   
      for (let i = 0, ii = styles.length; i < ii; ++i) {
   
   
        loading =
          renderFeature(
            builderGroup,
            feature,
            styles[i],
            squaredTolerance,
            this.boundHandleStyleImageChange_,
            transform,
            declutter,
            index
          ) || loading;
      }
    } else {
   
   
      loading = renderFeature(
        builderGroup,
        feature,
        styles,
        squaredTolerance,
        this.boundHandleStyleImageChange_,
        transform,
        declutter,
        index
      );
    }
    return loading;
  }
}

renderFeature方法内部会先判断,若styles样式不存在,则返回;然后判断样式styles是否是数组,若是数组,则循环遍历样式styles调用外部方法renderFeature,所以这里如果定义多个样式,后面的样式会覆盖前面样式的相同属性;否则只需要调用一次外部方法renderFeature,该外部方法renderFeature接受参数builderGroupfeaturestyle等等。builderGroup就是在prepareFrame方法中的实例对象replayGroup.

vector.js

上面提到的外部方法renderFeature是在src\ol\renderer\vector.js中定义的,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Jinuss

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

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

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

打赏作者

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

抵扣说明:

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

余额充值