Add an image vector layer for rendering vectors to an image
This commit is contained in:
@@ -3,7 +3,7 @@ layout: example.html
|
|||||||
title: Drag-and-Drop Image Vector
|
title: Drag-and-Drop Image Vector
|
||||||
shortdesc: Example of using the drag-and-drop interaction with image vector rendering.
|
shortdesc: Example of using the drag-and-drop interaction with image vector rendering.
|
||||||
docs: >
|
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"
|
tags: "drag-and-drop-image-vector, gpx, geojson, igc, kml, topojson, vector, image"
|
||||||
cloak:
|
cloak:
|
||||||
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
- key: As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Map from '../src/ol/Map.js';
|
|||||||
import View from '../src/ol/View.js';
|
import View from '../src/ol/View.js';
|
||||||
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
|
import {GPX, GeoJSON, IGC, KML, TopoJSON} from '../src/ol/format.js';
|
||||||
import {defaults as defaultInteractions, DragAndDrop} from '../src/ol/interaction.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';
|
import {BingMaps, Vector as VectorSource} from '../src/ol/source.js';
|
||||||
|
|
||||||
const dragAndDropInteraction = new DragAndDrop({
|
const dragAndDropInteraction = new DragAndDrop({
|
||||||
@@ -36,8 +36,7 @@ dragAndDropInteraction.on('addfeatures', function(event) {
|
|||||||
const vectorSource = new VectorSource({
|
const vectorSource = new VectorSource({
|
||||||
features: event.features
|
features: event.features
|
||||||
});
|
});
|
||||||
map.addLayer(new VectorLayer({
|
map.addLayer(new VectorImageLayer({
|
||||||
renderMode: 'image',
|
|
||||||
source: vectorSource
|
source: vectorSource
|
||||||
}));
|
}));
|
||||||
map.getView().fit(vectorSource.getExtent());
|
map.getView().fit(vectorSource.getExtent());
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
layout: example.html
|
layout: example.html
|
||||||
title: Image Vector Layer
|
title: Vector Image Layer
|
||||||
shortdesc: Example of an image vector layer.
|
shortdesc: Example of rendering vector data as an image layer.
|
||||||
docs: >
|
docs: >
|
||||||
<p>This example uses <code>ol/layer/Vector</code> with `renderMode: 'image'`. This mode results in faster rendering during interaction and animations, at the cost of less accurate rendering.</p>
|
<p>This example uses <code>ol/layer/VectorImage</code> for faster rendering during interaction and animations, at the cost of less accurate rendering.</p>
|
||||||
tags: "vector, image"
|
tags: "vector, image"
|
||||||
---
|
---
|
||||||
<div id="map" class="map"></div>
|
<div id="map" class="map"></div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import Map from '../src/ol/Map.js';
|
import Map from '../src/ol/Map.js';
|
||||||
import View from '../src/ol/View.js';
|
import View from '../src/ol/View.js';
|
||||||
import GeoJSON from '../src/ol/format/GeoJSON.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 VectorLayer from '../src/ol/layer/Vector.js';
|
||||||
import VectorSource from '../src/ol/source/Vector.js';
|
import VectorSource from '../src/ol/source/Vector.js';
|
||||||
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
import {Fill, Stroke, Style, Text} from '../src/ol/style.js';
|
||||||
@@ -19,8 +20,7 @@ const style = new Style({
|
|||||||
|
|
||||||
const map = new Map({
|
const map = new Map({
|
||||||
layers: [
|
layers: [
|
||||||
new VectorLayer({
|
new VectorImageLayer({
|
||||||
renderMode: 'image',
|
|
||||||
source: new VectorSource({
|
source: new VectorSource({
|
||||||
url: 'data/geojson/countries.geojson',
|
url: 'data/geojson/countries.geojson',
|
||||||
format: new GeoJSON()
|
format: new GeoJSON()
|
||||||
|
|||||||
@@ -9,4 +9,5 @@ export {default as Image} from './layer/Image.js';
|
|||||||
export {default as Layer} from './layer/Layer.js';
|
export {default as Layer} from './layer/Layer.js';
|
||||||
export {default as Tile} from './layer/Tile.js';
|
export {default as Tile} from './layer/Tile.js';
|
||||||
export {default as Vector} from './layer/Vector.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';
|
export {default as VectorTile} from './layer/VectorTile.js';
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
import LayerType from '../LayerType.js';
|
import LayerType from '../LayerType.js';
|
||||||
import Layer from './Layer.js';
|
import Layer from './Layer.js';
|
||||||
import VectorRenderType from './VectorRenderType.js';
|
|
||||||
import {assign} from '../obj.js';
|
import {assign} from '../obj.js';
|
||||||
import {createDefaultStyle, toFunction as toStyleFunction} from '../style/Style.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
|
* @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.
|
* 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.
|
* 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("../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
|
* @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
|
* 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.
|
* means higher priority.
|
||||||
* @property {import("../style/Style.js").StyleLike} [style] Layer style. See
|
* @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.
|
* {@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`
|
* @property {boolean} [updateWhileAnimating=false] When set to `true`, feature batches will
|
||||||
* is `vector`, feature batches will be recreated during animations. This means that no
|
* be recreated during animations. This means that no vectors will be shown clipped, but the
|
||||||
* vectors will be shown clipped, but the setting will have a performance impact for large
|
* setting will have a performance impact for large amounts of vector data. When set to `false`,
|
||||||
* amounts of vector data. When set to `false`, batches will be recreated when no animation
|
* batches will be recreated when no animation is active.
|
||||||
* is active.
|
* @property {boolean} [updateWhileInteracting=false] When set to `true`, feature batches will
|
||||||
* @property {boolean} [updateWhileInteracting=false] When set to `true` and `renderMode`
|
* be recreated during interactions. See also `updateWhileAnimating`.
|
||||||
* is `vector`, feature batches will be recreated during interactions. See also
|
|
||||||
* `updateWhileAnimating`.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -131,12 +123,6 @@ class BaseVectorLayer extends Layer {
|
|||||||
this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ?
|
this.updateWhileInteracting_ = options.updateWhileInteracting !== undefined ?
|
||||||
options.updateWhileInteracting : false;
|
options.updateWhileInteracting : false;
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
* @type {import("./VectorTileRenderType.js").default|string}
|
|
||||||
*/
|
|
||||||
this.renderMode_ = options.renderMode || VectorRenderType.VECTOR;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The layer type.
|
* The layer type.
|
||||||
* @protected
|
* @protected
|
||||||
@@ -237,12 +223,6 @@ class BaseVectorLayer extends Layer {
|
|||||||
this.changed();
|
this.changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {import("./VectorRenderType.js").default|string} The render mode.
|
|
||||||
*/
|
|
||||||
getRenderMode() {
|
|
||||||
return this.renderMode_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,11 +34,6 @@ import Style from '../style/Style.js';
|
|||||||
* @property {string|function(import("../Feature.js").default):number} [weight='weight'] The feature
|
* @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
|
* 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).
|
* 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.
|
* @property {import("../source/Vector.js").default} [source] Source.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
40
src/ol/layer/VectorImage.js
Normal file
40
src/ol/layer/VectorImage.js
Normal file
@@ -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;
|
||||||
@@ -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'
|
|
||||||
};
|
|
||||||
@@ -86,22 +86,28 @@ class VectorTileLayer extends BaseVectorLayer {
|
|||||||
constructor(opt_options) {
|
constructor(opt_options) {
|
||||||
const options = opt_options ? 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;
|
let renderMode = options.renderMode || VectorTileRenderType.HYBRID;
|
||||||
assert(renderMode == undefined ||
|
assert(renderMode == undefined ||
|
||||||
renderMode == VectorTileRenderType.IMAGE ||
|
renderMode == VectorTileRenderType.IMAGE ||
|
||||||
renderMode == VectorTileRenderType.HYBRID ||
|
renderMode == VectorTileRenderType.HYBRID ||
|
||||||
renderMode == VectorTileRenderType.VECTOR,
|
renderMode == VectorTileRenderType.VECTOR,
|
||||||
28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`
|
28); // `renderMode` must be `'image'`, `'hybrid'` or `'vector'`
|
||||||
|
|
||||||
if (options.declutter && renderMode == VectorTileRenderType.IMAGE) {
|
if (options.declutter && renderMode == VectorTileRenderType.IMAGE) {
|
||||||
renderMode = VectorTileRenderType.HYBRID;
|
renderMode = VectorTileRenderType.HYBRID;
|
||||||
}
|
}
|
||||||
options.renderMode = renderMode;
|
|
||||||
|
|
||||||
const baseOptions = /** @type {Object} */ (assign({}, options));
|
/**
|
||||||
delete baseOptions.preload;
|
* @private
|
||||||
delete baseOptions.useInterimTilesOnError;
|
* @type {VectorTileRenderType}
|
||||||
|
*/
|
||||||
super(/** @type {import("./Vector.js").Options} */ (baseOptions));
|
this.renderMode_ = renderMode;
|
||||||
|
|
||||||
this.setPreload(options.preload ? options.preload : 0);
|
this.setPreload(options.preload ? options.preload : 0);
|
||||||
this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?
|
this.setUseInterimTilesOnError(options.useInterimTilesOnError !== undefined ?
|
||||||
@@ -124,6 +130,13 @@ class VectorTileLayer extends BaseVectorLayer {
|
|||||||
return new CanvasVectorTileLayerRenderer(this);
|
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 the level as number to which we will preload tiles up to.
|
||||||
* @return {number} The level to preload tiles up to.
|
* @return {number} The level to preload tiles up to.
|
||||||
|
|||||||
@@ -2,14 +2,9 @@
|
|||||||
* @module ol/renderer/canvas/ImageLayer
|
* @module ol/renderer/canvas/ImageLayer
|
||||||
*/
|
*/
|
||||||
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
|
import {ENABLE_RASTER_REPROJECTION} from '../../reproj/common.js';
|
||||||
import ImageCanvas from '../../ImageCanvas.js';
|
|
||||||
import LayerType from '../../LayerType.js';
|
import LayerType from '../../LayerType.js';
|
||||||
import ViewHint from '../../ViewHint.js';
|
import ViewHint from '../../ViewHint.js';
|
||||||
import {equals} from '../../array.js';
|
import {getIntersection, isEmpty} from '../../extent.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 './IntermediateCanvas.js';
|
import IntermediateCanvasRenderer from './IntermediateCanvas.js';
|
||||||
import {create as createTransform, compose as composeTransform} from '../../transform.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 {
|
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) {
|
constructor(imageLayer) {
|
||||||
|
|
||||||
super(imageLayer);
|
super(imageLayer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @protected
|
||||||
* @type {?import("../../ImageBase.js").default}
|
* @type {?import("../../ImageBase.js").default}
|
||||||
*/
|
*/
|
||||||
this.image_ = null;
|
this.image_ = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @protected
|
||||||
* @type {import("../../transform.js").Transform}
|
* @type {import("../../transform.js").Transform}
|
||||||
*/
|
*/
|
||||||
this.imageTransform_ = createTransform();
|
this.imageTransform_ = createTransform();
|
||||||
|
|
||||||
/**
|
|
||||||
* @type {!Array<string>}
|
|
||||||
*/
|
|
||||||
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 hints = frameState.viewHints;
|
||||||
|
|
||||||
const vectorRenderer = this.vectorRenderer_;
|
|
||||||
let renderedExtent = frameState.extent;
|
let renderedExtent = frameState.extent;
|
||||||
if (!vectorRenderer && layerState.extent !== undefined) {
|
if (layerState.extent !== undefined) {
|
||||||
renderedExtent = getIntersection(renderedExtent, layerState.extent);
|
renderedExtent = getIntersection(renderedExtent, layerState.extent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,37 +80,9 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
projection = sourceProjection;
|
projection = sourceProjection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let skippedFeatures = this.skippedFeatures_;
|
const image = imageSource.getImage(renderedExtent, viewResolution, pixelRatio, projection);
|
||||||
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);
|
|
||||||
}
|
|
||||||
if (image && this.loadImage(image)) {
|
if (image && this.loadImage(image)) {
|
||||||
this.image_ = image;
|
this.image_ = image;
|
||||||
this.skippedFeatures_ = skippedFeatures;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,16 +111,6 @@ class CanvasImageLayerRenderer extends IntermediateCanvasRenderer {
|
|||||||
return !!this.image_;
|
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.
|
* @return {boolean} The renderer can render the layer.
|
||||||
*/
|
*/
|
||||||
CanvasImageLayerRenderer['handles'] = function(layer) {
|
CanvasImageLayerRenderer['handles'] = function(layer) {
|
||||||
return layer.getType() === LayerType.IMAGE ||
|
return layer.getType() === LayerType.IMAGE;
|
||||||
layer.getType() === LayerType.VECTOR &&
|
|
||||||
/** @type {import("../../layer/Vector.js").default} */ (layer).getRenderMode() === VectorRenderType.IMAGE;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
129
src/ol/renderer/canvas/VectorImageLayer.js
Normal file
129
src/ol/renderer/canvas/VectorImageLayer.js
Normal file
@@ -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<string>}
|
||||||
|
*/
|
||||||
|
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;
|
||||||
@@ -134,7 +134,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
prepareFrame(frameState, layerState) {
|
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();
|
const layerRevision = layer.getRevision();
|
||||||
if (this.renderedLayerRevision_ != layerRevision) {
|
if (this.renderedLayerRevision_ != layerRevision) {
|
||||||
this.renderedTiles.length = 0;
|
this.renderedTiles.length = 0;
|
||||||
@@ -328,7 +328,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
postCompose(context, frameState, layerState) {
|
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();
|
const renderMode = layer.getRenderMode();
|
||||||
if (renderMode != VectorTileRenderType.IMAGE) {
|
if (renderMode != VectorTileRenderType.IMAGE) {
|
||||||
const declutterReplays = layer.getDeclutter() ? {} : null;
|
const declutterReplays = layer.getDeclutter() ? {} : null;
|
||||||
@@ -447,7 +447,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer {
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
renderTileImage_(tile, pixelRatio, projection) {
|
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 replayState = tile.getReplayState(layer);
|
||||||
const revision = layer.getRevision();
|
const revision = layer.getRevision();
|
||||||
const replays = IMAGE_REPLAYS[layer.getRenderMode()];
|
const replays = IMAGE_REPLAYS[layer.getRenderMode()];
|
||||||
|
|||||||
@@ -10,15 +10,14 @@ import Event from '../events/Event.js';
|
|||||||
import EventType from '../events/EventType.js';
|
import EventType from '../events/EventType.js';
|
||||||
import {Processor} from 'pixelworks/lib/index';
|
import {Processor} from 'pixelworks/lib/index';
|
||||||
import {equals, getCenter, getHeight, getWidth} from '../extent.js';
|
import {equals, getCenter, getHeight, getWidth} from '../extent.js';
|
||||||
import LayerType from '../LayerType.js';
|
|
||||||
import ImageLayer from '../layer/Image.js';
|
import ImageLayer from '../layer/Image.js';
|
||||||
import TileLayer from '../layer/Tile.js';
|
import TileLayer from '../layer/Tile.js';
|
||||||
import {assign} from '../obj.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 {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
|
* @typedef {Object} Options
|
||||||
* @property {Array<import("./Source.js").default|import("../layer/Layer.js").default>} sources Input
|
* @property {Array<import("./Source.js").default|import("../layer/Layer.js").default>} 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.
|
* @property {Operation} [operation] Raster operation.
|
||||||
* The operation will be called with data from input sources
|
* The operation will be called with data from input sources
|
||||||
* and the output will be assigned to the raster source.
|
* 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.
|
* @return {import("../renderer/canvas/Layer.js").default} The renderer.
|
||||||
*/
|
*/
|
||||||
function createRenderer(layerOrSource) {
|
function createRenderer(layerOrSource) {
|
||||||
const tileSource = /** @type {import("./Tile.js").default} */ (layerOrSource);
|
// @type {import("../layer/Layer.js").default}
|
||||||
const imageSource = /** @type {import("./Image.js").default} */ (layerOrSource);
|
let layer;
|
||||||
const layer = /** @type {import("../layer/Layer.js").default} */ (layerOrSource);
|
if (layerOrSource instanceof Source) {
|
||||||
let renderer = null;
|
if (layerOrSource instanceof TileSource) {
|
||||||
if (typeof tileSource.getTile === 'function') {
|
layer = new TileLayer({source: layerOrSource});
|
||||||
renderer = createTileRenderer(tileSource);
|
} else if (layerOrSource instanceof ImageSource) {
|
||||||
} else if (typeof imageSource.getImage === 'function') {
|
layer = new ImageLayer({source: layerOrSource});
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
return renderer;
|
} else {
|
||||||
}
|
layer = layerOrSource;
|
||||||
|
}
|
||||||
|
return layer ? /** @type {import("../renderer/canvas/Layer.js").default} */ (layer.createRenderer()) : null;
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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) {
|
it('renders transparent layers correctly with the canvas renderer', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
const smallLine = new Feature(new LineString([
|
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) {
|
it('renders rotation correctly with the canvas renderer', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
map.getView().setRotation(Math.PI + Math.PI / 4);
|
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) {
|
it('renders fill/stroke batches correctly with the canvas renderer', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
source = new VectorSource({
|
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) {
|
it('declutters text and respects z-index', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
const layer = new VectorLayer({
|
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) {
|
it('declutters images and respects z-index', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
const layer = new VectorLayer({
|
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) {
|
it('declutters text along lines and images with z-index', function(done) {
|
||||||
createMap('canvas');
|
createMap('canvas');
|
||||||
const layer = new VectorLayer({
|
const layer = new VectorLayer({
|
||||||
|
|||||||
289
test/rendering/ol/layer/vectorimage.test.js
Normal file
289
test/rendering/ol/layer/vectorimage.test.js
Normal file
@@ -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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -1,45 +1,16 @@
|
|||||||
import Map from '../../../../../src/ol/Map.js';
|
import Map from '../../../../../src/ol/Map.js';
|
||||||
import View from '../../../../../src/ol/View.js';
|
import View from '../../../../../src/ol/View.js';
|
||||||
import ImageLayer from '../../../../../src/ol/layer/Image.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 Feature from '../../../../../src/ol/Feature.js';
|
||||||
import Point from '../../../../../src/ol/geom/Point.js';
|
import Point from '../../../../../src/ol/geom/Point.js';
|
||||||
import Projection from '../../../../../src/ol/proj/Projection.js';
|
import Projection from '../../../../../src/ol/proj/Projection.js';
|
||||||
import Static from '../../../../../src/ol/source/ImageStatic.js';
|
import Static from '../../../../../src/ol/source/ImageStatic.js';
|
||||||
import VectorSource from '../../../../../src/ol/source/Vector.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('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() {
|
describe('#forEachLayerAtCoordinate', function() {
|
||||||
|
|
||||||
let map, target, source;
|
let map, target, source;
|
||||||
@@ -99,8 +70,7 @@ describe('ol.renderer.canvas.ImageLayer', function() {
|
|||||||
let map, div, layer;
|
let map, div, layer;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
layer = new VectorLayer({
|
layer = new VectorImageLayer({
|
||||||
renderMode: 'image',
|
|
||||||
source: new VectorSource({
|
source: new VectorSource({
|
||||||
features: [new Feature(new Point([0, 0]))]
|
features: [new Feature(new Point([0, 0]))]
|
||||||
})
|
})
|
||||||
|
|||||||
21
test/spec/ol/renderer/canvas/vectorimage.test.js
Normal file
21
test/spec/ol/renderer/canvas/vectorimage.test.js
Normal file
@@ -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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@ import Map from '../../../../src/ol/Map.js';
|
|||||||
import TileState from '../../../../src/ol/TileState.js';
|
import TileState from '../../../../src/ol/TileState.js';
|
||||||
import View from '../../../../src/ol/View.js';
|
import View from '../../../../src/ol/View.js';
|
||||||
import ImageLayer from '../../../../src/ol/layer/Image.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 Projection from '../../../../src/ol/proj/Projection.js';
|
||||||
import Static from '../../../../src/ol/source/ImageStatic.js';
|
import Static from '../../../../src/ol/source/ImageStatic.js';
|
||||||
import RasterSource from '../../../../src/ol/source/Raster.js';
|
import RasterSource from '../../../../src/ol/source/Raster.js';
|
||||||
@@ -47,8 +47,7 @@ where('Uint8ClampedArray').describe('ol.source.Raster', function() {
|
|||||||
imageExtent: extent
|
imageExtent: extent
|
||||||
});
|
});
|
||||||
|
|
||||||
blueSource = new VectorLayer({
|
blueSource = new VectorImageLayer({
|
||||||
renderMode: 'image',
|
|
||||||
source: new VectorSource({
|
source: new VectorSource({
|
||||||
features: [new Feature(new Point([0, 0]))]
|
features: [new Feature(new Point([0, 0]))]
|
||||||
}),
|
}),
|
||||||
|
|||||||
Reference in New Issue
Block a user