Merge branch 'master' into set-multi

This commit is contained in:
Björn Harrtell
2016-02-22 09:30:25 +01:00
35 changed files with 529 additions and 478 deletions

View File

@@ -575,18 +575,24 @@ ol.extent.getForViewAndSize = function(center, resolution, rotation, size, opt_e
var dy = resolution * size[1] / 2;
var cosRotation = Math.cos(rotation);
var sinRotation = Math.sin(rotation);
/** @type {Array.<number>} */
var xs = [-dx, -dx, dx, dx];
/** @type {Array.<number>} */
var ys = [-dy, dy, -dy, dy];
var i, x, y;
for (i = 0; i < 4; ++i) {
x = xs[i];
y = ys[i];
xs[i] = center[0] + x * cosRotation - y * sinRotation;
ys[i] = center[1] + x * sinRotation + y * cosRotation;
}
return ol.extent.boundingExtentXYs_(xs, ys, opt_extent);
var xCos = dx * cosRotation;
var xSin = dx * sinRotation;
var yCos = dy * cosRotation;
var ySin = dy * sinRotation;
var x = center[0];
var y = center[1];
var x0 = x - xCos + ySin;
var x1 = x - xCos - ySin;
var x2 = x + xCos - ySin;
var x3 = x + xCos + ySin;
var y0 = y - xSin - yCos;
var y1 = y - xSin + yCos;
var y2 = y + xSin + yCos;
var y3 = y + xSin - yCos;
return ol.extent.createOrUpdate(
Math.min(x0, x1, x2, x3), Math.min(y0, y1, y2, y3),
Math.max(x0, x1, x2, x3), Math.max(y0, y1, y2, y3),
opt_extent);
};

View File

@@ -411,6 +411,7 @@ ol.format.WFS.writeOgcFidFilter_ = function(node, fid, objectStack) {
ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
var context = objectStack[objectStack.length - 1];
goog.asserts.assert(goog.isObject(context), 'context should be an Object');
goog.asserts.assert(feature.getId() !== undefined, 'feature should have an id');
var featureType = context['featureType'];
var featurePrefix = context['featurePrefix'];
featurePrefix = featurePrefix ? featurePrefix :
@@ -420,7 +421,7 @@ ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
featureNS);
var fid = feature.getId();
if (fid) {
if (fid !== undefined) {
ol.format.WFS.writeOgcFidFilter_(node, fid, objectStack);
}
};
@@ -435,6 +436,7 @@ ol.format.WFS.writeDelete_ = function(node, feature, objectStack) {
ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
var context = objectStack[objectStack.length - 1];
goog.asserts.assert(goog.isObject(context), 'context should be an Object');
goog.asserts.assert(feature.getId() !== undefined, 'feature should have an id');
var featureType = context['featureType'];
var featurePrefix = context['featurePrefix'];
featurePrefix = featurePrefix ? featurePrefix :
@@ -444,7 +446,7 @@ ol.format.WFS.writeUpdate_ = function(node, feature, objectStack) {
ol.xml.setAttributeNS(node, ol.format.WFS.XMLNS, 'xmlns:' + featurePrefix,
featureNS);
var fid = feature.getId();
if (fid) {
if (fid !== undefined) {
var keys = feature.getKeys();
var values = [];
for (var i = 0, ii = keys.length; i < ii; i++) {

View File

@@ -147,16 +147,10 @@ ol.MapBrowserEventHandler = function(map) {
this.dragging_ = false;
/**
* @type {Array.<ol.events.Key>}
* @type {!Array.<ol.events.Key>}
* @private
*/
this.dragListenerKeys_ = null;
/**
* @type {?ol.events.Key}
* @private
*/
this.pointerdownListenerKey_ = null;
this.dragListenerKeys_ = [];
/**
* The most recent "down" type event (or null if none have occurred).
@@ -198,10 +192,18 @@ ol.MapBrowserEventHandler = function(map) {
*/
this.documentPointerEventHandler_ = null;
/**
* @type {?ol.events.Key}
* @private
*/
this.pointerdownListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERDOWN,
this.handlePointerDown_, this);
/**
* @type {?ol.events.Key}
* @private
*/
this.relayedListenerKey_ = ol.events.listen(this.pointerEventHandler_,
ol.pointer.EventType.POINTERMOVE,
this.relayEvent_, this);
@@ -280,7 +282,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerUp_ = function(pointerEvent) {
'this.activePointers_ should be equal to or larger than 0');
if (this.activePointers_ === 0) {
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_ = null;
this.dragListenerKeys_.length = 0;
this.dragging_ = false;
this.down_ = null;
goog.dispose(this.documentPointerEventHandler_);
@@ -311,7 +313,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent)
this.down_ = pointerEvent;
if (!this.dragListenerKeys_) {
if (this.dragListenerKeys_.length === 0) {
/* Set up a pointer event handler on the `document`,
* which is required when the pointer is moved outside
* the viewport when dragging.
@@ -319,7 +321,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent)
this.documentPointerEventHandler_ =
new ol.pointer.PointerEventHandler(document);
this.dragListenerKeys_ = [
this.dragListenerKeys_.push(
ol.events.listen(this.documentPointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERMOVE,
this.handlePointerMove_, this),
@@ -342,7 +344,7 @@ ol.MapBrowserEventHandler.prototype.handlePointerDown_ = function(pointerEvent)
ol.events.listen(this.pointerEventHandler_,
ol.MapBrowserEvent.EventType.POINTERCANCEL,
this.handlePointerUp_, this)
];
);
}
};
@@ -409,10 +411,10 @@ ol.MapBrowserEventHandler.prototype.disposeInternal = function() {
ol.events.unlistenByKey(this.pointerdownListenerKey_);
this.pointerdownListenerKey_ = null;
}
if (this.dragListenerKeys_) {
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_ = null;
}
this.dragListenerKeys_.forEach(ol.events.unlistenByKey);
this.dragListenerKeys_.length = 0;
if (this.documentPointerEventHandler_) {
goog.dispose(this.documentPointerEventHandler_);
this.documentPointerEventHandler_ = null;

View File

@@ -94,3 +94,18 @@ ol.render.canvas.defaultTextBaseline = 'middle';
* @type {number}
*/
ol.render.canvas.defaultLineWidth = 1;
/**
* @param {CanvasRenderingContext2D} context Context.
* @param {number} rotation Rotation.
* @param {number} offsetX X offset.
* @param {number} offsetY Y offset.
*/
ol.render.canvas.rotateAtOffset = function(context, rotation, offsetX, offsetY) {
if (rotation !== 0) {
context.translate(offsetX, offsetY);
context.rotate(rotation);
context.translate(-offsetX, -offsetY);
}
};

View File

@@ -147,7 +147,6 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, laye
var viewState = frameState.viewState;
var viewCenter = viewState.center;
var viewResolution = viewState.resolution;
var viewRotation = viewState.rotation;
var image;
var imageLayer = this.getLayer();
@@ -195,7 +194,7 @@ ol.renderer.canvas.ImageLayer.prototype.prepareFrame = function(frameState, laye
pixelRatio * frameState.size[0] / 2,
pixelRatio * frameState.size[1] / 2,
scale, scale,
viewRotation,
0,
imagePixelRatio * (imageExtent[0] - viewCenter[0]) / imageResolution,
imagePixelRatio * (viewCenter[1] - imageExtent[3]) / imageResolution);
this.imageTransformInv_ = null;

View File

@@ -2,12 +2,11 @@ goog.provide('ol.renderer.canvas.Layer');
goog.require('goog.asserts');
goog.require('goog.vec.Mat4');
goog.require('ol.array');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Layer');
goog.require('ol.render.Event');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas');
goog.require('ol.render.canvas.Immediate');
goog.require('ol.renderer.Layer');
goog.require('ol.vec.Mat4');
@@ -51,6 +50,9 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
goog.asserts.assert(extent !== undefined,
'layerState extent is defined');
var pixelRatio = frameState.pixelRatio;
var width = frameState.size[0] * pixelRatio;
var height = frameState.size[1] * pixelRatio;
var rotation = frameState.viewState.rotation;
var topLeft = ol.extent.getTopLeft(extent);
var topRight = ol.extent.getTopRight(extent);
var bottomRight = ol.extent.getBottomRight(extent);
@@ -66,12 +68,14 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
bottomLeft, bottomLeft);
context.save();
ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
context.beginPath();
context.moveTo(topLeft[0] * pixelRatio, topLeft[1] * pixelRatio);
context.lineTo(topRight[0] * pixelRatio, topRight[1] * pixelRatio);
context.lineTo(bottomRight[0] * pixelRatio, bottomRight[1] * pixelRatio);
context.lineTo(bottomLeft[0] * pixelRatio, bottomLeft[1] * pixelRatio);
context.clip();
ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
}
var imageTransform = this.getImageTransform();
@@ -83,24 +87,12 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
// for performance reasons, context.setTransform is only used
// when the view is rotated. see http://jsperf.com/canvas-transform
if (frameState.viewState.rotation === 0) {
var dx = goog.vec.Mat4.getElement(imageTransform, 0, 3);
var dy = goog.vec.Mat4.getElement(imageTransform, 1, 3);
var dw = image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0);
var dh = image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1);
context.drawImage(image, 0, 0, +image.width, +image.height,
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
} else {
context.setTransform(
goog.vec.Mat4.getElement(imageTransform, 0, 0),
goog.vec.Mat4.getElement(imageTransform, 1, 0),
goog.vec.Mat4.getElement(imageTransform, 0, 1),
goog.vec.Mat4.getElement(imageTransform, 1, 1),
goog.vec.Mat4.getElement(imageTransform, 0, 3),
goog.vec.Mat4.getElement(imageTransform, 1, 3));
context.drawImage(image, 0, 0);
context.setTransform(1, 0, 0, 1, 0, 0);
}
var dx = goog.vec.Mat4.getElement(imageTransform, 0, 3);
var dy = goog.vec.Mat4.getElement(imageTransform, 1, 3);
var dw = image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0);
var dh = image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1);
context.drawImage(image, 0, 0, +image.width, +image.height,
Math.round(dx), Math.round(dy), Math.round(dw), Math.round(dh));
context.globalAlpha = alpha;
if (clipped) {
@@ -123,6 +115,10 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat
ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, context, frameState, opt_transform) {
var layer = this.getLayer();
if (layer.hasListener(type)) {
var width = frameState.size[0] * frameState.pixelRatio;
var height = frameState.size[1] * frameState.pixelRatio;
var rotation = frameState.viewState.rotation;
ol.render.canvas.rotateAtOffset(context, -rotation, width / 2, height / 2);
var transform = opt_transform !== undefined ?
opt_transform : this.getTransform(frameState, 0);
var render = new ol.render.canvas.Immediate(
@@ -132,6 +128,7 @@ ol.renderer.canvas.Layer.prototype.dispatchComposeEvent_ = function(type, contex
context, null);
layer.dispatchEvent(composeEvent);
render.flush();
ol.render.canvas.rotateAtOffset(context, rotation, width / 2, height / 2);
}
};
@@ -224,46 +221,3 @@ ol.renderer.canvas.Layer.prototype.getPixelOnCanvas = function(pixelOnMap, image
ol.vec.Mat4.multVec2(imageTransformInv, pixelOnMap, pixelOnCanvas);
return pixelOnCanvas;
};
/**
* @param {ol.Size} size Size.
* @return {boolean} True when the canvas with the current size does not exceed
* the maximum dimensions.
*/
ol.renderer.canvas.Layer.testCanvasSize = (function() {
/**
* @type {CanvasRenderingContext2D}
*/
var context = null;
/**
* @type {ImageData}
*/
var imageData = null;
return function(size) {
if (!context) {
context = ol.dom.createCanvasContext2D(1, 1);
imageData = context.createImageData(1, 1);
var data = imageData.data;
data[0] = 42;
data[1] = 84;
data[2] = 126;
data[3] = 255;
}
var canvas = context.canvas;
var good = size[0] <= canvas.width && size[1] <= canvas.height;
if (!good) {
canvas.width = size[0];
canvas.height = size[1];
var x = size[0] - 1;
var y = size[1] - 1;
context.putImageData(imageData, x, y);
var result = context.getImageData(x, y, 1, 1);
good = ol.array.equals(imageData.data, result.data);
}
return good;
};
})();

View File

@@ -11,6 +11,7 @@ goog.require('ol.RendererType');
goog.require('ol.array');
goog.require('ol.css');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Image');
goog.require('ol.layer.Layer');
goog.require('ol.layer.Tile');
@@ -45,6 +46,12 @@ ol.renderer.canvas.Map = function(container, map) {
*/
this.context_ = ol.dom.createCanvasContext2D();
/**
* @private
* @type {CanvasRenderingContext2D}
*/
this.renderContext_ = ol.dom.createCanvasContext2D();
/**
* @private
* @type {HTMLCanvasElement}
@@ -56,6 +63,24 @@ ol.renderer.canvas.Map = function(container, map) {
this.canvas_.className = ol.css.CLASS_UNSELECTABLE;
goog.dom.insertChildAt(container, this.canvas_, 0);
/**
* @private
* @type {HTMLCanvasElement}
*/
this.renderCanvas_ = this.renderContext_.canvas;
/**
* @private
* @type {ol.Coordinate}
*/
this.pixelCenter_ = [0, 0];
/**
* @private
* @type {ol.Extent}
*/
this.pixelExtent_ = ol.extent.createEmpty();
/**
* @private
* @type {boolean}
@@ -156,14 +181,27 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
return;
}
var context = this.context_;
var width = frameState.size[0] * frameState.pixelRatio;
var height = frameState.size[1] * frameState.pixelRatio;
if (this.canvas_.width != width || this.canvas_.height != height) {
this.canvas_.width = width;
this.canvas_.height = height;
var context;
var pixelRatio = frameState.pixelRatio;
var width = frameState.size[0] * pixelRatio;
var height = frameState.size[1] * pixelRatio;
this.canvas_.width = width;
this.canvas_.height = height;
var rotation = frameState.viewState.rotation;
var pixelExtent;
if (rotation) {
context = this.renderContext_;
pixelExtent = ol.extent.getForViewAndSize(this.pixelCenter_, pixelRatio,
rotation, frameState.size, this.pixelExtent_);
var renderWidth = ol.extent.getWidth(pixelExtent);
var renderHeight = ol.extent.getHeight(pixelExtent);
this.renderCanvas_.width = renderWidth + 0.5;
this.renderCanvas_.height = renderHeight + 0.5;
this.renderContext_.translate(Math.round((renderWidth - width) / 2),
Math.round((renderHeight - height) / 2));
} else {
context.clearRect(0, 0, this.canvas_.width, this.canvas_.height);
context = this.context_;
}
this.calculateMatrices2D(frameState);
@@ -190,6 +228,15 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) {
}
}
if (rotation) {
this.context_.translate(width / 2, height / 2);
this.context_.rotate(rotation);
this.context_.drawImage(this.renderCanvas_,
Math.round(pixelExtent[0]), Math.round(pixelExtent[1]));
this.context_.rotate(-rotation);
this.context_.translate(-width / 2, -height / 2);
}
this.dispatchComposeEvent_(
ol.render.EventType.POSTCOMPOSE, frameState);

View File

@@ -1,20 +1,17 @@
// FIXME find correct globalCompositeOperation
// FIXME optimize :-)
goog.provide('ol.renderer.canvas.TileLayer');
goog.require('goog.asserts');
goog.require('goog.vec.Mat4');
goog.require('ol.Size');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.array');
goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Tile');
goog.require('ol.render.EventType');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.size');
goog.require('ol.vec.Mat4');
goog.require('ol.source.Tile');
/**
@@ -28,63 +25,15 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
/**
* @private
* @type {HTMLCanvasElement}
* @type {Object.<string, Array.<ol.Extent>>}
*/
this.canvas_ = null;
/**
* @private
* @type {ol.Size}
*/
this.canvasSize_ = null;
/**
* @private
* @type {boolean}
*/
this.canvasTooBig_ = false;
this.clipExtents_ = null;
/**
* @private
* @type {CanvasRenderingContext2D}
*/
this.context_ = null;
/**
* @private
* @type {!goog.vec.Mat4.Number}
*/
this.imageTransform_ = goog.vec.Mat4.createNumber();
/**
* @private
* @type {?goog.vec.Mat4.Number}
*/
this.imageTransformInv_ = null;
/**
* @private
* @type {number}
*/
this.renderedCanvasZ_ = NaN;
/**
* @private
* @type {number}
*/
this.renderedTileWidth_ = NaN;
/**
* @private
* @type {number}
*/
this.renderedTileHeight_ = NaN;
/**
* @private
* @type {ol.TileRange}
*/
this.renderedCanvasTileRange_ = null;
this.context_ = ol.dom.createCanvasContext2D();
/**
* @private
@@ -94,9 +43,9 @@ ol.renderer.canvas.TileLayer = function(tileLayer) {
/**
* @private
* @type {ol.Size}
* @type {ol.Extent}
*/
this.tmpSize_ = [0, 0];
this.tmpExtent_ = ol.extent.createEmpty();
};
goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
@@ -105,86 +54,120 @@ goog.inherits(ol.renderer.canvas.TileLayer, ol.renderer.canvas.Layer);
/**
* @inheritDoc
*/
ol.renderer.canvas.TileLayer.prototype.getImage = function() {
return this.canvas_;
ol.renderer.canvas.TileLayer.prototype.composeFrame = function(
frameState, layerState, context) {
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
var center = viewState.center;
var projection = viewState.projection;
var resolution = viewState.resolution;
var size = frameState.size;
var pixelScale = pixelRatio / resolution;
var layer = this.getLayer();
var source = layer.getSource();
goog.asserts.assertInstanceof(source, ol.source.Tile,
'source is an ol.source.Tile');
var tileGutter = source.getGutter(projection);
var opaque = source.getOpaque(projection);
var transform = this.getTransform(frameState, 0);
this.dispatchPreComposeEvent(context, frameState, transform);
var renderContext;
if (layer.hasListener(ol.render.EventType.RENDER)) {
// resize and clear
this.context_.canvas.width = context.canvas.width;
this.context_.canvas.height = context.canvas.height;
renderContext = this.context_;
} else {
renderContext = context;
}
var offsetX = Math.round(pixelRatio * size[0] / 2);
var offsetY = Math.round(pixelRatio * size[1] / 2);
// for performance reasons, context.save / context.restore is not used
// to save and restore the transformation matrix and the opacity.
// see http://jsperf.com/context-save-restore-versus-variable
var alpha = renderContext.globalAlpha;
renderContext.globalAlpha = layerState.opacity;
var tileGrid = source.getTileGridForProjection(projection);
var tilesToDraw = this.renderedTiles_;
var clipExtents, clipExtent, currentZ, i, ii, j, jj, insertPoint;
var origin, tile, tileExtent, tileHeight, tileOffsetX, tileOffsetY;
var tilePixelSize, tileWidth;
for (i = 0, ii = tilesToDraw.length; i < ii; ++i) {
tile = tilesToDraw[i];
tileExtent = tileGrid.getTileCoordExtent(
tile.getTileCoord(), this.tmpExtent_);
clipExtents = !opaque && this.clipExtents_[tile.tileCoord.toString()];
if (clipExtents) {
// Create a clip mask for regions in this low resolution tile that will be
// filled by a higher resolution tile
renderContext.save();
renderContext.beginPath();
renderContext.moveTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((tileExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - tileExtent[3]) * pixelScale + offsetY);
renderContext.closePath();
for (j = 0, jj = clipExtents.length; j < jj; ++j) {
clipExtent = clipExtents[j];
renderContext.moveTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[1]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[0] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[3]) * pixelScale + offsetY);
renderContext.lineTo((clipExtent[2] - center[0]) * pixelScale + offsetX,
(center[1] - clipExtent[1]) * pixelScale + offsetY);
renderContext.closePath();
}
renderContext.clip();
}
currentZ = tile.getTileCoord()[0];
tilePixelSize = source.getTilePixelSize(currentZ, pixelRatio, projection);
insertPoint = ol.extent.getTopLeft(tileExtent);
tileWidth = Math.round(ol.extent.getWidth(tileExtent) * pixelScale);
tileHeight = Math.round(ol.extent.getHeight(tileExtent) * pixelScale);
// Calculate all insert points from a common origin and tile widths to avoid
// gaps caused by rounding
origin = ol.extent.getBottomLeft(tileGrid.getTileCoordExtent(
tileGrid.getTileCoordForCoordAndZ(center, currentZ)));
tileOffsetX = offsetX + Math.round((origin[0] - center[0]) * pixelScale);
tileOffsetY = offsetY + Math.round((center[1] - origin[1]) * pixelScale);
renderContext.drawImage(tile.getImage(), tileGutter, tileGutter,
tilePixelSize[0], tilePixelSize[1],
Math.round((insertPoint[0] - origin[0]) * pixelScale / tileWidth) *
tileWidth + tileOffsetX,
Math.round((origin[1] - insertPoint[1]) * pixelScale / tileHeight) *
tileHeight + tileOffsetY, tileWidth, tileHeight);
if (clipExtents) {
renderContext.restore();
}
}
if (renderContext != context) {
this.dispatchRenderEvent(renderContext, frameState, transform);
context.drawImage(renderContext.canvas, 0, 0);
}
renderContext.globalAlpha = alpha;
this.dispatchPostComposeEvent(context, frameState, transform);
};
/**
* @inheritDoc
*/
ol.renderer.canvas.TileLayer.prototype.getImageTransform = function() {
return this.imageTransform_;
};
/**
* @inheritDoc
*/
ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layerState) {
//
// Warning! You're entering a dangerous zone!
//
// The canvas tile layer renderering is highly optimized, hence
// the complexity of this function. For best performance we try
// to minimize the number of pixels to update on the canvas. This
// includes:
//
// - Only drawing pixels that will be visible.
// - Not re-drawing pixels/tiles that are already correct.
// - Minimizing calls to clearRect.
// - Never shrink the canvas. Just make it bigger when necessary.
// Re-sizing the canvas also clears it, which further means
// re-creating it (expensive).
//
// The various steps performed by this functions:
//
// - Create a canvas element if none has been created yet.
//
// - Make the canvas bigger if it's too small. Note that we never shrink
// the canvas, we just make it bigger when necessary, when rotating for
// example. Note also that the canvas always contains a whole number
// of tiles.
//
// - Invalidate the canvas tile range (renderedCanvasTileRange_ = null)
// if (1) the canvas has been enlarged, or (2) the zoom level changes,
// or (3) the canvas tile range doesn't contain the required tile
// range. This canvas tile range invalidation thing is related to
// an optimization where we attempt to redraw as few pixels as
// possible on each prepareFrame call.
//
// - If the canvas tile range has been invalidated we reset
// renderedCanvasTileRange_ and reset the renderedTiles_ array.
// The renderedTiles_ array is the structure used to determine
// the canvas pixels that need not be redrawn from one prepareFrame
// call to another. It records while tile has been rendered at
// which position in the canvas.
//
// - We then determine the tiles to draw on the canvas. Tiles for
// the target resolution may not be loaded yet. In that case we
// use low-resolution/interim tiles if loaded already. And, if
// for a non-yet-loaded tile we haven't found a corresponding
// low-resolution tile we indicate that the pixels for that
// tile must be cleared on the canvas. Note: determining the
// interim tiles is based on tile extents instead of tile
// coords, this is to be able to handler irregular tile grids.
//
// - We're now ready to render. We start by calling clearRect
// for the tiles that aren't loaded yet and are not fully covered
// by a low-resolution tile (if they're loaded, we'll draw them;
// if they're fully covered by a low-resolution tile then there's
// no need to clear). We then render the tiles "back to front",
// i.e. starting with the low-resolution tiles.
//
// - After rendering some bookkeeping is performed (updateUsedTiles,
// etc.). manageTilePyramid is what enqueue tiles in the tile
// queue for loading.
//
// - The last step involves updating the image transform matrix,
// which will be used by the map renderer for the final
// composition and positioning.
//
ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(
frameState, layerState) {
var pixelRatio = frameState.pixelRatio;
var viewState = frameState.viewState;
@@ -195,14 +178,8 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
'layer is an instance of ol.layer.Tile');
var tileSource = tileLayer.getSource();
var tileGrid = tileSource.getTileGridForProjection(projection);
var tileGutter = tileSource.getGutter();
var z = tileGrid.getZForResolution(viewState.resolution);
var tilePixelSize =
tileSource.getTilePixelSize(z, frameState.pixelRatio, projection);
var tilePixelRatio = tilePixelSize[0] /
ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
var tileResolution = tileGrid.getResolution(z);
var tilePixelResolution = tileResolution / tilePixelRatio;
var center = viewState.center;
var extent;
if (tileResolution == viewState.resolution) {
@@ -224,87 +201,11 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
var tileRange = tileGrid.getTileRangeForExtentAndResolution(
extent, tileResolution);
var canvasWidth = tilePixelSize[0] * tileRange.getWidth();
var canvasHeight = tilePixelSize[1] * tileRange.getHeight();
var canvas, context;
if (!this.canvas_) {
goog.asserts.assert(!this.canvasSize_,
'canvasSize is null (because canvas is null)');
goog.asserts.assert(!this.context_,
'context is null (because canvas is null)');
goog.asserts.assert(!this.renderedCanvasTileRange_,
'renderedCanvasTileRange is null (because canvas is null)');
context = ol.dom.createCanvasContext2D(canvasWidth, canvasHeight);
this.canvas_ = context.canvas;
this.canvasSize_ = [canvasWidth, canvasHeight];
this.context_ = context;
this.canvasTooBig_ =
!ol.renderer.canvas.Layer.testCanvasSize(this.canvasSize_);
} else {
goog.asserts.assert(this.canvasSize_,
'non-null canvasSize (because canvas is not null)');
goog.asserts.assert(this.context_,
'non-null context (because canvas is not null)');
canvas = this.canvas_;
context = this.context_;
if (this.canvasSize_[0] < canvasWidth ||
this.canvasSize_[1] < canvasHeight ||
this.renderedTileWidth_ !== tilePixelSize[0] ||
this.renderedTileHeight_ !== tilePixelSize[1] ||
(this.canvasTooBig_ && (this.canvasSize_[0] > canvasWidth ||
this.canvasSize_[1] > canvasHeight))) {
// Canvas is too small or tileSize has changed, resize it.
// We never shrink the canvas, unless
// we know that the current canvas size exceeds the maximum size
canvas.width = canvasWidth;
canvas.height = canvasHeight;
this.canvasSize_ = [canvasWidth, canvasHeight];
this.canvasTooBig_ =
!ol.renderer.canvas.Layer.testCanvasSize(this.canvasSize_);
this.renderedCanvasTileRange_ = null;
} else {
canvasWidth = this.canvasSize_[0];
canvasHeight = this.canvasSize_[1];
if (z != this.renderedCanvasZ_ ||
!this.renderedCanvasTileRange_.containsTileRange(tileRange)) {
this.renderedCanvasTileRange_ = null;
}
}
}
var canvasTileRange, canvasTileRangeWidth, minX, minY;
if (!this.renderedCanvasTileRange_) {
canvasTileRangeWidth = canvasWidth / tilePixelSize[0];
var canvasTileRangeHeight = canvasHeight / tilePixelSize[1];
minX = tileRange.minX -
Math.floor((canvasTileRangeWidth - tileRange.getWidth()) / 2);
minY = tileRange.minY -
Math.floor((canvasTileRangeHeight - tileRange.getHeight()) / 2);
this.renderedCanvasZ_ = z;
this.renderedTileWidth_ = tilePixelSize[0];
this.renderedTileHeight_ = tilePixelSize[1];
this.renderedCanvasTileRange_ = new ol.TileRange(
minX, minX + canvasTileRangeWidth - 1,
minY, minY + canvasTileRangeHeight - 1);
this.renderedTiles_ =
new Array(canvasTileRangeWidth * canvasTileRangeHeight);
canvasTileRange = this.renderedCanvasTileRange_;
} else {
canvasTileRange = this.renderedCanvasTileRange_;
canvasTileRangeWidth = canvasTileRange.getWidth();
}
goog.asserts.assert(canvasTileRange.containsTileRange(tileRange),
'tileRange is contained in canvasTileRange');
/**
* @type {Object.<number, Object.<string, ol.Tile>>}
*/
var tilesToDrawByZ = {};
tilesToDrawByZ[z] = {};
/** @type {Array.<ol.Tile>} */
var tilesToClear = [];
var findLoadedTiles = this.createLoadedTileFinder(
tileSource, projection, tilesToDrawByZ);
@@ -339,9 +240,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
if (!fullyLoaded) {
// FIXME we do not need to clear the tile if it is fully covered by its
// children
tilesToClear.push(tile);
childTileRange = tileGrid.getTileCoordChildTileRange(
tile.tileCoord, tmpTileRange, tmpExtent);
if (childTileRange) {
@@ -352,86 +250,49 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
}
}
var i, ii;
for (i = 0, ii = tilesToClear.length; i < ii; ++i) {
tile = tilesToClear[i];
x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX);
y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]);
context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]);
}
/** @type {Array.<number>} */
var zs = Object.keys(tilesToDrawByZ).map(Number);
zs.sort(ol.array.numberSafeCompareFunction);
var opaque = tileSource.getOpaque(projection);
var origin = ol.extent.getTopLeft(tileGrid.getTileCoordExtent(
[z, canvasTileRange.minX, canvasTileRange.maxY],
tmpExtent));
var currentZ, index, scale, tileCoordKey, tileExtent, tileState, tilesToDraw;
var ix, iy, interimTileRange, maxX, maxY;
var height, width;
var renderables = [];
var i, ii, currentZ, tileCoordKey, tilesToDraw;
for (i = 0, ii = zs.length; i < ii; ++i) {
currentZ = zs[i];
tilePixelSize =
tileSource.getTilePixelSize(currentZ, pixelRatio, projection);
tilesToDraw = tilesToDrawByZ[currentZ];
if (currentZ == z) {
for (tileCoordKey in tilesToDraw) {
tile = tilesToDraw[tileCoordKey];
index =
(tile.tileCoord[2] - canvasTileRange.minY) * canvasTileRangeWidth +
(tile.tileCoord[1] - canvasTileRange.minX);
if (this.renderedTiles_[index] != tile) {
x = tilePixelSize[0] * (tile.tileCoord[1] - canvasTileRange.minX);
y = tilePixelSize[1] * (canvasTileRange.maxY - tile.tileCoord[2]);
tileState = tile.getState();
if (tileState == ol.TileState.EMPTY ||
(tileState == ol.TileState.ERROR && !useInterimTilesOnError) ||
!opaque) {
context.clearRect(x, y, tilePixelSize[0], tilePixelSize[1]);
}
if (tileState == ol.TileState.LOADED) {
context.drawImage(tile.getImage(),
tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1],
x, y, tilePixelSize[0], tilePixelSize[1]);
}
this.renderedTiles_[index] = tile;
}
}
} else {
scale = tileGrid.getResolution(currentZ) / tileResolution;
for (tileCoordKey in tilesToDraw) {
tile = tilesToDraw[tileCoordKey];
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
x = (tileExtent[0] - origin[0]) / tilePixelResolution;
y = (origin[1] - tileExtent[3]) / tilePixelResolution;
width = scale * tilePixelSize[0];
height = scale * tilePixelSize[1];
tileState = tile.getState();
if (tileState == ol.TileState.EMPTY || !opaque) {
context.clearRect(x, y, width, height);
}
if (tileState == ol.TileState.LOADED) {
context.drawImage(tile.getImage(),
tileGutter, tileGutter, tilePixelSize[0], tilePixelSize[1],
x, y, width, height);
}
interimTileRange =
tileGrid.getTileRangeForExtentAndZ(tileExtent, z, tmpTileRange);
minX = Math.max(interimTileRange.minX, canvasTileRange.minX);
maxX = Math.min(interimTileRange.maxX, canvasTileRange.maxX);
minY = Math.max(interimTileRange.minY, canvasTileRange.minY);
maxY = Math.min(interimTileRange.maxY, canvasTileRange.maxY);
for (ix = minX; ix <= maxX; ++ix) {
for (iy = minY; iy <= maxY; ++iy) {
index = (iy - canvasTileRange.minY) * canvasTileRangeWidth +
(ix - canvasTileRange.minX);
this.renderedTiles_[index] = undefined;
}
}
for (tileCoordKey in tilesToDraw) {
tile = tilesToDraw[tileCoordKey];
if (tile.getState() == ol.TileState.LOADED) {
renderables.push(tile);
}
}
}
this.renderedTiles_ = renderables;
if (!tileSource.getOpaque(projection)) {
var clipExtents = {};
var tileCoord;
for (i = renderables.length - 1; i >= 0; --i) {
tileCoord = renderables[i].getTileCoord();
tileGrid.forEachTileCoordParentTileRange(tileCoord,
function(z, tileRange) {
var tiles = tilesToDrawByZ[z];
if (tiles) {
var key, tile;
for (key in tiles) {
tile = tiles[key];
if (tileRange.contains(tile.getTileCoord()) &&
tile.getState() == ol.TileState.LOADED) {
if (!(key in clipExtents)) {
clipExtents[key] = [];
}
clipExtents[key].push(tileGrid.getTileCoordExtent(tileCoord));
return true;
}
}
}
return false;
}, this, tmpTileRange, tmpExtent);
}
this.clipExtents_ = clipExtents;
}
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
this.manageTilePyramid(frameState, tileSource, tileGrid, pixelRatio,
@@ -439,16 +300,6 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
this.scheduleExpireCache(frameState, tileSource);
this.updateLogos(frameState, tileSource);
ol.vec.Mat4.makeTransform2D(this.imageTransform_,
pixelRatio * frameState.size[0] / 2,
pixelRatio * frameState.size[1] / 2,
pixelRatio * tilePixelResolution / viewState.resolution,
pixelRatio * tilePixelResolution / viewState.resolution,
viewState.rotation,
(origin[0] - center[0]) / tilePixelResolution,
(center[1] - origin[1]) / tilePixelResolution);
this.imageTransformInv_ = null;
return true;
};
@@ -456,21 +307,16 @@ ol.renderer.canvas.TileLayer.prototype.prepareFrame = function(frameState, layer
/**
* @inheritDoc
*/
ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function(pixel, frameState, callback, thisArg) {
if (!this.context_) {
return undefined;
}
if (!this.imageTransformInv_) {
this.imageTransformInv_ = goog.vec.Mat4.createNumber();
goog.vec.Mat4.invert(this.imageTransform_, this.imageTransformInv_);
}
var pixelOnCanvas =
this.getPixelOnCanvas(pixel, this.imageTransformInv_);
ol.renderer.canvas.TileLayer.prototype.forEachLayerAtPixel = function(
pixel, frameState, callback, thisArg) {
var canvas = this.context_.canvas;
var size = frameState.size;
canvas.width = size[0];
canvas.height = size[1];
this.composeFrame(frameState, this.getLayer().getLayerState(), this.context_);
var imageData = this.context_.getImageData(
pixelOnCanvas[0], pixelOnCanvas[1], 1, 1).data;
pixel[0], pixel[1], 1, 1).data;
if (imageData[3] > 0) {
return callback.call(thisArg, this.getLayer());

View File

@@ -7,6 +7,7 @@ goog.require('ol.dom');
goog.require('ol.extent');
goog.require('ol.layer.Vector');
goog.require('ol.render.EventType');
goog.require('ol.render.canvas');
goog.require('ol.render.canvas.ReplayGroup');
goog.require('ol.renderer.canvas.Layer');
goog.require('ol.renderer.vector');
@@ -106,6 +107,10 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
var alpha = replayContext.globalAlpha;
replayContext.globalAlpha = layerState.opacity;
var width = frameState.size[0] * pixelRatio;
var height = frameState.size[1] * pixelRatio;
ol.render.canvas.rotateAtOffset(replayContext, -rotation,
width / 2, height / 2);
replayGroup.replay(replayContext, pixelRatio, transform, rotation,
skippedFeatureUids);
if (vectorSource.getWrapX() && projection.canWrapX() &&
@@ -135,6 +140,8 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay
// restore original transform for render and compose events
transform = this.getTransform(frameState, 0);
}
ol.render.canvas.rotateAtOffset(replayContext, rotation,
width / 2, height / 2);
if (replayContext != context) {
this.dispatchRenderEvent(replayContext, frameState, transform);

View File

@@ -183,12 +183,9 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function(frameState,
0, 0, pixelScale, -pixelScale, 0, -center[0], -center[1]);
insertPoint = ol.geom.flat.transform.transform2D(
ol.extent.getTopLeft(tileExtent), 0, 1, 2, insertTransform);
replayContext.translate(offsetX, offsetY);
replayContext.rotate(rotation);
replayContext.drawImage(tileContext.canvas,
Math.round(insertPoint[0]), Math.round(insertPoint[1]));
replayContext.rotate(-rotation);
replayContext.translate(-offsetX, -offsetY);
Math.round(insertPoint[0] + offsetX),
Math.round(insertPoint[1]) + offsetY);
}
}

View File

@@ -94,7 +94,7 @@ ol.renderer.dom.TileLayer.prototype.prepareFrame = function(frameState, layerSta
'layer is an instance of ol.layer.Tile');
var tileSource = tileLayer.getSource();
var tileGrid = tileSource.getTileGridForProjection(projection);
var tileGutter = tileSource.getGutter();
var tileGutter = tileSource.getGutter(projection);
var z = tileGrid.getZForResolution(viewState.resolution);
var tileResolution = tileGrid.getResolution(z);
var center = viewState.center;

View File

@@ -169,7 +169,7 @@ ol.renderer.webgl.TileLayer.prototype.prepareFrame = function(frameState, layerS
var pixelRatio = tilePixelSize[0] /
ol.size.toSize(tileGrid.getTileSize(z), this.tmpSize_)[0];
var tilePixelResolution = tileResolution / pixelRatio;
var tileGutter = tileSource.getGutter();
var tileGutter = tileSource.getGutter(projection);
var center = viewState.center;
var extent;

View File

@@ -163,7 +163,7 @@ ol.reproj.Image.prototype.reproject_ = function() {
this.targetResolution_, this.targetExtent_, this.triangulation_, [{
extent: this.sourceImage_.getExtent(),
image: this.sourceImage_.getImage()
}]);
}], 0);
}
this.state = sourceState;
this.changed();

View File

@@ -101,12 +101,13 @@ ol.reproj.enlargeClipPoint_ = function(centroidX, centroidY, x, y) {
* @param {Array.<{extent: ol.Extent,
* image: (HTMLCanvasElement|Image|HTMLVideoElement)}>} sources
* Array of sources.
* @param {number} gutter Gutter of the sources.
* @param {boolean=} opt_renderEdges Render reprojection edges.
* @return {HTMLCanvasElement} Canvas with reprojected data.
*/
ol.reproj.render = function(width, height, pixelRatio,
sourceResolution, sourceExtent, targetResolution, targetExtent,
triangulation, sources, opt_renderEdges) {
triangulation, sources, gutter, opt_renderEdges) {
var context = ol.dom.createCanvasContext2D(Math.round(pixelRatio * width),
Math.round(pixelRatio * height));
@@ -128,17 +129,20 @@ ol.reproj.render = function(width, height, pixelRatio,
Math.round(pixelRatio * canvasWidthInUnits / sourceResolution),
Math.round(pixelRatio * canvasHeightInUnits / sourceResolution));
stitchContext.scale(pixelRatio / sourceResolution,
pixelRatio / sourceResolution);
stitchContext.translate(-sourceDataExtent[0], sourceDataExtent[3]);
var stitchScale = pixelRatio / sourceResolution;
sources.forEach(function(src, i, arr) {
var xPos = src.extent[0];
var yPos = -src.extent[3];
var xPos = src.extent[0] - sourceDataExtent[0];
var yPos = -(src.extent[3] - sourceDataExtent[3]);
var srcWidth = ol.extent.getWidth(src.extent);
var srcHeight = ol.extent.getHeight(src.extent);
stitchContext.drawImage(src.image, xPos, yPos, srcWidth, srcHeight);
stitchContext.drawImage(
src.image,
gutter, gutter,
src.image.width - 2 * gutter, src.image.height - 2 * gutter,
xPos * stitchScale, yPos * stitchScale,
srcWidth * stitchScale, srcHeight * stitchScale);
});
var targetTopLeft = ol.extent.getTopLeft(targetExtent);

View File

@@ -35,6 +35,7 @@ ol.reproj.TileFunctionType;
* @param {ol.TileCoord} tileCoord Coordinate of the tile.
* @param {ol.TileCoord} wrappedTileCoord Coordinate of the tile wrapped in X.
* @param {number} pixelRatio Pixel ratio.
* @param {number} gutter Gutter of the source tiles.
* @param {ol.reproj.TileFunctionType} getTileFunction
* Function returning source tiles (z, x, y, pixelRatio).
* @param {number=} opt_errorThreshold Acceptable reprojection error (in px).
@@ -42,7 +43,7 @@ ol.reproj.TileFunctionType;
*/
ol.reproj.Tile = function(sourceProj, sourceTileGrid,
targetProj, targetTileGrid, tileCoord, wrappedTileCoord,
pixelRatio, getTileFunction,
pixelRatio, gutter, getTileFunction,
opt_errorThreshold,
opt_renderEdges) {
goog.base(this, tileCoord, ol.TileState.IDLE);
@@ -59,6 +60,12 @@ ol.reproj.Tile = function(sourceProj, sourceTileGrid,
*/
this.pixelRatio_ = pixelRatio;
/**
* @private
* @type {number}
*/
this.gutter_ = gutter;
/**
* @private
* @type {HTMLCanvasElement}
@@ -269,7 +276,7 @@ ol.reproj.Tile.prototype.reproject_ = function() {
this.canvas_ = ol.reproj.render(width, height, this.pixelRatio_,
sourceResolution, this.sourceTileGrid_.getExtent(),
targetResolution, targetExtent, this.triangulation_, sources,
this.renderEdges_);
this.gutter_, this.renderEdges_);
this.state = ol.TileState.LOADED;
}

View File

@@ -344,39 +344,20 @@ ol.source.Raster.prototype.onWorkerComplete_ = function(frameState, callback, er
*/
ol.source.Raster.getImageData_ = function(renderer, frameState, layerState) {
renderer.prepareFrame(frameState, layerState);
// We should be able to call renderer.composeFrame(), but this is inefficient
// for tiled sources (we've already rendered to an intermediate canvas in the
// prepareFrame call and we don't need to render again to the output canvas).
// TODO: make all canvas renderers render to a single canvas
var image = renderer.getImage();
if (!image) {
return null;
}
var imageTransform = renderer.getImageTransform();
var dx = Math.round(goog.vec.Mat4.getElement(imageTransform, 0, 3));
var dy = Math.round(goog.vec.Mat4.getElement(imageTransform, 1, 3));
var width = frameState.size[0];
var height = frameState.size[1];
if (image instanceof Image) {
if (!ol.source.Raster.context_) {
if (!ol.source.Raster.context_) {
ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
} else {
var canvas = ol.source.Raster.context_.canvas;
if (canvas.width !== width || canvas.height !== height) {
ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
} else {
var canvas = ol.source.Raster.context_.canvas;
if (canvas.width !== width || canvas.height !== height) {
ol.source.Raster.context_ = ol.dom.createCanvasContext2D(width, height);
} else {
ol.source.Raster.context_.clearRect(0, 0, width, height);
}
ol.source.Raster.context_.clearRect(0, 0, width, height);
}
var dw = Math.round(
image.width * goog.vec.Mat4.getElement(imageTransform, 0, 0));
var dh = Math.round(
image.height * goog.vec.Mat4.getElement(imageTransform, 1, 1));
ol.source.Raster.context_.drawImage(image, dx, dy, dw, dh);
return ol.source.Raster.context_.getImageData(0, 0, width, height);
} else {
return image.getContext('2d').getImageData(-dx, -dy, width, height);
}
renderer.composeFrame(frameState, layerState, ol.source.Raster.context_);
return ol.source.Raster.context_.getImageData(0, 0, width, height);
};

View File

@@ -120,6 +120,29 @@ ol.source.TileImage.prototype.expireCache = function(projection, usedTiles) {
};
/**
* @inheritDoc
*/
ol.source.TileImage.prototype.getGutter = function(projection) {
if (ol.ENABLE_RASTER_REPROJECTION &&
this.getProjection() && projection &&
!ol.proj.equivalent(this.getProjection(), projection)) {
return 0;
} else {
return this.getGutterInternal();
}
};
/**
* @protected
* @return {number} Gutter.
*/
ol.source.TileImage.prototype.getGutterInternal = function() {
return 0;
};
/**
* @inheritDoc
*/
@@ -230,6 +253,7 @@ ol.source.TileImage.prototype.getTile = function(z, x, y, pixelRatio, projection
sourceProjection, sourceTileGrid,
projection, targetTileGrid,
tileCoord, wrappedTileCoord, this.getTilePixelRatio(pixelRatio),
this.getGutterInternal(),
function(z, x, y, pixelRatio) {
return this.getTileInternal(z, x, y, pixelRatio, sourceProjection);
}.bind(this), this.reprojectionErrorThreshold_,

View File

@@ -147,9 +147,10 @@ ol.source.Tile.prototype.forEachLoadedTile = function(projection, z, tileRange,
/**
* @param {ol.proj.Projection} projection Projection.
* @return {number} Gutter.
*/
ol.source.Tile.prototype.getGutter = function() {
ol.source.Tile.prototype.getGutter = function(projection) {
return 0;
};

View File

@@ -177,7 +177,7 @@ ol.source.TileWMS.prototype.getGetFeatureInfoUrl = function(coordinate, resoluti
/**
* @inheritDoc
*/
ol.source.TileWMS.prototype.getGutter = function() {
ol.source.TileWMS.prototype.getGutterInternal = function() {
return this.gutter_;
};