From 1c73dc9088c7ebca682bf7b94f94d41394525e93 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 23 Aug 2016 15:12:19 +0200 Subject: [PATCH 1/3] Enable extent clipping for vector layers --- src/ol/renderer/canvas/layer.js | 57 ++++++++++++++++----------- src/ol/renderer/canvas/vectorlayer.js | 9 +++++ 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/ol/renderer/canvas/layer.js b/src/ol/renderer/canvas/layer.js index 1bcf37b4cd..6bf1d0f738 100644 --- a/src/ol/renderer/canvas/layer.js +++ b/src/ol/renderer/canvas/layer.js @@ -29,6 +29,39 @@ ol.renderer.canvas.Layer = function(layer) { ol.inherits(ol.renderer.canvas.Layer, ol.renderer.Layer); +/** + * @param {CanvasRenderingContext2D} context Context. + * @param {olx.FrameState} frameState Frame state. + * @param {ol.Extent} extent Clip extent. + * @protected + */ +ol.renderer.canvas.Layer.prototype.clip = function(context, frameState, extent) { + 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(/** @type {ol.Extent} */ (extent)); + var topRight = ol.extent.getTopRight(/** @type {ol.Extent} */ (extent)); + var bottomRight = ol.extent.getBottomRight(/** @type {ol.Extent} */ (extent)); + var bottomLeft = ol.extent.getBottomLeft(/** @type {ol.Extent} */ (extent)); + + ol.transform.apply(frameState.coordinateToPixelTransform, topLeft); + ol.transform.apply(frameState.coordinateToPixelTransform, topRight); + ol.transform.apply(frameState.coordinateToPixelTransform, bottomRight); + ol.transform.apply(frameState.coordinateToPixelTransform, 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); +}; + + /** * @param {olx.FrameState} frameState Frame state. * @param {ol.LayerState} layerState Layer state. @@ -45,29 +78,7 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat var extent = layerState.extent; var clipped = extent !== undefined; if (clipped) { - 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(/** @type {ol.Extent} */ (extent)); - var topRight = ol.extent.getTopRight(/** @type {ol.Extent} */ (extent)); - var bottomRight = ol.extent.getBottomRight(/** @type {ol.Extent} */ (extent)); - var bottomLeft = ol.extent.getBottomLeft(/** @type {ol.Extent} */ (extent)); - - ol.transform.apply(frameState.coordinateToPixelTransform, topLeft); - ol.transform.apply(frameState.coordinateToPixelTransform, topRight); - ol.transform.apply(frameState.coordinateToPixelTransform, bottomRight); - ol.transform.apply(frameState.coordinateToPixelTransform, 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); + this.clip(context, frameState, extent); } var imageTransform = this.getImageTransform(); diff --git a/src/ol/renderer/canvas/vectorlayer.js b/src/ol/renderer/canvas/vectorlayer.js index f48a23ee2a..fc1ef29379 100644 --- a/src/ol/renderer/canvas/vectorlayer.js +++ b/src/ol/renderer/canvas/vectorlayer.js @@ -85,6 +85,12 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay this.dispatchPreComposeEvent(context, frameState, transform); + // clipped rendering if layer extent is set + var clipExtent = layerState.extent; + var clipped = clipExtent !== undefined; + if (clipped) { + this.clip(context, frameState, clipExtent); + } var replayGroup = this.replayGroup_; if (replayGroup && !replayGroup.isEmpty()) { var layer = this.getLayer(); @@ -160,6 +166,9 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay replayContext.globalAlpha = alpha; } + if (clipped) { + context.restore(); + } this.dispatchPostComposeEvent(context, frameState, transform); }; From f490302959d3f8d4af03bf0d41f619b78da4df52 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 23 Aug 2016 15:20:00 +0200 Subject: [PATCH 2/3] Enable extent clipping for vector tile layers --- src/ol/renderer/canvas/vectortilelayer.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index 3f41dc906c..143f98a1af 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -72,6 +72,14 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( frameState, layerState, context) { var transform = this.getTransform(frameState, 0); this.dispatchPreComposeEvent(context, frameState, transform); + + // clipped rendering if layer extent is set + var extent = layerState.extent; + var clipped = extent !== undefined; + if (clipped) { + this.clip(context, frameState, extent); + } + var renderMode = this.getLayer().getRenderMode(); if (renderMode !== ol.layer.VectorTileRenderType.VECTOR) { this.renderTileImages(context, frameState, layerState); @@ -79,6 +87,11 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( if (renderMode !== ol.layer.VectorTileRenderType.IMAGE) { this.renderTileReplays_(context, frameState, layerState); } + + if (clipped) { + context.restore(); + } + this.dispatchPostComposeEvent(context, frameState, transform); }; From 8992ee8e73b260bbc3b7d444fb7c8e3b32a4d436 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 23 Aug 2016 15:33:52 +0200 Subject: [PATCH 3/3] Entertain the compiler --- src/ol/renderer/canvas/layer.js | 2 +- src/ol/renderer/canvas/vectorlayer.js | 2 +- src/ol/renderer/canvas/vectortilelayer.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ol/renderer/canvas/layer.js b/src/ol/renderer/canvas/layer.js index 6bf1d0f738..296f4d8fe4 100644 --- a/src/ol/renderer/canvas/layer.js +++ b/src/ol/renderer/canvas/layer.js @@ -78,7 +78,7 @@ ol.renderer.canvas.Layer.prototype.composeFrame = function(frameState, layerStat var extent = layerState.extent; var clipped = extent !== undefined; if (clipped) { - this.clip(context, frameState, extent); + this.clip(context, frameState, /** @type {ol.Extent} */ (extent)); } var imageTransform = this.getImageTransform(); diff --git a/src/ol/renderer/canvas/vectorlayer.js b/src/ol/renderer/canvas/vectorlayer.js index fc1ef29379..0525478346 100644 --- a/src/ol/renderer/canvas/vectorlayer.js +++ b/src/ol/renderer/canvas/vectorlayer.js @@ -89,7 +89,7 @@ ol.renderer.canvas.VectorLayer.prototype.composeFrame = function(frameState, lay var clipExtent = layerState.extent; var clipped = clipExtent !== undefined; if (clipped) { - this.clip(context, frameState, clipExtent); + this.clip(context, frameState, /** @type {ol.Extent} */ (clipExtent)); } var replayGroup = this.replayGroup_; if (replayGroup && !replayGroup.isEmpty()) { diff --git a/src/ol/renderer/canvas/vectortilelayer.js b/src/ol/renderer/canvas/vectortilelayer.js index 143f98a1af..bd86581aec 100644 --- a/src/ol/renderer/canvas/vectortilelayer.js +++ b/src/ol/renderer/canvas/vectortilelayer.js @@ -77,7 +77,7 @@ ol.renderer.canvas.VectorTileLayer.prototype.composeFrame = function( var extent = layerState.extent; var clipped = extent !== undefined; if (clipped) { - this.clip(context, frameState, extent); + this.clip(context, frameState, /** @type {ol.Extent} */ (extent)); } var renderMode = this.getLayer().getRenderMode();