Add 'rendercomplete' event
This commit is contained in:
@@ -30,7 +30,7 @@ const map = new Map({
|
|||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('export-png').addEventListener('click', function() {
|
document.getElementById('export-png').addEventListener('click', function() {
|
||||||
map.once('postcompose', function(event) {
|
map.once('rendercomplete', function(event) {
|
||||||
const canvas = event.context.canvas;
|
const canvas = event.context.canvas;
|
||||||
if (navigator.msSaveBlob) {
|
if (navigator.msSaveBlob) {
|
||||||
navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
|
navigator.msSaveBlob(canvas.msToBlob(), 'map.png');
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import View from '../src/ol/View.js';
|
|||||||
import {defaults as defaultControls} from '../src/ol/control.js';
|
import {defaults as defaultControls} from '../src/ol/control.js';
|
||||||
import WKT from '../src/ol/format/WKT.js';
|
import WKT from '../src/ol/format/WKT.js';
|
||||||
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
|
||||||
import {unByKey} from '../src/ol/Observable.js';
|
|
||||||
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
|
||||||
|
|
||||||
const raster = new TileLayer({
|
const raster = new TileLayer({
|
||||||
@@ -48,9 +47,6 @@ const dims = {
|
|||||||
a5: [210, 148]
|
a5: [210, 148]
|
||||||
};
|
};
|
||||||
|
|
||||||
let loading = 0;
|
|
||||||
let loaded = 0;
|
|
||||||
|
|
||||||
const exportButton = document.getElementById('export-pdf');
|
const exportButton = document.getElementById('export-pdf');
|
||||||
|
|
||||||
exportButton.addEventListener('click', function() {
|
exportButton.addEventListener('click', function() {
|
||||||
@@ -66,57 +62,22 @@ exportButton.addEventListener('click', function() {
|
|||||||
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
const size = /** @type {module:ol/size~Size} */ (map.getSize());
|
||||||
const extent = map.getView().calculateExtent(size);
|
const extent = map.getView().calculateExtent(size);
|
||||||
|
|
||||||
const source = raster.getSource();
|
map.once('rendercomplete', function(event) {
|
||||||
|
|
||||||
const tileLoadStart = function() {
|
|
||||||
++loading;
|
|
||||||
};
|
|
||||||
|
|
||||||
let timer;
|
|
||||||
let keys = [];
|
|
||||||
|
|
||||||
function tileLoadEndFactory(canvas) {
|
|
||||||
return () => {
|
|
||||||
++loaded;
|
|
||||||
if (timer) {
|
|
||||||
clearTimeout(timer);
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
if (loading === loaded) {
|
|
||||||
timer = window.setTimeout(() => {
|
|
||||||
loading = 0;
|
|
||||||
loaded = 0;
|
|
||||||
const data = canvas.toDataURL('image/jpeg');
|
|
||||||
const pdf = new jsPDF('landscape', undefined, format);
|
|
||||||
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
|
|
||||||
pdf.save('map.pdf');
|
|
||||||
keys.forEach(unByKey);
|
|
||||||
keys = [];
|
|
||||||
map.setSize(size);
|
|
||||||
map.getView().fit(extent, {size});
|
|
||||||
map.renderSync();
|
|
||||||
exportButton.disabled = false;
|
|
||||||
document.body.style.cursor = 'auto';
|
|
||||||
}, 500);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
map.once('postcompose', function(event) {
|
|
||||||
const canvas = event.context.canvas;
|
const canvas = event.context.canvas;
|
||||||
const tileLoadEnd = tileLoadEndFactory(canvas);
|
const data = canvas.toDataURL('image/jpeg');
|
||||||
keys = [
|
const pdf = new jsPDF('landscape', undefined, format);
|
||||||
source.on('tileloadstart', tileLoadStart),
|
pdf.addImage(data, 'JPEG', 0, 0, dim[0], dim[1]);
|
||||||
source.on('tileloadend', tileLoadEnd),
|
pdf.save('map.pdf');
|
||||||
source.on('tileloaderror', tileLoadEnd)
|
// Reset original map size
|
||||||
];
|
map.setSize(size);
|
||||||
tileLoadEnd();
|
map.getView().fit(extent, {size});
|
||||||
|
exportButton.disabled = false;
|
||||||
|
document.body.style.cursor = 'auto';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Set print size
|
||||||
const printSize = [width, height];
|
const printSize = [width, height];
|
||||||
map.setSize(printSize);
|
map.setSize(printSize);
|
||||||
map.getView().fit(extent, {size: printSize});
|
map.getView().fit(extent, {size: printSize});
|
||||||
loaded = -1;
|
|
||||||
map.renderSync();
|
|
||||||
|
|
||||||
}, false);
|
}, false);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import MapBrowserEventType from './MapBrowserEventType.js';
|
|||||||
import MapEvent from './MapEvent.js';
|
import MapEvent from './MapEvent.js';
|
||||||
import MapEventType from './MapEventType.js';
|
import MapEventType from './MapEventType.js';
|
||||||
import MapProperty from './MapProperty.js';
|
import MapProperty from './MapProperty.js';
|
||||||
|
import RenderEventType from './render/EventType.js';
|
||||||
import BaseObject, {getChangeEventType} from './Object.js';
|
import BaseObject, {getChangeEventType} from './Object.js';
|
||||||
import ObjectEventType from './ObjectEventType.js';
|
import ObjectEventType from './ObjectEventType.js';
|
||||||
import TileQueue from './TileQueue.js';
|
import TileQueue from './TileQueue.js';
|
||||||
@@ -135,6 +136,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js
|
|||||||
* @fires module:ol/MapEvent~MapEvent
|
* @fires module:ol/MapEvent~MapEvent
|
||||||
* @fires module:ol/render/Event~RenderEvent#postcompose
|
* @fires module:ol/render/Event~RenderEvent#postcompose
|
||||||
* @fires module:ol/render/Event~RenderEvent#precompose
|
* @fires module:ol/render/Event~RenderEvent#precompose
|
||||||
|
* @fires module:ol/render/Event~RenderEvent#rendercomplete
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
class PluggableMap extends BaseObject {
|
class PluggableMap extends BaseObject {
|
||||||
@@ -961,6 +963,10 @@ class PluggableMap extends BaseObject {
|
|||||||
tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
|
tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (frameState && this.hasListener(MapEventType.RENDERCOMPLETE) && !frameState.animate &&
|
||||||
|
!this.tileQueue_.getTilesLoading() && !getLoading(this.getLayers().getArray())) {
|
||||||
|
this.renderer_.dispatchRenderEvent(RenderEventType.RENDERCOMPLETE, frameState);
|
||||||
|
}
|
||||||
|
|
||||||
const postRenderFunctions = this.postRenderFunctions_;
|
const postRenderFunctions = this.postRenderFunctions_;
|
||||||
for (let i = 0, ii = postRenderFunctions.length; i < ii; ++i) {
|
for (let i = 0, ii = postRenderFunctions.length; i < ii; ++i) {
|
||||||
@@ -1407,3 +1413,21 @@ function createOptionsInternal(options) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
export default PluggableMap;
|
export default PluggableMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Array<module:ol/layer/Base>} layers Layers.
|
||||||
|
* @return {boolean} Layers have sources that are still loading.
|
||||||
|
*/
|
||||||
|
function getLoading(layers) {
|
||||||
|
for (let i = 0, ii = layers.length; i < ii; ++i) {
|
||||||
|
const layer = layers[i];
|
||||||
|
if (layer instanceof LayerGroup) {
|
||||||
|
return getLoading(layer.getLayers().getArray());
|
||||||
|
}
|
||||||
|
const source = layers[i].getSource();
|
||||||
|
if (source && source.loading) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,5 +20,12 @@ export default {
|
|||||||
* @event module:ol/render/Event~RenderEvent#render
|
* @event module:ol/render/Event~RenderEvent#render
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
RENDER: 'render'
|
RENDER: 'render',
|
||||||
|
/**
|
||||||
|
* Triggered when rendering is complete, i.e. all sources and tiles have
|
||||||
|
* finished loading for the current viewport, and all tiles are faded in.
|
||||||
|
* @event module:ol/render/Event~RenderEvent#rendercomplete
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
RENDERCOMPLETE: 'rendercomplete'
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -332,6 +332,13 @@ function expireIconCache(map, frameState) {
|
|||||||
MapRenderer.prototype.renderFrame = VOID;
|
MapRenderer.prototype.renderFrame = VOID;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {module:ol/render/EventType} type Event type.
|
||||||
|
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
|
||||||
|
*/
|
||||||
|
MapRenderer.prototype.dispatchRenderEvent = VOID;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {module:ol/layer/Layer~State} state1 First layer state.
|
* @param {module:ol/layer/Layer~State} state1 First layer state.
|
||||||
* @param {module:ol/layer/Layer~State} state2 Second layer state.
|
* @param {module:ol/layer/Layer~State} state2 Second layer state.
|
||||||
|
|||||||
@@ -69,9 +69,8 @@ class CanvasMapRenderer extends MapRenderer {
|
|||||||
/**
|
/**
|
||||||
* @param {module:ol/render/EventType} type Event type.
|
* @param {module:ol/render/EventType} type Event type.
|
||||||
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
|
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
|
||||||
* @private
|
|
||||||
*/
|
*/
|
||||||
dispatchComposeEvent_(type, frameState) {
|
dispatchRenderEvent(type, frameState) {
|
||||||
const map = this.getMap();
|
const map = this.getMap();
|
||||||
const context = this.context_;
|
const context = this.context_;
|
||||||
if (map.hasListener(type)) {
|
if (map.hasListener(type)) {
|
||||||
@@ -135,7 +134,7 @@ class CanvasMapRenderer extends MapRenderer {
|
|||||||
|
|
||||||
this.calculateMatrices2D(frameState);
|
this.calculateMatrices2D(frameState);
|
||||||
|
|
||||||
this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, frameState);
|
this.dispatchRenderEvent(RenderEventType.PRECOMPOSE, frameState);
|
||||||
|
|
||||||
const layerStatesArray = frameState.layerStatesArray;
|
const layerStatesArray = frameState.layerStatesArray;
|
||||||
stableSort(layerStatesArray, sortByZIndex);
|
stableSort(layerStatesArray, sortByZIndex);
|
||||||
@@ -164,7 +163,7 @@ class CanvasMapRenderer extends MapRenderer {
|
|||||||
context.restore();
|
context.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, frameState);
|
this.dispatchRenderEvent(RenderEventType.POSTCOMPOSE, frameState);
|
||||||
|
|
||||||
if (!this.renderedVisible_) {
|
if (!this.renderedVisible_) {
|
||||||
this.canvas_.style.display = '';
|
this.canvas_.style.display = '';
|
||||||
|
|||||||
@@ -249,9 +249,8 @@ class WebGLMapRenderer extends MapRenderer {
|
|||||||
/**
|
/**
|
||||||
* @param {module:ol/render/EventType} type Event type.
|
* @param {module:ol/render/EventType} type Event type.
|
||||||
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
|
* @param {module:ol/PluggableMap~FrameState} frameState Frame state.
|
||||||
* @private
|
|
||||||
*/
|
*/
|
||||||
dispatchComposeEvent_(type, frameState) {
|
dispatchRenderEvent(type, frameState) {
|
||||||
const map = this.getMap();
|
const map = this.getMap();
|
||||||
if (map.hasListener(type)) {
|
if (map.hasListener(type)) {
|
||||||
const context = this.context_;
|
const context = this.context_;
|
||||||
@@ -411,7 +410,7 @@ class WebGLMapRenderer extends MapRenderer {
|
|||||||
this.textureCache_.set((-frameState.index).toString(), null);
|
this.textureCache_.set((-frameState.index).toString(), null);
|
||||||
++this.textureCacheFrameMarkerCount_;
|
++this.textureCacheFrameMarkerCount_;
|
||||||
|
|
||||||
this.dispatchComposeEvent_(RenderEventType.PRECOMPOSE, frameState);
|
this.dispatchRenderEvent(RenderEventType.PRECOMPOSE, frameState);
|
||||||
|
|
||||||
/** @type {Array<module:ol/layer/Layer~State>} */
|
/** @type {Array<module:ol/layer/Layer~State>} */
|
||||||
const layerStatesToDraw = [];
|
const layerStatesToDraw = [];
|
||||||
@@ -470,7 +469,7 @@ class WebGLMapRenderer extends MapRenderer {
|
|||||||
frameState.animate = true;
|
frameState.animate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dispatchComposeEvent_(RenderEventType.POSTCOMPOSE, frameState);
|
this.dispatchRenderEvent(RenderEventType.POSTCOMPOSE, frameState);
|
||||||
|
|
||||||
this.scheduleRemoveUnusedLayerRenderers(frameState);
|
this.scheduleRemoveUnusedLayerRenderers(frameState);
|
||||||
this.scheduleExpireIconCache(frameState);
|
this.scheduleExpireIconCache(frameState);
|
||||||
|
|||||||
@@ -201,16 +201,19 @@ class ImageSource extends Source {
|
|||||||
const image = /** @type {module:ol/Image} */ (event.target);
|
const image = /** @type {module:ol/Image} */ (event.target);
|
||||||
switch (image.getState()) {
|
switch (image.getState()) {
|
||||||
case ImageState.LOADING:
|
case ImageState.LOADING:
|
||||||
|
this.loading = true;
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADSTART,
|
new ImageSourceEvent(ImageSourceEventType.IMAGELOADSTART,
|
||||||
image));
|
image));
|
||||||
break;
|
break;
|
||||||
case ImageState.LOADED:
|
case ImageState.LOADED:
|
||||||
|
this.loading = false;
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,
|
new ImageSourceEvent(ImageSourceEventType.IMAGELOADEND,
|
||||||
image));
|
image));
|
||||||
break;
|
break;
|
||||||
case ImageState.ERROR:
|
case ImageState.ERROR:
|
||||||
|
this.loading = false;
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new ImageSourceEvent(ImageSourceEventType.IMAGELOADERROR,
|
new ImageSourceEvent(ImageSourceEventType.IMAGELOADERROR,
|
||||||
image));
|
image));
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ class Source extends BaseObject {
|
|||||||
*/
|
*/
|
||||||
this.attributions_ = this.adaptAttributions_(options.attributions);
|
this.attributions_ = this.adaptAttributions_(options.attributions);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This source is currently loading data. Sources that defer loading to the
|
||||||
|
* map's tile queue never set this to `true`.
|
||||||
|
* @type {boolean}
|
||||||
|
*/
|
||||||
|
this.loading = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @private
|
* @private
|
||||||
* @type {module:ol/source/State}
|
* @type {module:ol/source/State}
|
||||||
|
|||||||
@@ -871,6 +871,7 @@ class VectorSource extends Source {
|
|||||||
loadFeatures(extent, resolution, projection) {
|
loadFeatures(extent, resolution, projection) {
|
||||||
const loadedExtentsRtree = this.loadedExtentsRtree_;
|
const loadedExtentsRtree = this.loadedExtentsRtree_;
|
||||||
const extentsToLoad = this.strategy_(extent, resolution);
|
const extentsToLoad = this.strategy_(extent, resolution);
|
||||||
|
this.loading = false;
|
||||||
for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
|
for (let i = 0, ii = extentsToLoad.length; i < ii; ++i) {
|
||||||
const extentToLoad = extentsToLoad[i];
|
const extentToLoad = extentsToLoad[i];
|
||||||
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,
|
const alreadyLoaded = loadedExtentsRtree.forEachInExtent(extentToLoad,
|
||||||
@@ -884,6 +885,7 @@ class VectorSource extends Source {
|
|||||||
if (!alreadyLoaded) {
|
if (!alreadyLoaded) {
|
||||||
this.loader_.call(this, extentToLoad, resolution, projection);
|
this.loader_.call(this, extentToLoad, resolution, projection);
|
||||||
loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
|
loadedExtentsRtree.insert(extentToLoad, {extent: extentToLoad.slice()});
|
||||||
|
this.loading = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Feature from '../../../src/ol/Feature.js';
|
import Feature from '../../../src/ol/Feature.js';
|
||||||
|
import ImageState from '../../../src/ol/ImageState.js';
|
||||||
import Map from '../../../src/ol/Map.js';
|
import Map from '../../../src/ol/Map.js';
|
||||||
import MapEvent from '../../../src/ol/MapEvent.js';
|
import MapEvent from '../../../src/ol/MapEvent.js';
|
||||||
import Overlay from '../../../src/ol/Overlay.js';
|
import Overlay from '../../../src/ol/Overlay.js';
|
||||||
@@ -7,14 +8,18 @@ import LineString from '../../../src/ol/geom/LineString.js';
|
|||||||
import {TOUCH} from '../../../src/ol/has.js';
|
import {TOUCH} from '../../../src/ol/has.js';
|
||||||
import {focus} from '../../../src/ol/events/condition.js';
|
import {focus} from '../../../src/ol/events/condition.js';
|
||||||
import {defaults as defaultInteractions} from '../../../src/ol/interaction.js';
|
import {defaults as defaultInteractions} from '../../../src/ol/interaction.js';
|
||||||
|
import {get as getProjection} from '../../../src/ol/proj.js';
|
||||||
|
import GeoJSON from '../../../src/ol/format/GeoJSON.js';
|
||||||
import DragPan from '../../../src/ol/interaction/DragPan.js';
|
import DragPan from '../../../src/ol/interaction/DragPan.js';
|
||||||
import DoubleClickZoom from '../../../src/ol/interaction/DoubleClickZoom.js';
|
import DoubleClickZoom from '../../../src/ol/interaction/DoubleClickZoom.js';
|
||||||
import Interaction from '../../../src/ol/interaction/Interaction.js';
|
import Interaction from '../../../src/ol/interaction/Interaction.js';
|
||||||
import MouseWheelZoom from '../../../src/ol/interaction/MouseWheelZoom.js';
|
import MouseWheelZoom from '../../../src/ol/interaction/MouseWheelZoom.js';
|
||||||
import PinchZoom from '../../../src/ol/interaction/PinchZoom.js';
|
import PinchZoom from '../../../src/ol/interaction/PinchZoom.js';
|
||||||
|
import ImageLayer from '../../../src/ol/layer/Image.js';
|
||||||
import TileLayer from '../../../src/ol/layer/Tile.js';
|
import TileLayer from '../../../src/ol/layer/Tile.js';
|
||||||
import VectorLayer from '../../../src/ol/layer/Vector.js';
|
import VectorLayer from '../../../src/ol/layer/Vector.js';
|
||||||
import IntermediateCanvasRenderer from '../../../src/ol/renderer/canvas/IntermediateCanvas.js';
|
import IntermediateCanvasRenderer from '../../../src/ol/renderer/canvas/IntermediateCanvas.js';
|
||||||
|
import ImageStatic from '../../../src/ol/source/ImageStatic.js';
|
||||||
import VectorSource from '../../../src/ol/source/Vector.js';
|
import VectorSource from '../../../src/ol/source/Vector.js';
|
||||||
import XYZ from '../../../src/ol/source/XYZ.js';
|
import XYZ from '../../../src/ol/source/XYZ.js';
|
||||||
|
|
||||||
@@ -188,6 +193,60 @@ describe('ol.Map', function() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('rendercomplete event', function() {
|
||||||
|
|
||||||
|
let map;
|
||||||
|
beforeEach(function() {
|
||||||
|
const target = document.createElement('div');
|
||||||
|
target.style.width = target.style.height = '100px';
|
||||||
|
document.body.appendChild(target);
|
||||||
|
map = new Map({
|
||||||
|
target: target,
|
||||||
|
layers: [
|
||||||
|
new TileLayer({
|
||||||
|
source: new XYZ({
|
||||||
|
url: 'spec/ol/data/osm-{z}-{x}-{y}.png'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
new ImageLayer({
|
||||||
|
source: new ImageStatic({
|
||||||
|
url: 'spec/ol/data/osm-0-0-0.png',
|
||||||
|
imageExtent: getProjection('EPSG:3857').getExtent(),
|
||||||
|
projection: 'EPSG:3857'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
new VectorLayer({
|
||||||
|
source: new VectorSource({
|
||||||
|
url: 'spec/ol/data/point.json',
|
||||||
|
format: new GeoJSON()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
document.body.removeChild(map.getTargetElement());
|
||||||
|
map.setTarget(null);
|
||||||
|
map.dispose();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers when all tiles and sources are loaded and faded in', function(done) {
|
||||||
|
map.once('rendercomplete', function() {
|
||||||
|
const layers = map.getLayers().getArray();
|
||||||
|
expect(map.tileQueue_.getTilesLoading()).to.be(0);
|
||||||
|
expect(layers[1].getSource().image_.getState()).to.be(ImageState.LOADED);
|
||||||
|
expect(layers[2].getSource().getFeatures().length).to.be(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
map.setView(new View({
|
||||||
|
center: [0, 0],
|
||||||
|
zoom: 0
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#getFeaturesAtPixel', function() {
|
describe('#getFeaturesAtPixel', function() {
|
||||||
|
|
||||||
let target, map;
|
let target, map;
|
||||||
|
|||||||
Reference in New Issue
Block a user