美文网首页OpenLayers
OpenLayers中切片图层TileLayer的渲染解析

OpenLayers中切片图层TileLayer的渲染解析

作者: jadefan | 来源:发表于2019-11-04 21:38 被阅读0次

    切片图层是最常用也是最基础的图层,通常底图或者影像图层都采用TileLayer加载
    TileLayer由Tile组成,Tile一般是图片切片
    我们来看TileLayer渲染过程

    TileLayer的创建

    从最初的地方开始,也就是初始化地图时,会实例化一个切片图层

    const map = new Map({
      layers: [
        new TileLayer({
          source: new OSM()
        })
      ],
      target: 'map',
      view: new View({
        center: [0, 0],
        zoom: 2
      })
    });
    

    TileLayer里也比较简洁,初始化调用父类的构造函数,自己只负责创建渲染器

    class TileLayer extends BaseTileLayer {
      constructor(opt_options) {
        super(opt_options);
      }
      createRenderer() {
        return new CanvasTileLayerRenderer(this);
      }
    }
    

    那在何处执行createRenderer,构建layer.render以备Map调用呢?
    TileLayer属于Layer的子类,看Layer的实现:

    class Layer extends BaseLayer {
      constructor(options) {
        ...
      }
      render(frameState, target) {
        const layerRenderer = this.getRenderer(); 
        if (layerRenderer.prepareFrame(frameState)) {
          return layerRenderer.renderFrame(frameState, target);
        }
      }
      getRenderer() {
        if (!this.renderer_) {
          this.renderer_ = this.createRenderer();
        }
        return this.renderer_;
      }
    }
    

    可以看到Layer定义了render()方法,并调用了createRenderer(),并执行渲染器的renderFrame()方法
    这里就引出了ol的一个图层渲染机制

    ol的图层类型很多,但大部分属性和方法通用,不同的图层类型自己创建渲染器,用Layer统筹初始化图层,再调用各自实现的渲染器

    TileLayer的继承链条为:
    TileLayer->BaseTileLayer->Layer->BaseLayer->BaseObject->Observable->EventTarget->Disposable
    TileLayer的渲染器CanvasTileLayerRenderer的继承链条为:
    CanvasTileLayerRenderer->CanvasLayerRenderer->LayerRenderer->Observable->EventTarget->Disposable
    接下来看ol是如何渲染切片图层的

    TileLayer的渲染器CanvasTileLayerRenderer的实现逻辑

    通过上面的解析可以看出渲染的核心方法是renderFrame(),代码很长,来看主要逻辑

    首先看下切片图层的数据源Source

    TileLayer的一个重要属性就是source,定义了切片的网络地址、规则、大小、分辨率、比例尺、生产商等等信息。要正确渲染就必须先正确解析并请求到切片图片。

    OSM看下source的继承关系
    OSM->XYZ->TileImage->UrlTile->TileSource->Source->BaseObject->Observable->EventTarget->Disposable

    OpenStreetMap(简称OSM,中文是公开地图)是一个网上地图协作计划,目标是创造一个内容自由且能让所有人编辑的世界地图。它是利用公众集体的力量和无偿的贡献来改善地图相关的地理数据。OSM是非营利性 的,它将数据回馈给社区重新用于其它的产品与服务。

    可以看到OSM继承自XYZ,XYZ是切片地图很常用的一套切片规则,在new OSM()时已经将对应投影和切片规则读取出来

    在调用渲染器时,根据设置好的中心点和级别,通过切片规则和投影定义计算出需要的切片Z\X\Y的值,从而请求到切片的图片,再绘制到canvas中。

    canvas / TileLayer.js

    class CanvasTileLayerRenderer extends CanvasLayerRenderer {
    ...
      renderFrame(frameState, target) {
        ...
        for (const tileCoordKey in tilesToDraw) {
          //调用绘制切片
          this.drawTileImage(tile, frameState, x, y, w, h, tileGutter, transition, layerState.opacity);
        } 
        ...
      }
    
      drawTileImage(tile, frameState, x, y, w, h, gutter, transition, opacity) {
        ...
        //画布绘制
        this.context.drawImage(image, gutter, gutter, image.width - 2 * gutter, image.height - 2 * gutter, x, y, w, h);
        ...
      }
      ...
    }
    

    相关文章

      网友评论

        本文标题:OpenLayers中切片图层TileLayer的渲染解析

        本文链接:https://www.haomeiwen.com/subject/pfrjbctx.html