diff --git a/examples/drag-and-drop-image-vector.html b/examples/drag-and-drop-image-vector.html
index 2635bb9e1a..f6f791278f 100644
--- a/examples/drag-and-drop-image-vector.html
+++ b/examples/drag-and-drop-image-vector.html
@@ -3,7 +3,7 @@ layout: example.html
title: Drag-and-Drop Image Vector
shortdesc: Example of using the drag-and-drop interaction with image vector rendering.
docs: >
- Example of using the drag-and-drop interaction with an `ol/layer/Vector` with `renderMode: 'image'`. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
+ Example of using the drag-and-drop interaction with an `ol/layer/VectorImage` layer. Drag and drop GPX, GeoJSON, IGC, KML, or TopoJSON files on to the map. Each file is rendered to an image on the client.
tags: "drag-and-drop-image-vector, gpx, geojson, igc, kml, topojson, vector, image"
cloak:
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
diff --git a/examples/drag-and-drop-image-vector.js b/examples/drag-and-drop-image-vector.js
index bfbe18b276..6b0fb4a3c2 100644
--- a/examples/drag-and-drop-image-vector.js
+++ b/examples/drag-and-drop-image-vector.js
@@ -2,7 +2,7 @@ import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
import {defaults as defaultInteractions, DragAndDrop} from '../src/ol/interaction.js';
-import {Vector as VectorLayer, Tile as TileLayer} from '../src/ol/layer.js';
+import {VectorImage as VectorImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
import {BingMaps, Vector as VectorSource} from '../src/ol/source.js';
const dragAndDropInteraction = new DragAndDrop({
@@ -36,8 +36,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
const vectorSource = new VectorSource({
features: event.features
});
- map.addLayer(new VectorLayer({
- renderMode: 'image',
+ map.addLayer(new VectorImageLayer({
source: vectorSource
}));
map.getView().fit(vectorSource.getExtent());
diff --git a/examples/image-vector-layer.html b/examples/image-vector-layer.html
index 99613624d3..03350b09c1 100644
--- a/examples/image-vector-layer.html
+++ b/examples/image-vector-layer.html
@@ -1,9 +1,9 @@
---
layout: example.html
-title: Image Vector Layer
-shortdesc: Example of an image vector layer.
+title: Vector Image Layer
+shortdesc: Example of rendering vector data as an image layer.
docs: >
-
This example uses ol/layer/Vector with `renderMode: 'image'`. This mode results in faster rendering during interaction and animations, at the cost of less accurate rendering.
+ This example uses ol/layer/VectorImage for faster rendering during interaction and animations, at the cost of less accurate rendering.
tags: "vector, image"
---
diff --git a/examples/image-vector-layer.js b/examples/image-vector-layer.js
index 768ffa5198..16966e28ba 100644
--- a/examples/image-vector-layer.js
+++ b/examples/image-vector-layer.js
@@ -1,6 +1,7 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
+import VectorImageLayer from '../src/ol/layer/VectorImage.js';
import VectorLayer from '../src/ol/layer/Vector.js';
import VectorSource from '../src/ol/source/Vector.js';
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
@@ -19,8 +20,7 @@ const style = new Style({
const map = new Map({
layers: [
- new VectorLayer({
- renderMode: 'image',
+ new VectorImageLayer({
source: new VectorSource({
url: 'data/geojson/countries.geojson',
format: new GeoJSON()
diff --git a/src/ol/layer.js b/src/ol/layer.js
index c218524084..7da542afe6 100644
--- a/src/ol/layer.js
+++ b/src/ol/layer.js
@@ -9,4 +9,5 @@ export {default as Image} from './layer/Image.js';
export {default as Layer} from './layer/Layer.js';
export {default as Tile} from './layer/Tile.js';
export {default as Vector} from './layer/Vector.js';
+export {default as VectorImage} from './layer/VectorImage.js';
export {default as VectorTile} from './layer/VectorTile.js';
diff --git a/src/ol/layer/BaseVector.js b/src/ol/layer/BaseVector.js
index 98950bd2e9..57dc79eb90 100644
--- a/src/ol/layer/BaseVector.js
+++ b/src/ol/layer/BaseVector.js
@@ -3,7 +3,6 @@
*/
import LayerType from '../LayerType.js';
import Layer from './Layer.js';
-import VectorRenderType from './VectorRenderType.js';
import {assign} from '../obj.js';
import {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style.js';
@@ -28,11 +27,6 @@ import {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style.
* @property {number} [renderBuffer=100] The buffer in pixels around the viewport extent used by the
* renderer when getting features from the vector source for the rendering or hit-detection.
* Recommended value: the size of the largest symbol, line width or label.
- * @property {import("./VectorRenderType.js").default|string} [renderMode='vector'] Render mode for vector layers:
- * * `'image'`: Vector layers are rendered as images. Great performance, but point symbols and
- * texts are always rotated with the view and pixels are scaled during zoom animations.
- * * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering even during
- * animations, but slower performance.
* @property {import("../source/Vector.js").default} [source] Source.
* @property {import("../PluggableMap.js").default} [map] Sets the layer as overlay on a map. The map will not manage
* this layer in its layers collection, and the layer will be rendered on top. This is useful for
@@ -43,14 +37,12 @@ import {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style.
* means higher priority.
* @property {import("../style/Style.js").StyleLike} [style] Layer style. See
* {@link module:ol/style} for default style which will be used if this is not defined.
- * @property {boolean} [updateWhileAnimating=false] When set to `true` and `renderMode`
- * is `vector`, feature batches will be recreated during animations. This means that no
- * vectors will be shown clipped, but the setting will have a performance impact for large
- * amounts of vector data. When set to `false`, batches will be recreated when no animation
- * is active.
- * @property {boolean} [updateWhileInteracting=false] When set to `true` and `renderMode`
- * is `vector`, feature batches will be recreated during interactions. See also
- * `updateWhileAnimating`.
+ * @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will
+ * be recreated during animations. This means that no vectors will be shown clipped, but the
+ * setting will have a performance impact for large amounts of vector data. When set to `false`,
+ * batches will be recreated when no animation is active.
+ * @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will
+ * be recreated during interactions. See also `updateWhileAnimating`.
*/
@@ -131,12 +123,6 @@ class BaseVectorLayer extends Layer {
this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ?
options.updateWhileInteracting : false;
- /**
- * @private
- * @type {import("./VectorTileRenderType.js").default|string}
- */
- this.renderMode_ = options.renderMode || VectorRenderType.VECTOR;
-
/**
* The layer type.
* @protected
@@ -237,12 +223,6 @@ class BaseVectorLayer extends Layer {
this.changed();
}
- /**
- * @return {import("./VectorRenderType.js").default|string} The render mode.
- */
- getRenderMode() {
- return this.renderMode_;
- }
}
diff --git a/src/ol/layer/Heatmap.js b/src/ol/layer/Heatmap.js
index db062774c7..16f642f9dc 100644
--- a/src/ol/layer/Heatmap.js
+++ b/src/ol/layer/Heatmap.js
@@ -34,11 +34,6 @@ import Style from '../style/Style.js';
* @property {string|function(import("../Feature.js").default):number} [weight='weight'] The feature
* attribute to use for the weight or a function that returns a weight from a feature. Weight values
* should range from 0 to 1 (and values outside will be clamped to that range).
- * @property {import("./VectorRenderType.js").default|string} [renderMode='vector'] Render mode for vector layers:
- * * `'image'`: Vector layers are rendered as images. Great performance, but point symbols and
- * texts are always rotated with the view and pixels are scaled during zoom animations.
- * * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering even during
- * animations, but slower performance.
* @property {import("../source/Vector.js").default} [source] Source.
*/
diff --git a/src/ol/layer/VectorImage.js b/src/ol/layer/VectorImage.js
new file mode 100644
index 0000000000..42678c778d
--- /dev/null
+++ b/src/ol/layer/VectorImage.js
@@ -0,0 +1,40 @@
+/**
+ * @module ol/layer/VectorImage
+ */
+import BaseVectorLayer from './BaseVector.js';
+import CanvasVectorImageLayerRenderer from '../renderer/canvas/VectorImageLayer.js';
+
+/**
+ * @typedef {import("./BaseVector.js").Options} Options
+ */
+
+
+/**
+ * @classdesc
+ * Vector data that is rendered client-side.
+ * Note that any property set in the options is set as a {@link module:ol/Object~BaseObject}
+ * property on the layer object; for example, setting `title: 'My Title'` in the
+ * options means that `title` is observable, and has get/set accessors.
+ *
+ * @api
+ */
+class VectorImageLayer extends BaseVectorLayer {
+ /**
+ * @param {Options=} opt_options Options.
+ */
+ constructor(opt_options) {
+ super(opt_options);
+ }
+
+ /**
+ * Create a renderer for this layer.
+ * @return {import("../renderer/Layer.js").default} A layer renderer.
+ * @protected
+ */
+ createRenderer() {
+ return new CanvasVectorImageLayerRenderer(this);
+ }
+}
+
+
+export default VectorImageLayer;
diff --git a/src/ol/layer/VectorRenderType.js b/src/ol/layer/VectorRenderType.js
deleted file mode 100644
index 03f4c87006..0000000000
--- a/src/ol/layer/VectorRenderType.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- * @module ol/layer/VectorRenderType
- */
-
-/**
- * @enum {string}
- * Render mode for vector layers:
- * * `'image'`: Vector layers are rendered as images. Great performance, but
- * point symbols and texts are always rotated with the view and pixels are
- * scaled during zoom animations.
- * * `'vector'`: Vector layers are rendered as vectors. Most accurate rendering
- * even during animations, but slower performance.
- * @api
- */
-export default {
- IMAGE: 'image',
- VECTOR: 'vector'
-};
diff --git a/src/ol/layer/VectorTile.js b/src/ol/layer/VectorTile.js
index a40caa1057..7bafcc3943 100644
--- a/src/ol/layer/VectorTile.js
+++ b/src/ol/layer/VectorTile.js
@@ -86,22 +86,28 @@ class VectorTileLayer extends BaseVectorLayer {
constructor(opt_options) {
const options = opt_options ? opt_options : {};
+ const baseOptions = /** @type {Object} */ (assign({}, options));
+ delete baseOptions.preload;
+ delete baseOptions.useInterimTilesOnError;
+
+ super(/** @type {import("./Vector.js").Options} */ (baseOptions));
+
let renderMode = options.renderMode || VectorTileRenderType.HYBRID;
assert(renderMode == undefined ||
renderMode == VectorTileRenderType.IMAGE ||
renderMode == VectorTileRenderType.HYBRID ||
renderMode == VectorTileRenderType.VECTOR,
28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`
+
if (options.declutter && renderMode == VectorTileRenderType.IMAGE) {
renderMode = VectorTileRenderType.HYBRID;
}
- options.renderMode = renderMode;
- const baseOptions = /** @type {Object} */ (assign({}, options));
- delete baseOptions.preload;
- delete baseOptions.useInterimTilesOnError;
-
- super(/** @type {import("./Vector.js").Options} */ (baseOptions));
+ /**
+ * @private
+ * @type {VectorTileRenderType}
+ */
+ this.renderMode_ = renderMode;
this.setPreload(options.preload ? options.preload : 0);
this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?
@@ -124,6 +130,13 @@ class VectorTileLayer extends BaseVectorLayer {
return new CanvasVectorTileLayerRenderer(this);
}
+ /**
+ * @return {VectorTileRenderType} The render mode.
+ */
+ getRenderMode() {
+ return this.renderMode_;
+ }
+
/**
* Return the level as number to which we will preload tiles up to.
* @return {number} The level to preload tiles up to.
diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js
index 9436725087..677e7e48a8 100644
--- a/src/ol/renderer/canvas/ImageLayer.js
+++ b/src/ol/renderer/canvas/ImageLayer.js
@@ -2,14 +2,9 @@
* @module ol/renderer/canvas/ImageLayer
*/
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
-import ImageCanvas from '../../ImageCanvas.js';
import LayerType from '../../LayerType.js';
import ViewHint from '../../ViewHint.js';
-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 {getIntersection, isEmpty} from '../../extent.js';
import IntermediateCanvasRenderer from './IntermediateCanvas.js';
import {create as createTransform, compose as composeTransform} from '../../transform.js';
@@ -21,55 +16,23 @@ import {create as createTransform, compose as composeTransform} from '../../tran
class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
/**
- * @param {import("../../layer/Image.js").default|import("../../layer/Vector.js").default} imageLayer Image or vector layer.
+ * @param {import("../../layer/Image.js").default} imageLayer Image layer.
*/
constructor(imageLayer) {
-
super(imageLayer);
/**
- * @private
+ * @protected
* @type {?import("../../ImageBase.js").default}
*/
this.image_ = null;
/**
- * @private
+ * @protected
* @type {import("../../transform.js").Transform}
*/
this.imageTransform_ = createTransform();
- /**
- * @type {!Array}
- */
- this.skippedFeatures_ = [];
-
- /**
- * @private
- * @type {import("./VectorLayer.js").default}
- */
- this.vectorRenderer_ = null;
-
- if (imageLayer.getType() === LayerType.VECTOR) {
- for (let i = 0, ii = layerRendererConstructors.length; i < ii; ++i) {
- const ctor = layerRendererConstructors[i];
- if (ctor !== CanvasImageLayerRenderer && ctor['handles'](imageLayer)) {
- this.vectorRenderer_ = /** @type {import("./VectorLayer.js").default} */ (new ctor(imageLayer));
- break;
- }
- }
- }
-
- }
-
- /**
- * @inheritDoc
- */
- disposeInternal() {
- if (this.vectorRenderer_) {
- this.vectorRenderer_.dispose();
- }
- super.disposeInternal();
}
/**
@@ -103,9 +66,8 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
const hints = frameState.viewHints;
- const vectorRenderer = this.vectorRenderer_;
let renderedExtent = frameState.extent;
- if (!vectorRenderer && layerState.extent !== undefined) {
+ if (layerState.extent !== undefined) {
renderedExtent = getIntersection(renderedExtent, layerState.extent);
}
@@ -118,37 +80,9 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
projection = sourceProjection;
}
}
- let skippedFeatures = this.skippedFeatures_;
- if (vectorRenderer) {
- const context = vectorRenderer.context;
- const imageFrameState = /** @type {import("../../PluggableMap.js").FrameState} */ (assign({}, frameState, {
- size: [
- getWidth(renderedExtent) / viewResolution,
- getHeight(renderedExtent) / viewResolution
- ],
- viewState: /** @type {import("../../View.js").State} */ (assign({}, frameState.viewState, {
- rotation: 0
- }))
- }));
- const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort();
- image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) {
- if (vectorRenderer.prepareFrame(imageFrameState, layerState) &&
- (vectorRenderer.replayGroupChanged ||
- !equals(skippedFeatures, newSkippedFeatures))) {
- context.canvas.width = imageFrameState.size[0] * pixelRatio;
- context.canvas.height = imageFrameState.size[1] * pixelRatio;
- vectorRenderer.compose(context, imageFrameState, layerState);
- skippedFeatures = newSkippedFeatures;
- callback();
- }
- });
- } else {
- image = imageSource.getImage(
- renderedExtent, viewResolution, pixelRatio, projection);
- }
+ const image = imageSource.getImage(renderedExtent, viewResolution, pixelRatio, projection);
if (image && this.loadImage(image)) {
this.image_ = image;
- this.skippedFeatures_ = skippedFeatures;
}
}
@@ -177,16 +111,6 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
return !!this.image_;
}
- /**
- * @inheritDoc
- */
- forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) {
- if (this.vectorRenderer_) {
- return this.vectorRenderer_.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback);
- } else {
- return super.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback);
- }
- }
}
@@ -196,9 +120,7 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
* @return {boolean} The renderer can render the layer.
*/
CanvasImageLayerRenderer['handles'] = function(layer) {
- return layer.getType() === LayerType.IMAGE ||
- layer.getType() === LayerType.VECTOR &&
- /** @type {import("../../layer/Vector.js").default} */ (layer).getRenderMode() === VectorRenderType.IMAGE;
+ return layer.getType() === LayerType.IMAGE;
};
diff --git a/src/ol/renderer/canvas/VectorImageLayer.js b/src/ol/renderer/canvas/VectorImageLayer.js
new file mode 100644
index 0000000000..034018f793
--- /dev/null
+++ b/src/ol/renderer/canvas/VectorImageLayer.js
@@ -0,0 +1,129 @@
+/**
+ * @module ol/renderer/canvas/ImageLayer
+ */
+import ImageCanvas from '../../ImageCanvas.js';
+import ViewHint from '../../ViewHint.js';
+import {equals} from '../../array.js';
+import {getHeight, getWidth, isEmpty} from '../../extent.js';
+import {assign} from '../../obj.js';
+import CanvasImageLayerRenderer from './ImageLayer.js';
+import {compose as composeTransform} from '../../transform.js';
+import CanvasVectorLayerRenderer from './VectorLayer.js';
+
+/**
+ * @classdesc
+ * Canvas renderer for image layers.
+ * @api
+ */
+class CanvasVectorImageLayerRenderer extends CanvasImageLayerRenderer {
+
+ /**
+ * @param {import("../../layer/VectorImage.js").default} layer Vector image layer.
+ */
+ constructor(layer) {
+ super(layer);
+
+ /**
+ * @type {!Array}
+ */
+ this.skippedFeatures_ = [];
+
+ /**
+ * @private
+ * @type {import("./VectorLayer.js").default}
+ */
+ this.vectorRenderer_ = new CanvasVectorLayerRenderer(layer);
+
+ }
+
+ /**
+ * @inheritDoc
+ */
+ disposeInternal() {
+ this.vectorRenderer_.dispose();
+ super.disposeInternal();
+ }
+
+ /**
+ * @inheritDoc
+ */
+ prepareFrame(frameState, layerState) {
+ const pixelRatio = frameState.pixelRatio;
+ const size = frameState.size;
+ const viewState = frameState.viewState;
+ const viewCenter = viewState.center;
+ const viewResolution = viewState.resolution;
+
+ const hints = frameState.viewHints;
+ const vectorRenderer = this.vectorRenderer_;
+ const renderedExtent = frameState.extent;
+
+ if (!hints[ViewHint.ANIMATING] && !hints[ViewHint.INTERACTING] && !isEmpty(renderedExtent)) {
+ let skippedFeatures = this.skippedFeatures_;
+ const context = vectorRenderer.context;
+ const imageFrameState = /** @type {import("../../PluggableMap.js").FrameState} */ (assign({}, frameState, {
+ size: [
+ getWidth(renderedExtent) / viewResolution,
+ getHeight(renderedExtent) / viewResolution
+ ],
+ viewState: /** @type {import("../../View.js").State} */ (assign({}, frameState.viewState, {
+ rotation: 0
+ }))
+ }));
+ const newSkippedFeatures = Object.keys(imageFrameState.skippedFeatureUids).sort();
+ const image = new ImageCanvas(renderedExtent, viewResolution, pixelRatio, context.canvas, function(callback) {
+ if (vectorRenderer.prepareFrame(imageFrameState, layerState) &&
+ (vectorRenderer.replayGroupChanged ||
+ !equals(skippedFeatures, newSkippedFeatures))) {
+ context.canvas.width = imageFrameState.size[0] * pixelRatio;
+ context.canvas.height = imageFrameState.size[1] * pixelRatio;
+ vectorRenderer.compose(context, imageFrameState, layerState);
+ skippedFeatures = newSkippedFeatures;
+ callback();
+ }
+ });
+ if (this.loadImage(image)) {
+ this.image_ = image;
+ this.skippedFeatures_ = skippedFeatures;
+ }
+ }
+
+ if (this.image_) {
+ const image = this.image_;
+ const imageExtent = image.getExtent();
+ const imageResolution = image.getResolution();
+ const imagePixelRatio = image.getPixelRatio();
+ const scale = pixelRatio * imageResolution /
+ (viewResolution * imagePixelRatio);
+ const transform = composeTransform(this.imageTransform_,
+ pixelRatio * size[0] / 2, pixelRatio * size[1] / 2,
+ scale, scale,
+ 0,
+ imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
+ imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
+ composeTransform(this.coordinateToCanvasPixelTransform,
+ pixelRatio * size[0] / 2 - transform[4], pixelRatio * size[1] / 2 - transform[5],
+ pixelRatio / viewResolution, -pixelRatio / viewResolution,
+ 0,
+ -viewCenter[0], -viewCenter[1]);
+
+ this.renderedResolution = imageResolution * pixelRatio / imagePixelRatio;
+ }
+
+ return !!this.image_;
+ }
+
+ /**
+ * @inheritDoc
+ */
+ forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback) {
+ if (this.vectorRenderer_) {
+ return this.vectorRenderer_.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback);
+ } else {
+ return super.forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, callback);
+ }
+ }
+}
+
+
+export default CanvasVectorImageLayerRenderer;
diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js
index 60570990ec..01d2c73f39 100644
--- a/src/ol/renderer/canvas/VectorTileLayer.js
+++ b/src/ol/renderer/canvas/VectorTileLayer.js
@@ -134,7 +134,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @inheritDoc
*/
prepareFrame(frameState, layerState) {
- const layer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
+ const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const layerRevision = layer.getRevision();
if (this.renderedLayerRevision_ != layerRevision) {
this.renderedTiles.length = 0;
@@ -328,7 +328,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @inheritDoc
*/
postCompose(context, frameState, layerState) {
- const layer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
+ const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const renderMode = layer.getRenderMode();
if (renderMode != VectorTileRenderType.IMAGE) {
const declutterReplays = layer.getDeclutter() ? {} : null;
@@ -447,7 +447,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
* @private
*/
renderTileImage_(tile, pixelRatio, projection) {
- const layer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
+ const layer = /** @type {import("../../layer/VectorTile.js").default} */ (this.getLayer());
const replayState = tile.getReplayState(layer);
const revision = layer.getRevision();
const replays = IMAGE_REPLAYS[layer.getRenderMode()];
diff --git a/src/ol/source/Raster.js b/src/ol/source/Raster.js
index 816d01db60..aa952010fb 100644
--- a/src/ol/source/Raster.js
+++ b/src/ol/source/Raster.js
@@ -10,15 +10,14 @@ 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 ImageLayer from '../layer/Image.js';
import TileLayer from '../layer/Tile.js';
import {assign} from '../obj.js';
-import CanvasImageLayerRenderer from '../renderer/canvas/ImageLayer.js';
-import CanvasTileLayerRenderer from '../renderer/canvas/TileLayer.js';
-import ImageSource from './Image.js';
-import SourceState from './State.js';
import {create as createTransform} from '../transform.js';
+import ImageSource from './Image.js';
+import TileSource from './Tile.js';
+import SourceState from './State.js';
+import Source from './Source.js';
/**
@@ -113,7 +112,7 @@ class RasterSourceEvent extends Event {
/**
* @typedef {Object} Options
* @property {Array} sources Input
- * sources or layers. Vector layers must be configured with `renderMode: 'image'`.
+ * sources or layers. For vector data, use an VectorImage layer.
* @property {Operation} [operation] Raster operation.
* The operation will be called with data from input sources
* and the output will be assigned to the raster source.
@@ -490,42 +489,18 @@ function createRenderers(sources) {
* @return {import("../renderer/canvas/Layer.js").default} The renderer.
*/
function createRenderer(layerOrSource) {
- const tileSource = /** @type {import("./Tile.js").default} */ (layerOrSource);
- const imageSource = /** @type {import("./Image.js").default} */ (layerOrSource);
- const layer = /** @type {import("../layer/Layer.js").default} */ (layerOrSource);
- let renderer = null;
- if (typeof tileSource.getTile === 'function') {
- renderer = createTileRenderer(tileSource);
- } else if (typeof imageSource.getImage === 'function') {
- renderer = createImageRenderer(imageSource);
- } else if (layer.getType() === LayerType.TILE) {
- renderer = new CanvasTileLayerRenderer(/** @type {import("../layer/Tile.js").default} */ (layer));
- } else if (layer.getType() == LayerType.IMAGE || layer.getType() == LayerType.VECTOR) {
- renderer = new CanvasImageLayerRenderer(/** @type {import("../layer/Image.js").default} */ (layer));
+ // @type {import("../layer/Layer.js").default}
+ let layer;
+ if (layerOrSource instanceof Source) {
+ if (layerOrSource instanceof TileSource) {
+ layer = new TileLayer({source: layerOrSource});
+ } else if (layerOrSource instanceof ImageSource) {
+ layer = new ImageLayer({source: layerOrSource});
+ }
+ } else {
+ layer = layerOrSource;
}
- return renderer;
-}
-
-
-/**
- * Create an image renderer for the provided source.
- * @param {import("./Image.js").default} source The source.
- * @return {import("../renderer/canvas/Layer.js").default} The renderer.
- */
-function createImageRenderer(source) {
- const layer = new ImageLayer({source: source});
- return new CanvasImageLayerRenderer(layer);
-}
-
-
-/**
- * Create a tile renderer for the provided source.
- * @param {import("./Tile.js").default} source The source.
- * @return {import("../renderer/canvas/Layer.js").default} The renderer.
- */
-function createTileRenderer(source) {
- const layer = new TileLayer({source: source});
- return new CanvasTileLayerRenderer(layer);
+ return layer ? /** @type {import("../renderer/canvas/Layer.js").default} */ (layer.createRenderer()) : null;
}
diff --git a/test/rendering/ol/layer/vector.test.js b/test/rendering/ol/layer/vector.test.js
index ce3a1ac883..963e97b09f 100644
--- a/test/rendering/ol/layer/vector.test.js
+++ b/test/rendering/ol/layer/vector.test.js
@@ -99,33 +99,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('renders opacity correctly with renderMode: \'image\'', function(done) {
- createMap('canvas');
- const smallLine = new Feature(new LineString([
- [center[0], center[1] - 1],
- [center[0], center[1] + 1]
- ]));
- smallLine.setStyle(new Style({
- zIndex: -99,
- stroke: new Stroke({width: 75, color: 'red'})
- }));
- source.addFeature(smallLine);
- addPolygon(100);
- addCircle(200);
- addPolygon(250);
- addCircle(500);
- addPolygon(600);
- addPolygon(720);
- map.addLayer(new VectorLayer({
- renerMode: 'image',
- source: source
- }));
- map.once('postrender', function() {
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas.png',
- 17, done);
- });
- });
-
it('renders transparent layers correctly with the canvas renderer', function(done) {
createMap('canvas');
const smallLine = new Feature(new LineString([
@@ -165,46 +138,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('renders transparent layers correctly with renderMode: \'image\'', function(done) {
- createMap('canvas');
- const smallLine = new Feature(new LineString([
- [center[0], center[1] - 1],
- [center[0], center[1] + 1]
- ]));
- smallLine.setStyle([
- new Style({
- stroke: new Stroke({width: 75, color: 'red'})
- }),
- new Style({
- stroke: new Stroke({width: 45, color: 'white'})
- })
- ]);
- source.addFeature(smallLine);
- const smallLine2 = new Feature(new LineString([
- [center[0], center[1] - 1000],
- [center[0], center[1] + 1000]
- ]));
- smallLine2.setStyle([
- new Style({
- stroke: new Stroke({width: 35, color: 'blue'})
- }),
- new Style({
- stroke: new Stroke({width: 15, color: 'green'})
- })
- ]);
- source.addFeature(smallLine2);
-
- map.addLayer(new VectorLayer({
- renderMode: 'image',
- source: source,
- opacity: 0.5
- }));
- map.once('postrender', function() {
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-transparent.png',
- 7, done);
- });
- });
-
it('renders rotation correctly with the canvas renderer', function(done) {
createMap('canvas');
map.getView().setRotation(Math.PI + Math.PI / 4);
@@ -225,53 +158,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('renders rotation correctly with renderMode: \'image\'', function(done) {
- createMap('canvas');
- map.getView().setRotation(Math.PI + Math.PI / 4);
- addPolygon(300);
- addCircle(500);
- map.addLayer(new VectorLayer({
- renderMode: 'image',
- source: source,
- style: new Style({
- stroke: new Stroke({
- width: 2,
- color: 'black'
- })
- })
- }));
- map.once('postrender', function() {
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-rotated.png',
- 2.9, done);
- });
- });
-
- it('unskips features correctly with renderMode: \'image\'', function(done) {
- createMap('canvas');
- addCircle(500);
- addPolygon(300);
- map.skipFeature(source.getFeatures()[1]);
- map.addLayer(new VectorLayer({
- renderMode: 'image',
- source: source,
- style: new Style({
- fill: new Fill({
- color: 'rgba(255,0,0,0.5)'
- }),
- stroke: new Stroke({
- width: 2,
- color: 'black'
- })
- })
- }));
- map.renderSync();
- map.unskipFeature(source.getFeatures()[1]);
- map.once('postrender', function() {
- expectResemble(map, 'rendering/ol/layer/expected/vector.png',
- IMAGE_TOLERANCE, done);
- });
- });
-
it('renders fill/stroke batches correctly with the canvas renderer', function(done) {
createMap('canvas');
source = new VectorSource({
@@ -622,47 +508,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('declutters text with renderMode: \'image\'', function(done) {
- createMap('canvas');
- const layer = new VectorLayer({
- renderMode: 'image',
- source: source
- });
- map.addLayer(layer);
-
- const centerFeature = new Feature({
- geometry: new Point(center),
- text: 'center'
- });
- source.addFeature(centerFeature);
- source.addFeature(new Feature({
- geometry: new Point([center[0] - 540, center[1]]),
- text: 'west'
- }));
- source.addFeature(new Feature({
- geometry: new Point([center[0] + 540, center[1]]),
- text: 'east'
- }));
-
- layer.setDeclutter(true);
- layer.setStyle(function(feature) {
- return new Style({
- text: new Text({
- text: feature.get('text'),
- font: '12px sans-serif'
- })
- });
- });
-
- map.once('postrender', function() {
- const hitDetected = map.getFeaturesAtPixel([42, 42]);
- expect(hitDetected).to.have.length(1);
- expect(hitDetected[0]).to.equal(centerFeature);
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter.png',
- 2.2, done);
- });
- });
-
it('declutters text and respects z-index', function(done) {
createMap('canvas');
const layer = new VectorLayer({
@@ -742,46 +587,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('declutters images with renderMode: \'image\'', function(done) {
- createMap('canvas');
- const layer = new VectorLayer({
- renderMode: 'image',
- source: source
- });
- map.addLayer(layer);
-
- const centerFeature = new Feature({
- geometry: new Point(center)
- });
- source.addFeature(centerFeature);
- source.addFeature(new Feature({
- geometry: new Point([center[0] - 540, center[1]])
- }));
- source.addFeature(new Feature({
- geometry: new Point([center[0] + 540, center[1]])
- }));
-
- layer.setDeclutter(true);
- layer.setStyle(function(feature) {
- return new Style({
- image: new CircleStyle({
- radius: 15,
- stroke: new Stroke({
- color: 'blue'
- })
- })
- });
- });
-
- map.once('postrender', function() {
- const hitDetected = map.getFeaturesAtPixel([40, 40]);
- expect(hitDetected).to.have.length(1);
- expect(hitDetected[0]).to.equal(centerFeature);
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-image.png',
- IMAGE_TOLERANCE, done);
- });
- });
-
it('declutters images and respects z-index', function(done) {
createMap('canvas');
const layer = new VectorLayer({
@@ -908,49 +713,6 @@ describe('ol.rendering.layer.Vector', function() {
});
});
- it('declutters text along lines and images with renderMode: \'image\'', function(done) {
- createMap('canvas');
- const layer = new VectorLayer({
- source: source
- });
- map.addLayer(layer);
-
- const point = new Feature(new Point(center));
- point.setStyle(new Style({
- image: new CircleStyle({
- radius: 8,
- stroke: new Stroke({
- color: 'blue'
- })
- })
- }));
- const line = new Feature(new LineString([
- [center[0] - 650, center[1] - 200],
- [center[0] + 650, center[1] - 200]
- ]));
- line.setStyle(new Style({
- stroke: new Stroke({
- color: '#CCC',
- width: 12
- }),
- text: new Text({
- placement: 'line',
- text: 'east-west',
- font: '12px sans-serif'
- })
- }));
-
- source.addFeature(point);
- source.addFeature(line);
-
- layer.setDeclutter(true);
-
- map.once('postrender', function() {
- expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-line.png',
- IMAGE_TOLERANCE, done);
- });
- });
-
it('declutters text along lines and images with z-index', function(done) {
createMap('canvas');
const layer = new VectorLayer({
diff --git a/test/rendering/ol/layer/vectorimage.test.js b/test/rendering/ol/layer/vectorimage.test.js
new file mode 100644
index 0000000000..036f0f0654
--- /dev/null
+++ b/test/rendering/ol/layer/vectorimage.test.js
@@ -0,0 +1,289 @@
+import Circle from '../../../../src/ol/geom/Circle.js';
+import CircleStyle from '../../../../src/ol/style/Circle.js';
+import Feature from '../../../../src/ol/Feature.js';
+import Fill from '../../../../src/ol/style/Fill.js';
+import LineString from '../../../../src/ol/geom/LineString.js';
+import Map from '../../../../src/ol/Map.js';
+import Point from '../../../../src/ol/geom/Point.js';
+import Polygon from '../../../../src/ol/geom/Polygon.js';
+import Stroke from '../../../../src/ol/style/Stroke.js';
+import Style from '../../../../src/ol/style/Style.js';
+import Text from '../../../../src/ol/style/Text.js';
+import VectorImageLayer from '../../../../src/ol/layer/VectorImage.js';
+import VectorSource from '../../../../src/ol/source/Vector.js';
+import View from '../../../../src/ol/View.js';
+
+describe('ol.rendering.layer.VectorImage', function() {
+
+ const center = [1825927.7316762917, 6143091.089223046];
+
+ let map, source;
+ function createMap(renderer) {
+ source = new VectorSource();
+ map = new Map({
+ pixelRatio: 1,
+ target: createMapDiv(80, 80),
+ renderer: renderer,
+ view: new View({
+ center: center,
+ zoom: 13
+ })
+ });
+ }
+
+ afterEach(function() {
+ if (map) {
+ disposeMap(map);
+ }
+ map = null;
+ });
+
+ function addCircle(r) {
+ source.addFeature(new Feature(new Circle(center, r)));
+ }
+
+ function addPolygon(r) {
+ source.addFeature(new Feature(new Polygon([
+ [
+ [center[0] - r, center[1] - r],
+ [center[0] + r, center[1] - r],
+ [center[0] + r, center[1] + r],
+ [center[0] - r, center[1] + r],
+ [center[0] - r, center[1] - r]
+ ]
+ ])));
+ }
+
+ it('renders opacity correctly', function(done) {
+ createMap('canvas');
+ const smallLine = new Feature(new LineString([
+ [center[0], center[1] - 1],
+ [center[0], center[1] + 1]
+ ]));
+ smallLine.setStyle(new Style({
+ zIndex: -99,
+ stroke: new Stroke({width: 75, color: 'red'})
+ }));
+ source.addFeature(smallLine);
+ addPolygon(100);
+ addCircle(200);
+ addPolygon(250);
+ addCircle(500);
+ addPolygon(600);
+ addPolygon(720);
+ map.addLayer(new VectorImageLayer({
+ source: source
+ }));
+ map.once('postrender', function() {
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas.png',
+ 17, done);
+ });
+ });
+
+ it('renders transparent layers correctly', function(done) {
+ createMap('canvas');
+ const smallLine = new Feature(new LineString([
+ [center[0], center[1] - 1],
+ [center[0], center[1] + 1]
+ ]));
+ smallLine.setStyle([
+ new Style({
+ stroke: new Stroke({width: 75, color: 'red'})
+ }),
+ new Style({
+ stroke: new Stroke({width: 45, color: 'white'})
+ })
+ ]);
+ source.addFeature(smallLine);
+ const smallLine2 = new Feature(new LineString([
+ [center[0], center[1] - 1000],
+ [center[0], center[1] + 1000]
+ ]));
+ smallLine2.setStyle([
+ new Style({
+ stroke: new Stroke({width: 35, color: 'blue'})
+ }),
+ new Style({
+ stroke: new Stroke({width: 15, color: 'green'})
+ })
+ ]);
+ source.addFeature(smallLine2);
+
+ map.addLayer(new VectorImageLayer({
+ source: source,
+ opacity: 0.5
+ }));
+ map.once('postrender', function() {
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-transparent.png',
+ 7, done);
+ });
+ });
+
+ it('renders rotation correctly', function(done) {
+ createMap('canvas');
+ map.getView().setRotation(Math.PI + Math.PI / 4);
+ addPolygon(300);
+ addCircle(500);
+ map.addLayer(new VectorImageLayer({
+ source: source,
+ style: new Style({
+ stroke: new Stroke({
+ width: 2,
+ color: 'black'
+ })
+ })
+ }));
+ map.once('postrender', function() {
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-rotated.png',
+ 2.9, done);
+ });
+ });
+
+ it('unskips features correctly', function(done) {
+ createMap('canvas');
+ addCircle(500);
+ addPolygon(300);
+ map.skipFeature(source.getFeatures()[1]);
+ map.addLayer(new VectorImageLayer({
+ source: source,
+ style: new Style({
+ fill: new Fill({
+ color: 'rgba(255,0,0,0.5)'
+ }),
+ stroke: new Stroke({
+ width: 2,
+ color: 'black'
+ })
+ })
+ }));
+ map.renderSync();
+ map.unskipFeature(source.getFeatures()[1]);
+ map.once('postrender', function() {
+ expectResemble(map, 'rendering/ol/layer/expected/vector.png',
+ IMAGE_TOLERANCE, done);
+ });
+ });
+
+ it('declutters text', function(done) {
+ createMap('canvas');
+ const layer = new VectorImageLayer({
+ source: source
+ });
+ map.addLayer(layer);
+
+ const centerFeature = new Feature({
+ geometry: new Point(center),
+ text: 'center'
+ });
+ source.addFeature(centerFeature);
+ source.addFeature(new Feature({
+ geometry: new Point([center[0] - 540, center[1]]),
+ text: 'west'
+ }));
+ source.addFeature(new Feature({
+ geometry: new Point([center[0] + 540, center[1]]),
+ text: 'east'
+ }));
+
+ layer.setDeclutter(true);
+ layer.setStyle(function(feature) {
+ return new Style({
+ text: new Text({
+ text: feature.get('text'),
+ font: '12px sans-serif'
+ })
+ });
+ });
+
+ map.once('postrender', function() {
+ const hitDetected = map.getFeaturesAtPixel([42, 42]);
+ expect(hitDetected).to.have.length(1);
+ expect(hitDetected[0]).to.equal(centerFeature);
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter.png',
+ 2.2, done);
+ });
+ });
+
+ it('declutters images', function(done) {
+ createMap('canvas');
+ const layer = new VectorImageLayer({
+ source: source
+ });
+ map.addLayer(layer);
+
+ const centerFeature = new Feature({
+ geometry: new Point(center)
+ });
+ source.addFeature(centerFeature);
+ source.addFeature(new Feature({
+ geometry: new Point([center[0] - 540, center[1]])
+ }));
+ source.addFeature(new Feature({
+ geometry: new Point([center[0] + 540, center[1]])
+ }));
+
+ layer.setDeclutter(true);
+ layer.setStyle(function(feature) {
+ return new Style({
+ image: new CircleStyle({
+ radius: 15,
+ stroke: new Stroke({
+ color: 'blue'
+ })
+ })
+ });
+ });
+
+ map.once('postrender', function() {
+ const hitDetected = map.getFeaturesAtPixel([40, 40]);
+ expect(hitDetected).to.have.length(1);
+ expect(hitDetected[0]).to.equal(centerFeature);
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-image.png',
+ IMAGE_TOLERANCE, done);
+ });
+ });
+
+ it('declutters text along lines and images', function(done) {
+ createMap('canvas');
+ const layer = new VectorImageLayer({
+ source: source
+ });
+ map.addLayer(layer);
+
+ const point = new Feature(new Point(center));
+ point.setStyle(new Style({
+ image: new CircleStyle({
+ radius: 8,
+ stroke: new Stroke({
+ color: 'blue'
+ })
+ })
+ }));
+ const line = new Feature(new LineString([
+ [center[0] - 650, center[1] - 200],
+ [center[0] + 650, center[1] - 200]
+ ]));
+ line.setStyle(new Style({
+ stroke: new Stroke({
+ color: '#CCC',
+ width: 12
+ }),
+ text: new Text({
+ placement: 'line',
+ text: 'east-west',
+ font: '12px sans-serif'
+ })
+ }));
+
+ source.addFeature(point);
+ source.addFeature(line);
+
+ layer.setDeclutter(true);
+
+ map.once('postrender', function() {
+ expectResemble(map, 'rendering/ol/layer/expected/vector-canvas-declutter-line.png',
+ IMAGE_TOLERANCE, done);
+ });
+ });
+
+});
diff --git a/test/spec/ol/renderer/canvas/imagelayer.test.js b/test/spec/ol/renderer/canvas/imagelayer.test.js
index 3068bec1f2..3e7ca3a1c8 100644
--- a/test/spec/ol/renderer/canvas/imagelayer.test.js
+++ b/test/spec/ol/renderer/canvas/imagelayer.test.js
@@ -1,45 +1,16 @@
import Map from '../../../../../src/ol/Map.js';
import View from '../../../../../src/ol/View.js';
import ImageLayer from '../../../../../src/ol/layer/Image.js';
-import VectorLayer from '../../../../../src/ol/layer/Vector.js';
+import VectorImageLayer from '../../../../../src/ol/layer/VectorImage.js';
import Feature from '../../../../../src/ol/Feature.js';
import Point from '../../../../../src/ol/geom/Point.js';
import Projection from '../../../../../src/ol/proj/Projection.js';
import Static from '../../../../../src/ol/source/ImageStatic.js';
import VectorSource from '../../../../../src/ol/source/Vector.js';
-import CanvasImageLayerRenderer from '../../../../../src/ol/renderer/canvas/ImageLayer.js';
-import CanvasVectorLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorLayer.js';
describe('ol.renderer.canvas.ImageLayer', function() {
- describe('#dispose()', function() {
- let layer, imageRenderer, vectorRenderer;
-
- beforeEach(function() {
- layer = new VectorLayer({
- renderMode: 'image',
- source: new VectorSource()
- });
- imageRenderer = new CanvasImageLayerRenderer(layer);
- vectorRenderer = new CanvasVectorLayerRenderer(layer);
- imageRenderer.vectorRenderer_ = vectorRenderer;
- });
-
- afterEach(function() {
- imageRenderer.dispose();
- vectorRenderer.dispose();
- layer.dispose();
- });
-
- it('cleans up CanvasVectorRenderer', function() {
- const vectorRenderer = imageRenderer.vectorRenderer_;
- const spy = sinon.spy(vectorRenderer, 'dispose');
- imageRenderer.dispose();
- expect(spy.called).to.be(true);
- });
- });
-
describe('#forEachLayerAtCoordinate', function() {
let map, target, source;
@@ -99,8 +70,7 @@ describe('ol.renderer.canvas.ImageLayer', function() {
let map, div, layer;
beforeEach(function() {
- layer = new VectorLayer({
- renderMode: 'image',
+ layer = new VectorImageLayer({
source: new VectorSource({
features: [new Feature(new Point([0, 0]))]
})
diff --git a/test/spec/ol/renderer/canvas/vectorimage.test.js b/test/spec/ol/renderer/canvas/vectorimage.test.js
new file mode 100644
index 0000000000..5948f40a44
--- /dev/null
+++ b/test/spec/ol/renderer/canvas/vectorimage.test.js
@@ -0,0 +1,21 @@
+import VectorImageLayer from '../../../../../src/ol/layer/VectorImage.js';
+import VectorSource from '../../../../../src/ol/source/Vector.js';
+import CanvasVectorImageLayerRenderer from '../../../../../src/ol/renderer/canvas/VectorImageLayer.js';
+
+describe('ol/renderer/canvas/VectorImageLayer', function() {
+
+ describe('#dispose()', function() {
+
+ it('cleans up CanvasVectorRenderer', function() {
+ const layer = new VectorImageLayer({
+ source: new VectorSource()
+ });
+ const renderer = new CanvasVectorImageLayerRenderer(layer);
+ const spy = sinon.spy(renderer.vectorRenderer_, 'dispose');
+ renderer.dispose();
+ expect(spy.called).to.be(true);
+ });
+
+ });
+
+});
diff --git a/test/spec/ol/source/raster.test.js b/test/spec/ol/source/raster.test.js
index 5f4d3928ad..510b357750 100644
--- a/test/spec/ol/source/raster.test.js
+++ b/test/spec/ol/source/raster.test.js
@@ -2,7 +2,7 @@ import Map from '../../../../src/ol/Map.js';
import TileState from '../../../../src/ol/TileState.js';
import View from '../../../../src/ol/View.js';
import ImageLayer from '../../../../src/ol/layer/Image.js';
-import VectorLayer from '../../../../src/ol/layer/Vector.js';
+import VectorImageLayer from '../../../../src/ol/layer/VectorImage.js';
import Projection from '../../../../src/ol/proj/Projection.js';
import Static from '../../../../src/ol/source/ImageStatic.js';
import RasterSource from '../../../../src/ol/source/Raster.js';
@@ -47,8 +47,7 @@ where('Uint8ClampedArray').describe('ol.source.Raster', function() {
imageExtent: extent
});
- blueSource = new VectorLayer({
- renderMode: 'image',
+ blueSource = new VectorImageLayer({
source: new VectorSource({
features: [new Feature(new Point([0, 0]))]
}),