From 137c875df7c99f9250c6693f97ad4924962e0777 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Mon, 28 May 2018 10:23:47 +0200 Subject: [PATCH] Support vector layers instead of renderers for ol/source/Raster --- src/ol/renderer/canvas/ImageLayer.js | 39 ++++++------------- src/ol/renderer/canvas/Map.js | 24 +++++++++++- src/ol/source/Raster.js | 11 +++--- .../ol/renderer/canvas/imagelayer.test.js | 35 ++--------------- test/spec/ol/source/raster.test.js | 8 ++-- 5 files changed, 46 insertions(+), 71 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 7b33394ce4..648647b865 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -10,13 +10,11 @@ import {equals} from '../../array.js'; import {getHeight, getIntersection, getWidth, isEmpty} from '../../extent.js'; import VectorRenderType from '../../layer/VectorRenderType.js'; import {assign} from '../../obj.js'; +import {layerRendererConstructors} from './Map.js'; import IntermediateCanvasRenderer from '../canvas/IntermediateCanvas.js'; import {create as createTransform, compose as composeTransform} from '../../transform.js'; /** - * Renderer for {@link module:ol/layer/Image} layers. When a vector renderer is - * set with the {@link module:ol/renderer/canvas/ImageLayer#setVectorRenderer} - * method, it can also render vector layers to an image. * @constructor * @extends {module:ol/renderer/canvas/IntermediateCanvas} * @param {module:ol/layer/Image|module:ol/layer/Vector} imageLayer Image or vector layer. @@ -49,6 +47,16 @@ const CanvasImageLayerRenderer = function(imageLayer) { */ this.vectorRenderer_ = null; + if (imageLayer.getType() === LayerType.VECTOR && imageLayer.getRenderMode() === VectorRenderType.IMAGE) { + for (let i = 0, ii = layerRendererConstructors.length; i < ii; ++i) { + const ctor = layerRendererConstructors[i]; + if (ctor !== CanvasImageLayerRenderer && ctor['handles'](imageLayer)) { + this.vectorRenderer_ = new ctor(imageLayer); + break; + } + } + } + }; inherits(CanvasImageLayerRenderer, IntermediateCanvasRenderer); @@ -73,18 +81,7 @@ CanvasImageLayerRenderer['handles'] = function(layer) { * @return {module:ol/renderer/canvas/ImageLayer} The layer renderer. */ CanvasImageLayerRenderer['create'] = function(mapRenderer, layer) { - const renderer = new CanvasImageLayerRenderer(/** @type {module:ol/layer/Image} */ (layer)); - if (layer.getType() === LayerType.VECTOR) { - const candidates = mapRenderer.getLayerRendererConstructors(); - for (let i = 0, ii = candidates.length; i < ii; ++i) { - const candidate = /** @type {Object.} */ (candidates[i]); - if (candidate !== CanvasImageLayerRenderer && candidate['handles'](layer)) { - renderer.setVectorRenderer(candidate['create'](mapRenderer, layer)); - break; - } - } - } - return renderer; + return new CanvasImageLayerRenderer(/** @type {module:ol/layer/Image} */ (layer)); }; @@ -219,16 +216,4 @@ CanvasImageLayerRenderer.prototype.forEachFeatureAtCoordinate = function(coordin }; -/** - * Sets a vector renderer on this renderer. Call this methond to set up the - * renderer for rendering vector layers to an image. - * @param {module:ol/renderer/canvas/VectorLayer} renderer Vector renderer. - * @api - */ -CanvasImageLayerRenderer.prototype.setVectorRenderer = function(renderer) { - if (this.vectorRenderer_) { - this.vectorRenderer_.dispose(); - } - this.vectorRenderer_ = renderer; -}; export default CanvasImageLayerRenderer; diff --git a/src/ol/renderer/canvas/Map.js b/src/ol/renderer/canvas/Map.js index 1097376053..4d96e1c97c 100644 --- a/src/ol/renderer/canvas/Map.js +++ b/src/ol/renderer/canvas/Map.js @@ -3,7 +3,7 @@ */ import {create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js'; import {inherits} from '../../index.js'; -import {stableSort} from '../../array.js'; +import {includes, stableSort} from '../../array.js'; import {CLASS_UNSELECTABLE} from '../../css.js'; import {createCanvasContext2D} from '../../dom.js'; import {visibleAtResolution} from '../../layer/Layer.js'; @@ -14,6 +14,13 @@ import CanvasImmediateRenderer from '../../render/canvas/Immediate.js'; import MapRenderer, {sortByZIndex} from '../Map.js'; import SourceState from '../../source/State.js'; + +/** + * @type {Array.} + */ +export const layerRendererConstructors = []; + + /** * @constructor * @extends {module:ol/renderer/Map} @@ -202,4 +209,19 @@ CanvasMapRenderer.prototype.forEachLayerAtPixel = function(pixel, frameState, ca } return undefined; }; + + +/** + * @inheritDoc + */ +CanvasMapRenderer.prototype.registerLayerRenderers = function(constructors) { + MapRenderer.prototype.registerLayerRenderers.call(this, constructors); + for (let i = 0, ii = constructors.length; i < ii; ++i) { + const ctor = constructors[i]; + if (!includes(layerRendererConstructors, ctor)) { + layerRendererConstructors.push(ctor); + } + } +}; + export default CanvasMapRenderer; diff --git a/src/ol/source/Raster.js b/src/ol/source/Raster.js index f8dbdbd3d3..dd2b77e4db 100644 --- a/src/ol/source/Raster.js +++ b/src/ol/source/Raster.js @@ -10,10 +10,11 @@ import Event from '../events/Event.js'; import EventType from '../events/EventType.js'; import {Processor} from 'pixelworks/lib/index'; import {equals, getCenter, getHeight, getWidth} from '../extent.js'; +import LayerType from '../LayerType.js'; +import Layer from '../layer/Layer.js'; import ImageLayer from '../layer/Image.js'; import TileLayer from '../layer/Tile.js'; import {assign} from '../obj.js'; -import CanvasLayerRenderer from '../renderer/canvas/Layer.js'; import CanvasImageLayerRenderer from '../renderer/canvas/ImageLayer.js'; import CanvasTileLayerRenderer from '../renderer/canvas/TileLayer.js'; import ImageSource from '../source/Image.js'; @@ -112,7 +113,7 @@ inherits(RasterSourceEvent, Event); /** * @typedef {Object} Options - * @property {Array.} sources Input sources. + * @property {Array.} sources Input sources. * @property {module:ol/source/Raster~Operation} [operation] Raster operation. * The operation will be called with data from input sources * and the output will be assigned to the raster source. @@ -488,10 +489,8 @@ function createRenderer(source) { renderer = createTileRenderer(source); } else if (source instanceof ImageSource) { renderer = createImageRenderer(source); - } else if (source instanceof TileLayer) { - renderer = new CanvasTileLayerRenderer(source); - } else if (source instanceof CanvasLayerRenderer) { - renderer = source; + } else if (source instanceof Layer && source.getType() == LayerType.VECTOR) { + renderer = new CanvasImageLayerRenderer(source); } return renderer; } diff --git a/test/spec/ol/renderer/canvas/imagelayer.test.js b/test/spec/ol/renderer/canvas/imagelayer.test.js index bdc2e8bebb..3068bec1f2 100644 --- a/test/spec/ol/renderer/canvas/imagelayer.test.js +++ b/test/spec/ol/renderer/canvas/imagelayer.test.js @@ -23,17 +23,18 @@ describe('ol.renderer.canvas.ImageLayer', function() { }); imageRenderer = new CanvasImageLayerRenderer(layer); vectorRenderer = new CanvasVectorLayerRenderer(layer); + imageRenderer.vectorRenderer_ = vectorRenderer; }); afterEach(function() { - vectorRenderer.dispose(); imageRenderer.dispose(); + vectorRenderer.dispose(); layer.dispose(); }); it('cleans up CanvasVectorRenderer', function() { + const vectorRenderer = imageRenderer.vectorRenderer_; const spy = sinon.spy(vectorRenderer, 'dispose'); - imageRenderer.setVectorRenderer(vectorRenderer); imageRenderer.dispose(); expect(spy.called).to.be(true); }); @@ -94,36 +95,6 @@ describe('ol.renderer.canvas.ImageLayer', function() { }); }); - describe('#setVectorRenderer()', function() { - let layer, imageRenderer, vectorRenderer1, vectorRenderer2; - - beforeEach(function() { - layer = new VectorLayer({ - renderMode: 'image', - source: new VectorSource() - }); - imageRenderer = new CanvasImageLayerRenderer(layer); - vectorRenderer1 = new CanvasVectorLayerRenderer(layer); - vectorRenderer2 = new CanvasVectorLayerRenderer(layer); - }); - - afterEach(function() { - layer.dispose(); - vectorRenderer1.dispose(); - vectorRenderer2.dispose(); - imageRenderer.dispose(); - }); - - it('cleans up an existing vectorRenderer', function() { - const spy = sinon.spy(vectorRenderer1, 'dispose'); - imageRenderer.setVectorRenderer(vectorRenderer1); - expect(spy.called).to.be(false); - imageRenderer.setVectorRenderer(vectorRenderer2); - expect(spy.called).to.be(true); - }); - - }); - describe('Vector image rendering', function() { let map, div, layer; diff --git a/test/spec/ol/source/raster.test.js b/test/spec/ol/source/raster.test.js index d7e4796dd1..5f4d3928ad 100644 --- a/test/spec/ol/source/raster.test.js +++ b/test/spec/ol/source/raster.test.js @@ -1,9 +1,7 @@ import Map from '../../../../src/ol/Map.js'; import TileState from '../../../../src/ol/TileState.js'; import View from '../../../../src/ol/View.js'; -import ImageLayerRenderer from '../../../../src/ol/renderer/canvas/ImageLayer.js'; import ImageLayer from '../../../../src/ol/layer/Image.js'; -import VectorLayerRenderer from '../../../../src/ol/renderer/canvas/VectorLayer.js'; import VectorLayer from '../../../../src/ol/layer/Vector.js'; import Projection from '../../../../src/ol/proj/Projection.js'; import Static from '../../../../src/ol/source/ImageStatic.js'; @@ -49,7 +47,8 @@ where('Uint8ClampedArray').describe('ol.source.Raster', function() { imageExtent: extent }); - blueSource = new ImageLayerRenderer(new VectorLayer({ + blueSource = new VectorLayer({ + renderMode: 'image', source: new VectorSource({ features: [new Feature(new Point([0, 0]))] }), @@ -59,8 +58,7 @@ where('Uint8ClampedArray').describe('ol.source.Raster', function() { fill: new Fill({color: 'blue'}) }) }) - })); - blueSource.setVectorRenderer(new VectorLayerRenderer(blueSource.getLayer())); + }); raster = new RasterSource({ threads: 0,