diff --git a/examples/mapbox-vector-tiles-advanced.html b/examples/mapbox-vector-tiles-advanced.html
index 62db367a3c..77e0c9c62a 100644
--- a/examples/mapbox-vector-tiles-advanced.html
+++ b/examples/mapbox-vector-tiles-advanced.html
@@ -3,7 +3,7 @@ layout: example.html
title: Advanced Mapbox Vector Tiles
shortdesc: Example of a Mapbox vector tiles map with custom tile grid.
docs: >
- A vector tiles map which reuses the same tiles for subsequent zoom levels to save bandwidth on mobile devices. **Note**: No map will be visible when the access token has expired.
+ A vector tiles map which reuses the same source tiles for subsequent zoom levels to save bandwidth on mobile devices. **Note**: No map will be visible when the access token has expired.
tags: "mapbox, vector, tiles, mobile"
resources:
- resources/mapbox-streets-v6-style.js
diff --git a/examples/mapbox-vector-tiles-advanced.js b/examples/mapbox-vector-tiles-advanced.js
index 31718d77e5..3dfc4950c5 100644
--- a/examples/mapbox-vector-tiles-advanced.js
+++ b/examples/mapbox-vector-tiles-advanced.js
@@ -15,25 +15,16 @@ goog.require('ol.tilegrid.TileGrid');
var key = 'pk.eyJ1IjoiYWhvY2V2YXIiLCJhIjoiRk1kMWZaSSJ9.E5BkluenyWQMsBLsuByrmg';
-// For how many zoom levels do we want to use the same vector tiles?
-// 1 means "use tiles from all zoom levels". 2 means "use the same tiles for 2
-// subsequent zoom levels".
-var reuseZoomLevels = 2;
-
-// Offset of loaded tiles from web mercator zoom level 0.
-// 0 means "At map zoom level 0, use tiles from zoom level 0". 1 means "At map
-// zoom level 0, use tiles from zoom level 1".
-var zoomOffset = 1;
-
-// Calculation of tile urls
+// Calculation of resolutions that match zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
var resolutions = [];
-for (var z = zoomOffset / reuseZoomLevels; z <= 22 / reuseZoomLevels; ++z) {
- resolutions.push(156543.03392804097 / Math.pow(2, z * reuseZoomLevels));
+for (var i = 0; i <= 7; ++i) {
+ resolutions.push(156543.03392804097 / Math.pow(2, i * 2));
}
+// Calculation of tile urls for zoom levels 1, 3, 5, 7, 9, 11, 13, 15.
function tileUrlFunction(tileCoord) {
return ('https://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
'{z}/{x}/{y}.vector.pbf?access_token=' + key)
- .replace('{z}', String(tileCoord[0] * reuseZoomLevels + zoomOffset))
+ .replace('{z}', String(tileCoord[0] * 2 - 1))
.replace('{x}', String(tileCoord[1]))
.replace('{y}', String(-tileCoord[2] - 1))
.replace('{a-d}', 'abcd'.substr(
@@ -43,8 +34,6 @@ function tileUrlFunction(tileCoord) {
var map = new ol.Map({
layers: [
new ol.layer.VectorTile({
- renderMode: 'vector',
- preload: Infinity,
source: new ol.source.VectorTile({
attributions: '© Mapbox ' +
'© ' +
@@ -52,9 +41,10 @@ var map = new ol.Map({
format: new ol.format.MVT(),
tileGrid: new ol.tilegrid.TileGrid({
extent: ol.proj.get('EPSG:3857').getExtent(),
- resolutions: resolutions
+ resolutions: resolutions,
+ tileSize: 512
}),
- tilePixelRatio: 16,
+ tilePixelRatio: 8,
tileUrlFunction: tileUrlFunction
}),
style: createMapboxStreetsV6Style()
diff --git a/externs/olx.js b/externs/olx.js
index a47e678e71..ad3e61083c 100644
--- a/externs/olx.js
+++ b/externs/olx.js
@@ -4864,7 +4864,7 @@ olx.source.VectorTileOptions.prototype.state;
/**
- * Class used to instantiate image tiles. Default is {@link ol.VectorTile}.
+ * Class used to instantiate vector tiles. Default is {@link ol.VectorTile}.
* @type {function(new: ol.VectorTile, ol.TileCoord,
* ol.TileState, string, ol.format.Feature,
* ol.TileLoadFunctionType)|undefined}
diff --git a/src/ol/imagetile.js b/src/ol/imagetile.js
index c10af92364..a474374a01 100644
--- a/src/ol/imagetile.js
+++ b/src/ol/imagetile.js
@@ -70,8 +70,8 @@ ol.ImageTile.prototype.disposeInternal = function() {
/**
- * Get the image element for this tile.
- * @inheritDoc
+ * Get the HTML image element for this tile (may be a Canvas, Image, or Video).
+ * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
* @api
*/
ol.ImageTile.prototype.getImage = function() {
diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js
index a7f4b38279..1a3b71ea6e 100644
--- a/src/ol/renderer/canvas/vectortilelayer.js
+++ b/src/ol/renderer/canvas/vectortilelayer.js
@@ -1,6 +1,7 @@
goog.provide('ol.renderer.canvas.VectorTileLayer');
goog.require('ol');
+goog.require('ol.TileState');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.proj');
@@ -12,7 +13,6 @@ goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.render.replay');
goog.require('ol.renderer.canvas.TileLayer');
goog.require('ol.renderer.vector');
-goog.require('ol.size');
goog.require('ol.transform');
@@ -23,6 +23,9 @@ goog.require('ol.transform');
*/
ol.renderer.canvas.VectorTileLayer = function(layer) {
+ /**
+ * @type {CanvasRenderingContext2D}
+ */
this.context = null;
ol.renderer.canvas.TileLayer.call(this, layer);
@@ -95,12 +98,12 @@ ol.renderer.canvas.VectorTileLayer.prototype.prepareFrame = function(frameState,
/**
- * @param {ol.VectorTile} tile Tile.
+ * @param {ol.VectorImageTile} tile Tile.
* @param {olx.FrameState} frameState Frame state.
* @private
*/
-ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
- frameState) {
+ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(
+ tile, frameState) {
var layer = this.getLayer();
var pixelRatio = frameState.pixelRatio;
var projection = frameState.viewState.projection;
@@ -113,78 +116,89 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
return;
}
- replayState.replayGroup = null;
- replayState.dirty = false;
+ var sourceTiles = tile.getSourceTiles();
+ for (var t = 0, tt = sourceTiles.length; t < tt; ++t) {
+ var sourceTile = sourceTiles[t];
+ sourceTile.replayGroup = null;
+ replayState.dirty = false;
- var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var tileGrid = source.getTileGrid();
- var tileCoord = tile.tileCoord;
- var tileProjection = tile.getProjection();
- var resolution = tileGrid.getResolution(tileCoord[0]);
- var extent, reproject, tileResolution;
- if (tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS) {
- var tilePixelRatio = tileResolution = source.getTilePixelRatio();
- var tileSize = ol.size.toSize(tileGrid.getTileSize(tileCoord[0]));
- extent = [0, 0, tileSize[0] * tilePixelRatio, tileSize[1] * tilePixelRatio];
- } else {
- tileResolution = resolution;
- extent = tileGrid.getTileCoordExtent(tileCoord);
- if (!ol.proj.equivalent(projection, tileProjection)) {
- reproject = true;
- tile.setProjection(projection);
- }
- }
- replayState.dirty = false;
- var replayGroup = new ol.render.canvas.ReplayGroup(0, extent,
- tileResolution, source.getOverlaps(), layer.getRenderBuffer());
- var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
- tileResolution, pixelRatio);
-
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @this {ol.renderer.canvas.VectorTileLayer}
- */
- function renderFeature(feature) {
- var styles;
- var styleFunction = feature.getStyleFunction();
- if (styleFunction) {
- styles = styleFunction.call(/** @type {ol.Feature} */ (feature), resolution);
+ var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
+ var sourceTileGrid = source.getTileGrid();
+ var sourceTileCoord = sourceTile.tileCoord;
+ var tileProjection = sourceTile.getProjection();
+ var tileGrid = source.getTileGridForProjection(projection);
+ var resolution = tileGrid.getResolution(tile.tileCoord[0]);
+ var sourceTileResolution = sourceTileGrid.getResolution(sourceTile.tileCoord[0]);
+ var tileExtent = tileGrid.getTileCoordExtent(tile.wrappedTileCoord);
+ var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
+ var sharedExtent = ol.extent.getIntersection(tileExtent, sourceTileExtent);
+ var extent, reproject, tileResolution;
+ if (tileProjection.getUnits() == ol.proj.Units.TILE_PIXELS) {
+ var tilePixelRatio = tileResolution = source.getTilePixelRatio();
+ var transform = ol.transform.compose(this.tmpTransform_,
+ 0, 0,
+ 1 / sourceTileResolution * tilePixelRatio, -1 / sourceTileResolution * tilePixelRatio,
+ 0,
+ -sourceTileExtent[0], -sourceTileExtent[3]);
+ extent = (ol.transform.apply(transform, [sharedExtent[0], sharedExtent[3]])
+ .concat(ol.transform.apply(transform, [sharedExtent[2], sharedExtent[1]])));
} else {
- styleFunction = layer.getStyleFunction();
+ tileResolution = resolution;
+ extent = sharedExtent;
+ if (!ol.proj.equivalent(projection, tileProjection)) {
+ reproject = true;
+ sourceTile.setProjection(projection);
+ }
+ }
+ replayState.dirty = false;
+ var replayGroup = new ol.render.canvas.ReplayGroup(0, extent,
+ tileResolution, source.getOverlaps(), layer.getRenderBuffer());
+ var squaredTolerance = ol.renderer.vector.getSquaredTolerance(
+ tileResolution, pixelRatio);
+
+ /**
+ * @param {ol.Feature|ol.render.Feature} feature Feature.
+ * @this {ol.renderer.canvas.VectorTileLayer}
+ */
+ var renderFeature = function(feature) {
+ var styles;
+ var styleFunction = feature.getStyleFunction();
if (styleFunction) {
- styles = styleFunction(feature, resolution);
+ styles = styleFunction.call(/** @type {ol.Feature} */ (feature), resolution);
+ } else {
+ styleFunction = layer.getStyleFunction();
+ if (styleFunction) {
+ styles = styleFunction(feature, resolution);
+ }
}
- }
- if (styles) {
- if (!Array.isArray(styles)) {
- styles = [styles];
+ if (styles) {
+ if (!Array.isArray(styles)) {
+ styles = [styles];
+ }
+ var dirty = this.renderFeature(feature, squaredTolerance, styles,
+ replayGroup);
+ this.dirty_ = this.dirty_ || dirty;
+ replayState.dirty = replayState.dirty || dirty;
}
- var dirty = this.renderFeature(feature, squaredTolerance, styles,
- replayGroup);
- this.dirty_ = this.dirty_ || dirty;
- replayState.dirty = replayState.dirty || dirty;
+ };
+
+ var features = sourceTile.getFeatures();
+ if (renderOrder && renderOrder !== replayState.renderedRenderOrder) {
+ features.sort(renderOrder);
}
- }
-
- var features = tile.getFeatures();
- if (renderOrder && renderOrder !== replayState.renderedRenderOrder) {
- features.sort(renderOrder);
- }
- var feature;
- for (var i = 0, ii = features.length; i < ii; ++i) {
- feature = features[i];
- if (reproject) {
- feature.getGeometry().transform(tileProjection, projection);
+ var feature;
+ for (var i = 0, ii = features.length; i < ii; ++i) {
+ feature = features[i];
+ if (reproject) {
+ feature.getGeometry().transform(tileProjection, projection);
+ }
+ renderFeature.call(this, feature);
}
- renderFeature.call(this, feature);
+ replayGroup.finish();
+ sourceTile.setReplayGroup(tile.tileCoord.toString(), replayGroup);
}
-
- replayGroup.finish();
-
replayState.renderedRevision = revision;
replayState.renderedRenderOrder = renderOrder;
- replayState.replayGroup = replayGroup;
- replayState.resolution = NaN;
};
@@ -193,10 +207,10 @@ ol.renderer.canvas.VectorTileLayer.prototype.createReplayGroup_ = function(tile,
*/
ol.renderer.canvas.VectorTileLayer.prototype.drawTileImage = function(
tile, frameState, layerState, x, y, w, h, gutter) {
- var vectorTile = /** @type {ol.VectorTile} */ (tile);
- this.createReplayGroup_(vectorTile, frameState);
+ var vectorImageTile = /** @type {ol.VectorImageTile} */ (tile);
+ this.createReplayGroup_(vectorImageTile, frameState);
if (this.context) {
- this.renderTileImage_(vectorTile, frameState, layerState);
+ this.renderTileImage_(vectorImageTile, frameState, layerState);
ol.renderer.canvas.TileLayer.prototype.drawTileImage.apply(this, arguments);
}
};
@@ -213,54 +227,62 @@ ol.renderer.canvas.VectorTileLayer.prototype.forEachFeatureAtCoordinate = functi
/** @type {Object.} */
var features = {};
- /** @type {Array.} */
- var replayables = this.renderedTiles;
+ /** @type {Array.} */
+ var renderedTiles = this.renderedTiles;
var source = /** @type {ol.source.VectorTile} */ (layer.getSource());
- var tileGrid = source.getTileGrid();
- var found, tileSpaceCoordinate;
+ var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
+ var sourceTileGrid = source.getTileGrid();
+ var bufferedExtent, found, tileSpaceCoordinate;
var i, ii, origin, replayGroup;
var tile, tileCoord, tileExtent, tilePixelRatio, tileResolution;
- for (i = 0, ii = replayables.length; i < ii; ++i) {
- tile = replayables[i];
+ for (i = 0, ii = renderedTiles.length; i < ii; ++i) {
+ tile = renderedTiles[i];
tileCoord = tile.tileCoord;
- tileExtent = source.getTileGrid().getTileCoordExtent(tileCoord, this.tmpExtent);
- if (!ol.extent.containsCoordinate(ol.extent.buffer(tileExtent, hitTolerance * resolution), coordinate)) {
+ tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
+ bufferedExtent = ol.extent.buffer(tileExtent, hitTolerance * resolution, bufferedExtent);
+ if (!ol.extent.containsCoordinate(bufferedExtent, coordinate)) {
continue;
}
- if (tile.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) {
- origin = ol.extent.getTopLeft(tileExtent);
- tilePixelRatio = source.getTilePixelRatio();
- tileResolution = tileGrid.getResolution(tileCoord[0]) / tilePixelRatio;
- tileSpaceCoordinate = [
- (coordinate[0] - origin[0]) / tileResolution,
- (origin[1] - coordinate[1]) / tileResolution
- ];
- resolution = tilePixelRatio;
- } else {
- tileSpaceCoordinate = coordinate;
+ var sourceTiles = tile.getSourceTiles();
+ for (var t = 0, tt = sourceTiles.length; t < tt; ++t) {
+ var sourceTile = sourceTiles[t];
+ if (sourceTile.getProjection().getUnits() === ol.proj.Units.TILE_PIXELS) {
+ var sourceTileCoord = sourceTile.tileCoord;
+ var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
+ origin = ol.extent.getTopLeft(sourceTileExtent);
+ tilePixelRatio = source.getTilePixelRatio();
+ tileResolution = sourceTileGrid.getResolution(sourceTileCoord[0]) / tilePixelRatio;
+ tileSpaceCoordinate = [
+ (coordinate[0] - origin[0]) / tileResolution,
+ (origin[1] - coordinate[1]) / tileResolution
+ ];
+ resolution = tilePixelRatio;
+ } else {
+ tileSpaceCoordinate = coordinate;
+ }
+ replayGroup = sourceTile.getReplayGroup(tile.tileCoord);
+ found = found || replayGroup.forEachFeatureAtCoordinate(
+ tileSpaceCoordinate, resolution, rotation, hitTolerance, {},
+ /**
+ * @param {ol.Feature|ol.render.Feature} feature Feature.
+ * @return {?} Callback result.
+ */
+ function(feature) {
+ var key = ol.getUid(feature).toString();
+ if (!(key in features)) {
+ features[key] = true;
+ return callback.call(thisArg, feature, layer);
+ }
+ });
}
- replayGroup = tile.getReplayState().replayGroup;
- found = found || replayGroup.forEachFeatureAtCoordinate(
- tileSpaceCoordinate, resolution, rotation, hitTolerance, {},
- /**
- * @param {ol.Feature|ol.render.Feature} feature Feature.
- * @return {?} Callback result.
- */
- function(feature) {
- var key = ol.getUid(feature).toString();
- if (!(key in features)) {
- features[key] = true;
- return callback.call(thisArg, feature, layer);
- }
- });
}
return found;
};
/**
- * @param {ol.Tile} tile Tile.
+ * @param {ol.VectorTile} tile Tile.
* @param {olx.FrameState} frameState Frame state.
* @return {ol.Transform} transform Transform.
* @private
@@ -308,7 +330,9 @@ ol.renderer.canvas.VectorTileLayer.prototype.handleStyleImageChange_ = function(
* @inheritDoc
*/
ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, frameState, layerState) {
- var renderMode = this.getLayer().getRenderMode();
+ var layer = this.getLayer();
+ var source = layer.getSource();
+ var renderMode = layer.getRenderMode();
var replays = ol.renderer.canvas.VectorTileLayer.VECTOR_REPLAYS[renderMode];
if (replays) {
var pixelRatio = frameState.pixelRatio;
@@ -317,40 +341,55 @@ ol.renderer.canvas.VectorTileLayer.prototype.postCompose = function(context, fra
var offsetX = Math.round(pixelRatio * size[0] / 2);
var offsetY = Math.round(pixelRatio * size[1] / 2);
var tiles = this.renderedTiles;
+ var tilePixelRatio = layer.getSource().getTilePixelRatio();
+ var sourceTileGrid = source.getTileGrid();
+ var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
var clips = [];
var zs = [];
for (var i = tiles.length - 1; i >= 0; --i) {
- var tile = /** @type {ol.VectorTile} */ (tiles[i]);
- // Create a clip mask for regions in this low resolution tile that are
- // already filled by a higher resolution tile
- var transform = this.getReplayTransform_(tile, frameState);
- var currentClip = tile.getReplayState().replayGroup.getClipCoords(transform);
- var currentZ = tile.tileCoord[0];
- context.save();
- context.globalAlpha = layerState.opacity;
- ol.render.canvas.rotateAtOffset(context, -rotation, offsetX, offsetY);
- for (var j = 0, jj = clips.length; j < jj; ++j) {
- var clip = clips[j];
- if (currentZ < zs[j]) {
- context.beginPath();
- // counter-clockwise (outer ring) for current tile
- context.moveTo(currentClip[0], currentClip[1]);
- context.lineTo(currentClip[2], currentClip[3]);
- context.lineTo(currentClip[4], currentClip[5]);
- context.lineTo(currentClip[6], currentClip[7]);
- // clockwise (inner ring) for higher resolution tile
- context.moveTo(clip[6], clip[7]);
- context.lineTo(clip[4], clip[5]);
- context.lineTo(clip[2], clip[3]);
- context.lineTo(clip[0], clip[1]);
- context.clip();
- }
+ var tile = /** @type {ol.VectorImageTile} */ (tiles[i]);
+ if (tile.getState() == ol.TileState.ABORT) {
+ continue;
+ }
+ var tileCoord = tile.tileCoord;
+ var worldOffset = tileGrid.getTileCoordExtent(tileCoord)[0] -
+ tileGrid.getTileCoordExtent(tile.wrappedTileCoord)[0];
+ var sourceTiles = tile.getSourceTiles();
+ for (var t = 0, tt = sourceTiles.length; t < tt; ++t) {
+ var sourceTile = sourceTiles[t];
+ var currentZ = sourceTile.tileCoord[0];
+ var sourceResolution = sourceTileGrid.getResolution(currentZ);
+ var transform = this.getReplayTransform_(sourceTile, frameState);
+ ol.transform.translate(transform, worldOffset * tilePixelRatio / sourceResolution, 0);
+ var replayGroup = sourceTile.getReplayGroup(tileCoord.toString());
+ var currentClip = replayGroup.getClipCoords(transform);
+ context.save();
+ context.globalAlpha = layerState.opacity;
+ ol.render.canvas.rotateAtOffset(context, -rotation, offsetX, offsetY);
+ // Create a clip mask for regions in this low resolution tile that are
+ // already filled by a higher resolution tile
+ for (var j = 0, jj = clips.length; j < jj; ++j) {
+ var clip = clips[j];
+ if (currentZ < zs[j]) {
+ context.beginPath();
+ // counter-clockwise (outer ring) for current tile
+ context.moveTo(currentClip[0], currentClip[1]);
+ context.lineTo(currentClip[2], currentClip[3]);
+ context.lineTo(currentClip[4], currentClip[5]);
+ context.lineTo(currentClip[6], currentClip[7]);
+ // clockwise (inner ring) for higher resolution tile
+ context.moveTo(clip[6], clip[7]);
+ context.lineTo(clip[4], clip[5]);
+ context.lineTo(clip[2], clip[3]);
+ context.lineTo(clip[0], clip[1]);
+ context.clip();
+ }
+ }
+ replayGroup.replay(context, pixelRatio, transform, rotation, {}, replays);
+ context.restore();
+ clips.push(currentClip);
+ zs.push(currentZ);
}
- var replayGroup = tile.getReplayState().replayGroup;
- replayGroup.replay(context, pixelRatio, transform, rotation, {}, replays);
- context.restore();
- clips.push(currentClip);
- zs.push(currentZ);
}
}
ol.renderer.canvas.TileLayer.prototype.postCompose.apply(this, arguments);
@@ -386,7 +425,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderFeature = function(feature, s
/**
- * @param {ol.VectorTile} tile Tile.
+ * @param {ol.VectorImageTile} tile Tile.
* @param {olx.FrameState} frameState Frame state.
* @param {ol.LayerState} layerState Layer state.
* @private
@@ -399,28 +438,39 @@ ol.renderer.canvas.VectorTileLayer.prototype.renderTileImage_ = function(
var replays = ol.renderer.canvas.VectorTileLayer.IMAGE_REPLAYS[layer.getRenderMode()];
if (replays && replayState.renderedTileRevision !== revision) {
replayState.renderedTileRevision = revision;
- var tileCoord = tile.tileCoord;
- var z = tile.tileCoord[0];
+ var tileCoord = tile.wrappedTileCoord;
+ var z = tileCoord[0];
var pixelRatio = frameState.pixelRatio;
var source = layer.getSource();
- var tileGrid = source.getTileGrid();
+ var sourceTileGrid = source.getTileGrid();
+ var tileGrid = source.getTileGridForProjection(frameState.viewState.projection);
+ var resolution = tileGrid.getResolution(z);
var tilePixelRatio = source.getTilePixelRatio();
- var transform = ol.transform.reset(this.tmpTransform_);
- if (tile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
- var renderPixelRatio = pixelRatio / tilePixelRatio;
- ol.transform.scale(transform, renderPixelRatio, renderPixelRatio);
- } else {
- var resolution = tileGrid.getResolution(z);
- var pixelScale = pixelRatio / resolution;
- var tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent);
- ol.transform.scale(transform, pixelScale, -pixelScale);
- ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
- }
-
var context = tile.getContext();
var size = source.getTilePixelSize(z, pixelRatio, frameState.viewState.projection);
context.canvas.width = size[0];
context.canvas.height = size[1];
- replayState.replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
+ var tileExtent = tileGrid.getTileCoordExtent(tileCoord);
+ var sourceTiles = tile.getSourceTiles();
+ for (var i = 0, ii = sourceTiles.length; i < ii; ++i) {
+ var sourceTile = sourceTiles[i];
+ var sourceTileCoord = sourceTile.tileCoord;
+ var pixelScale = pixelRatio / resolution;
+ var transform = ol.transform.reset(this.tmpTransform_);
+ if (sourceTile.getProjection().getUnits() == ol.proj.Units.TILE_PIXELS) {
+ var sourceTileExtent = sourceTileGrid.getTileCoordExtent(sourceTileCoord, this.tmpExtent);
+ var sourceResolution = sourceTileGrid.getResolution(sourceTileCoord[0]);
+ var renderPixelRatio = pixelRatio / tilePixelRatio * sourceResolution / resolution;
+ ol.transform.scale(transform, renderPixelRatio, renderPixelRatio);
+ var offsetX = (sourceTileExtent[0] - tileExtent[0]) / sourceResolution * tilePixelRatio;
+ var offsetY = (tileExtent[3] - sourceTileExtent[3]) / sourceResolution * tilePixelRatio;
+ ol.transform.translate(transform, Math.round(offsetX), Math.round(offsetY));
+ } else {
+ ol.transform.scale(transform, pixelScale, -pixelScale);
+ ol.transform.translate(transform, -tileExtent[0], -tileExtent[3]);
+ }
+ var replayGroup = sourceTile.getReplayGroup(tile.tileCoord.toString());
+ replayGroup.replay(context, pixelRatio, transform, 0, {}, replays);
+ }
}
};
diff --git a/src/ol/reproj/tile.js b/src/ol/reproj/tile.js
index 36b83f0371..95c77e85c0 100644
--- a/src/ol/reproj/tile.js
+++ b/src/ol/reproj/tile.js
@@ -202,7 +202,8 @@ ol.reproj.Tile.prototype.disposeInternal = function() {
/**
- * @inheritDoc
+ * Get the HTML Canvas element for this tile.
+ * @return {HTMLCanvasElement} Canvas.
*/
ol.reproj.Tile.prototype.getImage = function() {
return this.canvas_;
diff --git a/src/ol/source/tiledebug.js b/src/ol/source/tiledebug.js
index 3e301386cc..4325f16124 100644
--- a/src/ol/source/tiledebug.js
+++ b/src/ol/source/tiledebug.js
@@ -91,7 +91,6 @@ ol.inherits(ol.source.TileDebug.Tile_, ol.Tile);
/**
* Get the image element for this tile.
* @return {HTMLCanvasElement} Image.
- * @override
*/
ol.source.TileDebug.Tile_.prototype.getImage = function() {
if (this.canvas_) {
diff --git a/src/ol/source/tileutfgrid.js b/src/ol/source/tileutfgrid.js
index 0166caace1..70d469e04d 100644
--- a/src/ol/source/tileutfgrid.js
+++ b/src/ol/source/tileutfgrid.js
@@ -320,7 +320,6 @@ ol.inherits(ol.source.TileUTFGrid.Tile_, ol.Tile);
/**
* Get the image element for this tile.
* @return {Image} Image.
- * @override
*/
ol.source.TileUTFGrid.Tile_.prototype.getImage = function() {
return null;
diff --git a/src/ol/source/vectortile.js b/src/ol/source/vectortile.js
index 007b75dc86..1f296ef31a 100644
--- a/src/ol/source/vectortile.js
+++ b/src/ol/source/vectortile.js
@@ -2,9 +2,11 @@ goog.provide('ol.source.VectorTile');
goog.require('ol');
goog.require('ol.TileState');
+goog.require('ol.VectorImageTile');
goog.require('ol.VectorTile');
goog.require('ol.events');
goog.require('ol.events.EventType');
+goog.require('ol.proj');
goog.require('ol.size');
goog.require('ol.source.UrlTile');
@@ -35,9 +37,8 @@ ol.source.VectorTile = function(options) {
opaque: false,
projection: options.projection,
state: options.state,
- tileGrid: options.tileGrid,
tileLoadFunction: options.tileLoadFunction ?
- options.tileLoadFunction : ol.VectorTile.defaultLoadFunction,
+ options.tileLoadFunction : ol.VectorImageTile.defaultLoadFunction,
tileUrlFunction: options.tileUrlFunction,
tilePixelRatio: options.tilePixelRatio,
url: options.url,
@@ -51,6 +52,18 @@ ol.source.VectorTile = function(options) {
*/
this.format_ = options.format ? options.format : null;
+ /**
+ * @private
+ * @type {Object.}
+ */
+ this.sourceTiles_ = {};
+
+ /**
+ * @type {ol.tilegrid.TileGrid}
+ */
+ this.sourceTileGrid_ = options.tileGrid ||
+ this.getTileGridForProjection(ol.proj.get(options.projection || 'EPSG:3857'));
+
/**
* @private
* @type {boolean}
@@ -89,11 +102,13 @@ ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projectio
tileCoord, projection);
var tileUrl = urlTileCoord ?
this.tileUrlFunction(urlTileCoord, pixelRatio, projection) : undefined;
- var tile = new this.tileClass(
+ var tile = new ol.VectorImageTile(
tileCoord,
tileUrl !== undefined ? ol.TileState.IDLE : ol.TileState.EMPTY,
tileUrl !== undefined ? tileUrl : '',
- this.format_, this.tileLoadFunction);
+ this.format_, this.tileLoadFunction, urlTileCoord, this.tileUrlFunction,
+ this.sourceTileGrid_, this.getTileGridForProjection(projection),
+ this.sourceTiles_, pixelRatio, projection, this.tileClass);
ol.events.listen(tile, ol.events.EventType.CHANGE,
this.handleTileChange, this);
@@ -103,6 +118,14 @@ ol.source.VectorTile.prototype.getTile = function(z, x, y, pixelRatio, projectio
};
+/**
+ * @inheritDoc
+ */
+ol.source.VectorTile.prototype.getTileGrid = function() {
+ return this.sourceTileGrid_;
+};
+
+
/**
* @inheritDoc
*/
@@ -117,6 +140,6 @@ ol.source.VectorTile.prototype.getTilePixelRatio = function(opt_pixelRatio) {
* @inheritDoc
*/
ol.source.VectorTile.prototype.getTilePixelSize = function(z, pixelRatio, projection) {
- var tileSize = ol.size.toSize(this.tileGrid.getTileSize(z));
+ var tileSize = ol.size.toSize(this.getTileGridForProjection(projection).getTileSize(z));
return [Math.round(tileSize[0] * pixelRatio), Math.round(tileSize[1] * pixelRatio)];
};
diff --git a/src/ol/tile.js b/src/ol/tile.js
index c329c33017..4d1628bea4 100644
--- a/src/ol/tile.js
+++ b/src/ol/tile.js
@@ -59,14 +59,6 @@ ol.Tile.prototype.changed = function() {
};
-/**
- * Get the HTML image element for this tile (may be a Canvas, Image, or Video).
- * @abstract
- * @return {HTMLCanvasElement|HTMLImageElement|HTMLVideoElement} Image.
- */
-ol.Tile.prototype.getImage = function() {};
-
-
/**
* @return {string} Key.
*/
diff --git a/src/ol/tilegrid.js b/src/ol/tilegrid.js
index 2b39e0cec7..3eb2f43afa 100644
--- a/src/ol/tilegrid.js
+++ b/src/ol/tilegrid.js
@@ -74,7 +74,7 @@ ol.tilegrid.createForExtent = function(extent, opt_maxZoom, opt_tileSize, opt_co
/**
* Creates a tile grid with a standard XYZ tiling scheme.
* @param {olx.tilegrid.XYZOptions=} opt_options Tile grid options.
- * @return {ol.tilegrid.TileGrid} Tile grid instance.
+ * @return {!ol.tilegrid.TileGrid} Tile grid instance.
* @api
*/
ol.tilegrid.createXYZ = function(opt_options) {
diff --git a/src/ol/typedefs.js b/src/ol/typedefs.js
index dc436d0c03..a0c7be7310 100644
--- a/src/ol/typedefs.js
+++ b/src/ol/typedefs.js
@@ -652,8 +652,7 @@ ol.TilePriorityFunction;
* dirty: boolean,
* renderedRenderOrder: (null|ol.RenderOrderFunction),
* renderedTileRevision: number,
- * renderedRevision: number,
- * replayGroup: ol.render.ReplayGroup}}
+ * renderedRevision: number}}
*/
ol.TileReplayState;
diff --git a/src/ol/vectorimagetile.js b/src/ol/vectorimagetile.js
new file mode 100644
index 0000000000..795281ff40
--- /dev/null
+++ b/src/ol/vectorimagetile.js
@@ -0,0 +1,288 @@
+goog.provide('ol.VectorImageTile');
+
+goog.require('ol');
+goog.require('ol.Tile');
+goog.require('ol.TileState');
+goog.require('ol.array');
+goog.require('ol.dom');
+goog.require('ol.events');
+goog.require('ol.extent');
+goog.require('ol.events.EventType');
+goog.require('ol.featureloader');
+
+
+/**
+ * @constructor
+ * @extends {ol.Tile}
+ * @param {ol.TileCoord} tileCoord Tile coordinate.
+ * @param {ol.TileState} state State.
+ * @param {string} src Data source url.
+ * @param {ol.format.Feature} format Feature format.
+ * @param {ol.TileLoadFunctionType} tileLoadFunction Tile load function.
+ * @param {ol.TileCoord} urlTileCoord Wrapped tile coordinate for source urls.
+ * @param {ol.TileUrlFunctionType} tileUrlFunction Tile url function.
+ * @param {ol.tilegrid.TileGrid} sourceTileGrid Tile grid of the source.
+ * @param {ol.tilegrid.TileGrid} tileGrid Tile grid of the renderer.
+ * @param {Object.} sourceTiles Source tiles.
+ * @param {number} pixelRatio Pixel ratio.
+ * @param {ol.proj.Projection} projection Projection.
+ * @param {function(new: ol.VectorTile, ol.TileCoord, ol.TileState, string,
+ * ol.format.Feature, ol.TileLoadFunctionType)} tileClass Class to
+ * instantiate for source tiles.
+ */
+ol.VectorImageTile = function(tileCoord, state, src, format, tileLoadFunction,
+ urlTileCoord, tileUrlFunction, sourceTileGrid, tileGrid, sourceTiles,
+ pixelRatio, projection, tileClass) {
+
+ ol.Tile.call(this, tileCoord, state);
+
+ /**
+ * @private
+ * @type {CanvasRenderingContext2D}
+ */
+ this.context_ = null;
+
+ /**
+ * @private
+ * @type {ol.format.Feature}
+ */
+ this.format_ = format;
+
+ /**
+ * @private
+ * @type {ol.FeatureLoader}
+ */
+ this.loader_;
+
+ /**
+ * @private
+ * @type {ol.TileReplayState}
+ */
+ this.replayState_ = {
+ dirty: false,
+ renderedRenderOrder: null,
+ renderedRevision: -1,
+ renderedTileRevision: -1
+ };
+
+ /**
+ * @private
+ * @type {Object.}
+ */
+ this.sourceTiles_ = sourceTiles;
+
+ /**
+ * @private
+ * @type {Array.}
+ */
+ this.usedSourceTileKeys_ = [];
+
+ /**
+ * @type {string}
+ */
+ this.src_ = src;
+
+ /**
+ * @type {ol.TileCoord}
+ */
+ this.wrappedTileCoord = urlTileCoord;
+
+ /**
+ * @type {Array.}
+ */
+ this.loadListenerKeys_ = [];
+
+ if (urlTileCoord) {
+ var extent = tileGrid.getTileCoordExtent(urlTileCoord);
+ var resolution = tileGrid.getResolution(tileCoord[0]);
+ var sourceZ = sourceTileGrid.getZForResolution(resolution);
+ sourceTileGrid.forEachTileCoord(extent, sourceZ, function(sourceTileCoord) {
+ var sharedExtent = ol.extent.getIntersection(extent,
+ sourceTileGrid.getTileCoordExtent(sourceTileCoord));
+ if (ol.extent.getWidth(sharedExtent) / resolution >= 0.5 &&
+ ol.extent.getHeight(sharedExtent) / resolution >= 0.5) {
+ // only include source tile if overlap is at least 1 pixel
+ var sourceTileKey = sourceTileCoord.toString();
+ var sourceTile = sourceTiles[sourceTileKey];
+ if (!sourceTile) {
+ var tileUrl = /** @type {string} */
+ (tileUrlFunction(sourceTileCoord, pixelRatio, projection));
+ sourceTile = sourceTiles[sourceTileKey] = new tileClass(
+ sourceTileCoord, ol.TileState.IDLE, tileUrl, format, tileLoadFunction);
+ }
+ sourceTile.consumers++;
+ this.usedSourceTileKeys_.push(sourceTileKey);
+ }
+ }.bind(this));
+ }
+
+};
+ol.inherits(ol.VectorImageTile, ol.Tile);
+
+
+/**
+ * @inheritDoc
+ */
+ol.VectorImageTile.prototype.disposeInternal = function() {
+ var sourceTiles = this.getSourceTiles();
+ for (var i = 0, ii = sourceTiles.length; i < ii; ++i) {
+ var sourceTile = sourceTiles[i];
+ sourceTile.consumers--;
+ if (sourceTile.consumers == 0) {
+ delete this.sourceTiles_[sourceTile.tileCoord.toString()];
+ sourceTile.dispose();
+ }
+ }
+ this.tileKeys.length = 0;
+ this.sourceTiles_ = null;
+ if (this.state == ol.TileState.LOADING) {
+ this.loadListenerKeys_.forEach(ol.events.unlistenByKey);
+ this.loadListenerKeys_.length = 0;
+ }
+ if (this.interimTile) {
+ this.interimTile.dispose();
+ }
+ this.state = ol.TileState.ABORT;
+ this.changed();
+ ol.Tile.prototype.disposeInternal.call(this);
+};
+
+
+/**
+ * @return {CanvasRenderingContext2D} The rendering context.
+ */
+ol.VectorImageTile.prototype.getContext = function() {
+ if (!this.context_) {
+ this.context_ = ol.dom.createCanvasContext2D();
+ }
+ return this.context_;
+};
+
+
+/**
+ * Get the Canvas for this tile.
+ * @return {HTMLCanvasElement} Canvas.
+ * @api
+ */
+ol.VectorImageTile.prototype.getImage = function() {
+ return this.replayState_.renderedTileRevision == -1 ?
+ null : this.context_.canvas;
+};
+
+
+/**
+ * Get the feature format assigned for reading this tile's features.
+ * @return {ol.format.Feature} Feature format.
+ * @api
+ */
+ol.VectorImageTile.prototype.getFormat = function() {
+ return this.format_;
+};
+
+
+/**
+ * @return {Array.} Features.
+ */
+ol.VectorImageTile.prototype.getFeatures = function() {
+ return this.features_;
+};
+
+
+/**
+ * @return {ol.TileReplayState} The replay state.
+ */
+ol.VectorImageTile.prototype.getReplayState = function() {
+ return this.replayState_;
+};
+
+
+/**
+ * @inheritDoc
+ */
+ol.VectorImageTile.prototype.getKey = function() {
+ return this.usedSourceTileKeys_.join('/') + '/' + this.src_;
+};
+
+
+/**
+ * @return {Array.} Source tiles for this tile.
+ */
+ol.VectorImageTile.prototype.getSourceTiles = function() {
+ return this.usedSourceTileKeys_.map(function(sourceTileKey) {
+ return this.sourceTiles_[sourceTileKey];
+ }.bind(this));
+};
+
+
+/**
+ * @inheritDoc
+ */
+ol.VectorImageTile.prototype.load = function() {
+ var leftToLoad = 0;
+ if (this.state == ol.TileState.IDLE) {
+ this.setState(ol.TileState.LOADING);
+ }
+ if (this.state == ol.TileState.LOADING) {
+ this.usedSourceTileKeys_.forEach(function(sourceTileKey) {
+ var sourceTile = this.sourceTiles_[sourceTileKey];
+ if (sourceTile.state == ol.TileState.IDLE) {
+ sourceTile.setLoader(this.loader_);
+ sourceTile.load();
+ }
+ if (sourceTile.state == ol.TileState.LOADING) {
+ var key = ol.events.listen(sourceTile, ol.events.EventType.CHANGE, function(e) {
+ var state = sourceTile.getState();
+ if (state == ol.TileState.LOADED ||
+ state == ol.TileState.ERROR ||
+ state == ol.TileState.EMPTY) {
+ --leftToLoad;
+ ol.events.unlistenByKey(key);
+ ol.array.remove(this.loadListenerKeys_, key);
+ if (leftToLoad == 0) {
+ this.setState(ol.TileState.LOADED);
+ }
+ }
+ }.bind(this));
+ this.loadListenerKeys_.push(key);
+ ++leftToLoad;
+ }
+ }.bind(this));
+ }
+ if (leftToLoad == 0) {
+ setTimeout(function() {
+ this.setState(ol.TileState.LOADED);
+ }.bind(this), 0);
+ }
+};
+
+
+/**
+ * @param {Array.} features Features.
+ * @api
+ */
+ol.VectorImageTile.prototype.setFeatures = function(features) {
+ this.features_ = features;
+ this.setState(ol.TileState.LOADED);
+};
+
+
+/**
+ * @param {ol.TileState} tileState Tile state.
+ */
+ol.VectorImageTile.prototype.setState = function(tileState) {
+ this.state = tileState;
+ this.changed();
+};
+
+
+/**
+ * Sets the loader for a tile.
+ * @param {ol.VectorTile} tile Vector tile.
+ * @param {string} url URL.
+ */
+ol.VectorImageTile.defaultLoadFunction = function(tile, url) {
+ var loader = ol.featureloader.loadFeaturesXhr(
+ url, tile.getFormat(), tile.onLoad_.bind(tile), tile.onError_.bind(tile));
+
+ tile.setLoader(loader);
+};
diff --git a/src/ol/vectortile.js b/src/ol/vectortile.js
index ade49cf9e2..11fa1f8f05 100644
--- a/src/ol/vectortile.js
+++ b/src/ol/vectortile.js
@@ -3,8 +3,6 @@ goog.provide('ol.VectorTile');
goog.require('ol');
goog.require('ol.Tile');
goog.require('ol.TileState');
-goog.require('ol.dom');
-goog.require('ol.featureloader');
/**
@@ -21,10 +19,9 @@ ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) {
ol.Tile.call(this, tileCoord, state);
/**
- * @private
- * @type {CanvasRenderingContext2D}
+ * @type {number}
*/
- this.context_ = null;
+ this.consumers = 0;
/**
* @private
@@ -51,17 +48,7 @@ ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) {
*/
this.projection_;
- /**
- * @private
- * @type {ol.TileReplayState}
- */
- this.replayState_ = {
- dirty: false,
- renderedRenderOrder: null,
- renderedRevision: -1,
- renderedTileRevision: -1,
- replayGroup: null
- };
+ this.replayGroups_ = {};
/**
* @private
@@ -79,26 +66,6 @@ ol.VectorTile = function(tileCoord, state, src, format, tileLoadFunction) {
ol.inherits(ol.VectorTile, ol.Tile);
-/**
- * @return {CanvasRenderingContext2D} The rendering context.
- */
-ol.VectorTile.prototype.getContext = function() {
- if (!this.context_) {
- this.context_ = ol.dom.createCanvasContext2D();
- }
- return this.context_;
-};
-
-
-/**
- * @override
- */
-ol.VectorTile.prototype.getImage = function() {
- return this.replayState_.renderedTileRevision == -1 ?
- null : this.context_.canvas;
-};
-
-
/**
* Get the feature format assigned for reading this tile's features.
* @return {ol.format.Feature} Feature format.
@@ -117,14 +84,6 @@ ol.VectorTile.prototype.getFeatures = function() {
};
-/**
- * @return {ol.TileReplayState} The replay state.
- */
-ol.VectorTile.prototype.getReplayState = function() {
- return this.replayState_;
-};
-
-
/**
* @inheritDoc
*/
@@ -141,6 +100,11 @@ ol.VectorTile.prototype.getProjection = function() {
};
+ol.VectorTile.prototype.getReplayGroup = function(key) {
+ return this.replayGroups_[key];
+};
+
+
/**
* @inheritDoc
*/
@@ -192,6 +156,11 @@ ol.VectorTile.prototype.setProjection = function(projection) {
};
+ol.VectorTile.prototype.setReplayGroup = function(key, replayGroup) {
+ this.replayGroups_[key] = replayGroup;
+};
+
+
/**
* @param {ol.TileState} tileState Tile state.
*/
@@ -209,16 +178,3 @@ ol.VectorTile.prototype.setState = function(tileState) {
ol.VectorTile.prototype.setLoader = function(loader) {
this.loader_ = loader;
};
-
-
-/**
- * Sets the loader for a tile.
- * @param {ol.VectorTile} tile Vector tile.
- * @param {string} url URL.
- */
-ol.VectorTile.defaultLoadFunction = function(tile, url) {
- var loader = ol.featureloader.loadFeaturesXhr(
- url, tile.getFormat(), tile.onLoad_.bind(tile), tile.onError_.bind(tile));
-
- tile.setLoader(loader);
-};
diff --git a/test/spec/ol/renderer/canvas/vectortilelayer.test.js b/test/spec/ol/renderer/canvas/vectortilelayer.test.js
index e0bcc638a1..a0d0d04917 100644
--- a/test/spec/ol/renderer/canvas/vectortilelayer.test.js
+++ b/test/spec/ol/renderer/canvas/vectortilelayer.test.js
@@ -62,6 +62,11 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
tileClass: TileClass,
tileGrid: ol.tilegrid.createXYZ()
});
+ source.getTile = function() {
+ var tile = ol.source.VectorTile.prototype.getTile.apply(source, arguments);
+ tile.setState(ol.TileState.LOADED);
+ return tile;
+ };
layer = new ol.layer.VectorTile({
source: source,
style: layerStyle
@@ -156,12 +161,18 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
tileGrid: ol.tilegrid.createXYZ()
})
});
- var tile = new ol.VectorTile([0, 0, 0], 2);
- tile.projection_ = ol.proj.get('EPSG:3857');
- tile.features_ = [];
- tile.getImage = function() {
+ var sourceTile = new ol.VectorTile([0, 0, 0], 2);
+ sourceTile.setProjection(ol.proj.get('EPSG:3857'));
+ sourceTile.features_ = [];
+ sourceTile.getImage = function() {
return document.createElement('canvas');
};
+ var tile = new ol.VectorImageTile([0, 0, 0]);
+ tile.wrappedTileCoord = [0, 0, 0];
+ tile.setState(ol.TileState.LOADED);
+ tile.getSourceTiles = function() {
+ return [sourceTile];
+ };
layer.getSource().getTile = function() {
return tile;
};
@@ -192,12 +203,18 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
describe('#forEachFeatureAtCoordinate', function() {
var layer, renderer, replayGroup;
var TileClass = function() {
- ol.VectorTile.apply(this, arguments);
+ ol.VectorImageTile.apply(this, arguments);
this.setState('loaded');
- this.setProjection(ol.proj.get('EPSG:3857'));
- this.replayState_.replayGroup = replayGroup;
+ var sourceTile = new ol.VectorTile();
+ sourceTile.setProjection(ol.proj.get('EPSG:3857'));
+ sourceTile.getReplayGroup = function() {
+ return replayGroup;
+ };
+ this.getSourceTiles = function() {
+ return [sourceTile];
+ };
};
- ol.inherits(TileClass, ol.VectorTile);
+ ol.inherits(TileClass, ol.VectorImageTile);
beforeEach(function() {
replayGroup = {};
@@ -223,6 +240,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() {
layerStates: {},
skippedFeatureUids: {},
viewState: {
+ projection: ol.proj.get('EPSG:3857'),
resolution: 1,
rotation: 0
}
diff --git a/test/spec/ol/source/vectortile.test.js b/test/spec/ol/source/vectortile.test.js
index b634c7a69c..1c9b0e7312 100644
--- a/test/spec/ol/source/vectortile.test.js
+++ b/test/spec/ol/source/vectortile.test.js
@@ -1,6 +1,6 @@
goog.provide('ol.test.source.VectorTile');
-goog.require('ol.VectorTile');
+goog.require('ol.VectorImageTile');
goog.require('ol.format.MVT');
goog.require('ol.proj');
goog.require('ol.source.VectorTile');
@@ -29,7 +29,7 @@ describe('ol.source.VectorTile', function() {
describe('#getTile()', function() {
it('creates a tile with the correct tile class', function() {
tile = source.getTile(0, 0, 0, 1, ol.proj.get('EPSG:3857'));
- expect(tile).to.be.a(ol.VectorTile);
+ expect(tile).to.be.a(ol.VectorImageTile);
});
it('sets the correct tileCoord on the created tile', function() {
expect(tile.getTileCoord()).to.eql([0, 0, 0]);
diff --git a/test/spec/ol/vectorimagetile.test.js b/test/spec/ol/vectorimagetile.test.js
new file mode 100644
index 0000000000..8a3d6d25bb
--- /dev/null
+++ b/test/spec/ol/vectorimagetile.test.js
@@ -0,0 +1,43 @@
+goog.provide('ol.test.VectorImageTile');
+
+goog.require('ol.events');
+goog.require('ol.VectorImageTile');
+goog.require('ol.VectorTile');
+goog.require('ol.format.GeoJSON');
+goog.require('ol.proj');
+
+
+describe('ol.VectorImageTile', function() {
+
+ it('sets the loader function on source tiles', function() {
+ var format = new ol.format.GeoJSON();
+ var url = 'spec/ol/data/point.json';
+ var tile = new ol.VectorImageTile([0, 0, 0], 0, url, format,
+ ol.VectorImageTile.defaultLoadFunction,
+ [0, 0, 0], function() {}, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {},
+ 1, ol.proj.get('EPSG:3857'), ol.VectorTile);
+
+ tile.load();
+ var loader = tile.getSourceTiles()[0].loader_;
+ expect(typeof loader).to.be('function');
+ });
+
+ it('loader sets features on the source tile', function(done) {
+ var format = new ol.format.GeoJSON();
+ var url = 'spec/ol/data/point.json';
+ var tile = new ol.VectorImageTile([0, 0, 0], 0, url, format,
+ ol.VectorImageTile.defaultLoadFunction, [0, 0, 0], function() {
+ return url;
+ }, ol.tilegrid.createXYZ(), ol.tilegrid.createXYZ(), {},
+ 1, ol.proj.get('EPSG:3857'), ol.VectorTile);
+
+ tile.load();
+ var sourceTile = tile.getSourceTiles()[0];
+
+ ol.events.listen(sourceTile, 'change', function(e) {
+ expect(sourceTile.getFeatures().length).to.be.greaterThan(0);
+ done();
+ });
+ });
+
+});
diff --git a/test/spec/ol/vectortile.test.js b/test/spec/ol/vectortile.test.js
index 33531d21e6..b794ef0d90 100644
--- a/test/spec/ol/vectortile.test.js
+++ b/test/spec/ol/vectortile.test.js
@@ -1,39 +1,14 @@
goog.provide('ol.test.VectorTile');
goog.require('ol.events');
+goog.require('ol.VectorImageTile');
goog.require('ol.VectorTile');
goog.require('ol.Feature');
-goog.require('ol.format.GeoJSON');
goog.require('ol.format.TextFeature');
goog.require('ol.proj');
-describe('ol.VectorTile.defaultLoadFunction()', function() {
-
- it('sets the loader function on the tile', function() {
- var format = new ol.format.GeoJSON();
- var tile = new ol.VectorTile([0, 0, 0], null, null, format);
- var url = 'https://example.com/';
-
- ol.VectorTile.defaultLoadFunction(tile, url);
- var loader = tile.loader_;
- expect(typeof loader).to.be('function');
- });
-
- it('loader sets features on the tile', function(done) {
- var format = new ol.format.GeoJSON();
- var tile = new ol.VectorTile([0, 0, 0], null, null, format);
- var url = 'spec/ol/data/point.json';
-
- ol.VectorTile.defaultLoadFunction(tile, url);
- var loader = tile.loader_;
-
- ol.events.listen(tile, 'change', function(e) {
- expect(tile.getFeatures().length).to.be.greaterThan(0);
- done();
- });
- loader.call(tile, [], 1, ol.proj.get('EPSG:3857'));
- });
+describe('ol.VectorTile', function() {
it('loader sets features on the tile and updates proj units', function(done) {
// mock format that return a tile-pixels feature
@@ -51,7 +26,7 @@ describe('ol.VectorTile.defaultLoadFunction()', function() {
var tile = new ol.VectorTile([0, 0, 0], null, null, format);
var url = 'spec/ol/data/point.json';
- ol.VectorTile.defaultLoadFunction(tile, url);
+ ol.VectorImageTile.defaultLoadFunction(tile, url);
var loader = tile.loader_;
ol.events.listen(tile, 'change', function(e) {
expect(tile.getFeatures().length).to.be.greaterThan(0);