From 63cf21b6689e11c767955d4657c6f5bd3afc7634 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:41:33 +0100 Subject: [PATCH 1/8] Dedicated function for inverting a transform without modifying the source --- src/ol/transform.js | 52 ++++++++++++++++++++-------------- test/spec/ol/transform.test.js | 39 +++++++++++++++++++++---- 2 files changed, 64 insertions(+), 27 deletions(-) diff --git a/src/ol/transform.js b/src/ol/transform.js index cbb19c3c39..1694a4c95e 100644 --- a/src/ol/transform.js +++ b/src/ol/transform.js @@ -203,30 +203,40 @@ export function compose(transform, dx1, dy1, sx, sy, angle, dx2, dy2) { /** * Invert the given transform. - * @param {!Transform} transform Transform. - * @return {!Transform} Inverse of the transform. + * @param {!Transform} source The source transform to invert. + * @return {!Transform} The inverted (source) transform. */ -export function invert(transform) { - const det = determinant(transform); - assert(det !== 0, 32); // Transformation matrix cannot be inverted - - const a = transform[0]; - const b = transform[1]; - const c = transform[2]; - const d = transform[3]; - const e = transform[4]; - const f = transform[5]; - - transform[0] = d / det; - transform[1] = -b / det; - transform[2] = -c / det; - transform[3] = a / det; - transform[4] = (c * f - d * e) / det; - transform[5] = -(a * f - b * e) / det; - - return transform; +export function invert(source) { + return makeInverse(source, source); } +/** + * Invert the given transform. + * @param {!Transform} source The source transform to invert. + * @param {!Transform} target Transform to be set as the inverse of + * the source transform. + * @return {!Transform} The inverted (target) transform. + */ +export function makeInverse(source, target) { + const det = determinant(source); + assert(det !== 0, 32); // Transformation matrix cannot be inverted + + const a = source[0]; + const b = source[1]; + const c = source[2]; + const d = source[3]; + const e = source[4]; + const f = source[5]; + + target[0] = d / det; + target[1] = -b / det; + target[2] = -c / det; + target[3] = a / det; + target[4] = (c * f - d * e) / det; + target[5] = -(a * f - b * e) / det; + + return target; +} /** * Returns the determinant of the given matrix. diff --git a/test/spec/ol/transform.test.js b/test/spec/ol/transform.test.js index 13b5d91846..4cc8427fa2 100644 --- a/test/spec/ol/transform.test.js +++ b/test/spec/ol/transform.test.js @@ -9,6 +9,7 @@ import { multiply, compose, invert, + makeInverse, apply } from '../../../src/ol/transform.js'; @@ -110,13 +111,39 @@ describe('ol.transform', function() { describe('invert()', function() { it('inverts a transform', function() { - let transform = [1, 0, 1, 0, 1, 0]; - expect(function() { - invert(transform); - }).to.throwException(); - transform = [1, 1, 1, 2, 2, 0]; + const transform = [1, 1, 1, 2, 2, 0]; expect(invert(transform)).to.eql([2, -1, -1, 1, -4, 2]); - expect(transform).to.eql([2, -1, -1, 1, -4, 2]); + }); + + it('throws if the transform cannot be inverted', function() { + const indeterminant = [1, 0, 1, 0, 1, 0]; + expect(function() { + invert(indeterminant); + }).to.throwException(); + }); + + it('modifies the source', function() { + const source = [1, 1, 1, 2, 2, 0]; + const inverted = invert(source); + expect(inverted).to.eql([2, -1, -1, 1, -4, 2]); + expect(source).to.be(inverted); + }); + }); + + describe('makeInverse()', function() { + it('makes the target the inverse of the source', function() { + const source = [1, 1, 1, 2, 2, 0]; + const target = [1, 0, 0, 1, 0, 0]; + makeInverse(source, target); + expect(source).to.eql([1, 1, 1, 2, 2, 0]); + expect(target).to.eql([2, -1, -1, 1, -4, 2]); + }); + + it('returns the target', function() { + const source = [1, 1, 1, 2, 2, 0]; + const target = [1, 0, 0, 1, 0, 0]; + const inverted = makeInverse(source, target); + expect(target).to.be(inverted); }); }); From db1f4321976a030b327a4d7556897c3257ca4881 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:42:31 +0100 Subject: [PATCH 2/8] Function for making a scale transform --- src/ol/transform.js | 10 ++++++++++ test/spec/ol/transform.test.js | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/ol/transform.js b/src/ol/transform.js index 1694a4c95e..126c92129a 100644 --- a/src/ol/transform.js +++ b/src/ol/transform.js @@ -162,6 +162,16 @@ export function scale(transform, x, y) { return multiply(transform, set(tmp_, x, 0, 0, y, 0, 0)); } +/** + * Creates a scale transform. + * @param {!Transform} target Transform to overwrite. + * @param {number} x Scale factor x. + * @param {number} y Scale factor y. + * @return {!Transform} The scale transform. + */ +export function makeScale(target, x, y) { + return set(target, x, 0, 0, y, 0, 0); +} /** * Applies translation to the given transform. diff --git a/test/spec/ol/transform.test.js b/test/spec/ol/transform.test.js index 4cc8427fa2..4c7ea2df81 100644 --- a/test/spec/ol/transform.test.js +++ b/test/spec/ol/transform.test.js @@ -5,6 +5,7 @@ import { setFromArray, translate, scale, + makeScale, rotate, multiply, compose, @@ -69,6 +70,20 @@ describe('ol.transform', function() { }); }); + describe('makeScale()', function() { + it('creates a scale transform', function() { + const target = create(); + makeScale(target, 2, 3); + expect(target).to.eql([2, 0, 0, 3, 0, 0]); + }); + + it('returns the target', function() { + const target = create(); + const transform = makeScale(target, 2, 3); + expect(transform).to.be(target); + }); + }); + describe('rotate()', function() { it('applies rotation to a transform', function() { const transform = create(); From 686847f491a8ae6d123493fbf4d196c162dba559 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:46:38 +0100 Subject: [PATCH 3/8] Make forward and inverse pixel transforms during render --- src/ol/renderer/canvas/ImageLayer.js | 14 ++++++++------ src/ol/renderer/canvas/Layer.js | 14 ++++++++++++-- src/ol/renderer/canvas/TileLayer.js | 10 +++++++--- src/ol/renderer/canvas/VectorLayer.js | 9 +++++---- src/ol/renderer/canvas/VectorTileLayer.js | 17 ++++++++++++++--- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 405dd4ec05..8b1d80f7a2 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -6,7 +6,7 @@ import ViewHint from '../../ViewHint.js'; import {containsExtent, intersects} from '../../extent.js'; import {getIntersection, isEmpty} from '../../extent.js'; import CanvasLayerRenderer from './Layer.js'; -import {compose as composeTransform, toString as transformToString} from '../../transform.js'; +import {compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js'; /** * @classdesc @@ -93,16 +93,17 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { width = height = size; } - const context = this.context; - const canvas = context.canvas; - - const pixelTransform = composeTransform(this.pixelTransform_, + // set forward and inverse pixel transforms + composeTransform(this.pixelTransform_, frameState.size[0] / 2, frameState.size[1] / 2, 1 / pixelRatio, 1 / pixelRatio, rotation, -width / 2, -height / 2 ); - const canvasTransform = transformToString(pixelTransform); + makeInverse(this.pixelTransform_, this.inversePixelTransform_); + + const context = this.context; + const canvas = context.canvas; if (canvas.width != width || canvas.height != height) { canvas.width = width; @@ -150,6 +151,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { canvas.style.opacity = opacity; } + const canvasTransform = transformToString(this.pixelTransform_); if (canvasTransform !== canvas.style.transform) { canvas.style.transform = canvasTransform; } diff --git a/src/ol/renderer/canvas/Layer.js b/src/ol/renderer/canvas/Layer.js index 212ee2d995..dbdf6c8b0d 100644 --- a/src/ol/renderer/canvas/Layer.js +++ b/src/ol/renderer/canvas/Layer.js @@ -28,19 +28,29 @@ class CanvasLayerRenderer extends LayerRenderer { this.renderedResolution; /** - * A temporary transform. + * A temporary transform. The values in this transform should only be used in a + * function that sets the values. * @private * @type {import("../../transform.js").Transform} */ this.tempTransform_ = createTransform(); /** - * The transform for rendered pixels to viewport CSS pixels. + * The transform for rendered pixels to viewport CSS pixels. This transform must + * be set when rendering a frame and may be used by other functions after rendering. * @private * @type {import("../../transform.js").Transform} */ this.pixelTransform_ = createTransform(); + /** + * The transform for viewport CSS pixels to rendered pixels. This transform must + * be set when rendering a frame and may be used by other functions after rendering. + * @private + * @type {import("../../transform.js").Transform} + */ + this.inversePixelTransform_ = createTransform(); + /** * @protected * @type {CanvasRenderingContext2D} diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 3c8c56a8a2..59f199a6cc 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -6,7 +6,7 @@ import TileRange from '../../TileRange.js'; import TileState from '../../TileState.js'; import {createEmpty, getIntersection, getTopLeft} from '../../extent.js'; import CanvasLayerRenderer from './Layer.js'; -import {compose as composeTransform, toString as transformToString} from '../../transform.js'; +import {compose as composeTransform, makeInverse, toString as transformToString} from '../../transform.js'; /** * @classdesc @@ -222,15 +222,18 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { } } + const canvas = context.canvas; const canvasScale = tileResolution / frameState.viewState.resolution / tilePixelRatio; - const pixelTransform = composeTransform(this.pixelTransform_, + + // set forward and inverse pixel transforms + composeTransform(this.pixelTransform_, frameState.size[0] / 2, frameState.size[1] / 2, canvasScale, canvasScale, rotation, -width / 2, -height / 2 ); - const canvasTransform = transformToString(pixelTransform); + makeInverse(this.pixelTransform_, this.inversePixelTransform_); if (canvas.width != width || canvas.height != height) { canvas.width = width; @@ -302,6 +305,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { canvas.style.opacity = opacity; } + const canvasTransform = transformToString(this.pixelTransform_); if (canvasTransform !== canvas.style.transform) { canvas.style.transform = canvasTransform; } diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 78ffb866d4..9a31ef1982 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -13,7 +13,7 @@ import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js'; import InstructionsGroupExecutor from '../../render/canvas/ExecutorGroup.js'; import CanvasLayerRenderer from './Layer.js'; import {defaultOrder as defaultRenderOrder, getTolerance as getRenderTolerance, getSquaredTolerance as getSquaredRenderTolerance, renderFeature} from '../vector.js'; -import {toString as transformToString} from '../../transform.js'; +import {toString as transformToString, makeScale, makeInverse} from '../../transform.js'; /** * @classdesc @@ -105,8 +105,9 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { const pixelRatio = frameState.pixelRatio; - // a scale transform (we could add a createScale function in ol/transform) - const pixelTransform = [1 / pixelRatio, 0, 0, 1 / pixelRatio, 0, 0]; + // set forward and inverse pixel transforms + makeScale(this.pixelTransform_, 1 / pixelRatio, 1 / pixelRatio); + makeInverse(this.pixelTransform_, this.inversePixelTransform_); // resize and clear const width = Math.round(frameState.size[0] * pixelRatio); @@ -114,7 +115,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { if (canvas.width != width || canvas.height != height) { canvas.width = width; canvas.height = height; - const canvasTransform = transformToString(pixelTransform); + const canvasTransform = transformToString(this.pixelTransform_); if (canvas.style.transform !== canvasTransform) { canvas.style.transform = canvasTransform; } diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 8d58fbafec..9630ee99c5 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -26,7 +26,9 @@ import { reset as resetTransform, scale as scaleTransform, translate as translateTransform, - toString as transformToString + toString as transformToString, + makeScale, + makeInverse } from '../../transform.js'; import CanvasExecutorGroup, {replayDeclutter} from '../../render/canvas/ExecutorGroup.js'; @@ -98,6 +100,13 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { */ this.overlayPixelTransform_ = createTransform(); + /** + * The transform for viewport CSS pixels to rendered pixels for the overlay canvas. + * @private + * @type {import("../../transform.js").Transform} + */ + this.inverseOverlayPixelTransform_ = createTransform(); + /** * Declutter tree. * @private @@ -384,12 +393,14 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { const rotation = frameState.viewState.rotation; const size = frameState.size; + // set forward and inverse pixel transforms + makeScale(this.overlayPixelTransform_, 1 / pixelRatio, 1 / pixelRatio); + makeInverse(this.overlayPixelTransform_, this.inverseOverlayPixelTransform_); + // resize and clear const canvas = context.canvas; const width = Math.round(size[0] * pixelRatio); const height = Math.round(size[1] * pixelRatio); - this.overlayPixelTransform_[0] = 1 / pixelRatio; - this.overlayPixelTransform_[3] = 1 / pixelRatio; if (canvas.width != width || canvas.height != height) { canvas.width = width; canvas.height = height; From af10f6a75c7aab8cabd14b28dfdd348d6bfad745 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:49:02 +0100 Subject: [PATCH 4/8] Use the inverse pixel transform in pre/post render events --- src/ol/render.js | 4 ++-- src/ol/render/Event.js | 11 ++++++----- src/ol/renderer/canvas/Layer.js | 28 +++++++-------------------- src/ol/renderer/canvas/TileLayer.js | 4 ++-- src/ol/renderer/canvas/VectorLayer.js | 8 ++------ 5 files changed, 19 insertions(+), 36 deletions(-) diff --git a/src/ol/render.js b/src/ol/render.js index 0f39bf8803..ec8d3be91c 100644 --- a/src/ol/render.js +++ b/src/ol/render.js @@ -92,7 +92,7 @@ export function toContext(context, opt_options) { */ export function getVectorContext(event) { const frameState = event.frameState; - const transform = multiplyTransform(invertTransform(event.pixelTransform.slice()), frameState.coordinateToPixelTransform); + const transform = multiplyTransform(event.inversePixelTransform.slice(), frameState.coordinateToPixelTransform); return new CanvasImmediateRenderer( event.context, frameState.pixelRatio, frameState.extent, transform, frameState.viewState.rotation); @@ -108,6 +108,6 @@ export function getVectorContext(event) { */ export function getPixelFromPixel(event, pixel) { const result = pixel.slice(0); - applyTransform(invertTransform(event.pixelTransform.slice()), result); + applyTransform(event.inversePixelTransform.slice(), result); return result; } diff --git a/src/ol/render/Event.js b/src/ol/render/Event.js index 28caf9fdc2..36d09cf465 100644 --- a/src/ol/render/Event.js +++ b/src/ol/render/Event.js @@ -8,22 +8,23 @@ class RenderEvent extends Event { /** * @param {import("./EventType.js").default} type Type. - * @param {import("../transform.js").Transform=} opt_pixelTransform Transform. + * @param {import("../transform.js").Transform=} opt_inversePixelTransform Transform for + * CSS pixels to rendered pixels. * @param {import("../PluggableMap.js").FrameState=} opt_frameState Frame state. * @param {?CanvasRenderingContext2D=} opt_context Context. * @param {?import("../webgl/Helper.js").default=} opt_glContext WebGL Context. */ - constructor(type, opt_pixelTransform, opt_frameState, opt_context, opt_glContext) { + constructor(type, opt_inversePixelTransform, opt_frameState, opt_context, opt_glContext) { super(type); /** - * Transform from css pixels (relative to the top-left corner of the map viewport) - * to render pixel on this event's `context`. + * Transform from CSS pixels (relative to the top-left corner of the map viewport) + * to rendered pixels on this event's `context`. * @type {import("../transform.js").Transform|undefined} * @api */ - this.pixelTransform = opt_pixelTransform; + this.inversePixelTransform = opt_inversePixelTransform; /** * An object representing the current render frame state. diff --git a/src/ol/renderer/canvas/Layer.js b/src/ol/renderer/canvas/Layer.js index dbdf6c8b0d..6ae13eccff 100644 --- a/src/ol/renderer/canvas/Layer.js +++ b/src/ol/renderer/canvas/Layer.js @@ -132,46 +132,32 @@ class CanvasLayerRenderer extends LayerRenderer { * @param {import("../../render/EventType.js").default} type Event type. * @param {CanvasRenderingContext2D} context Context. * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. - * @param {import("../../transform.js").Transform} pixelTransform Transform. * @private */ - dispatchComposeEvent_(type, context, frameState, pixelTransform) { + dispatchRenderEvent_(type, context, frameState) { const layer = this.getLayer(); if (layer.hasListener(type)) { - const composeEvent = new RenderEvent(type, pixelTransform, frameState, - context, null); - layer.dispatchEvent(composeEvent); + const event = new RenderEvent(type, this.inversePixelTransform_, frameState, context, null); + layer.dispatchEvent(event); } } /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. - * @param {import("../../transform.js").Transform=} opt_transform Transform. * @protected */ - preRender(context, frameState, opt_transform) { - this.dispatchComposeEvent_(RenderEventType.PRERENDER, context, frameState, opt_transform); + preRender(context, frameState) { + this.dispatchRenderEvent_(RenderEventType.PRERENDER, context, frameState); } /** * @param {CanvasRenderingContext2D} context Context. * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. - * @param {import("../../transform.js").Transform=} opt_transform Transform. * @protected */ - postRender(context, frameState, opt_transform) { - this.dispatchComposeEvent_(RenderEventType.POSTRENDER, context, frameState, opt_transform); - } - - /** - * @param {CanvasRenderingContext2D} context Context. - * @param {import("../../PluggableMap.js").FrameState} frameState Frame state. - * @param {import("../../transform.js").Transform=} opt_transform Transform. - * @protected - */ - dispatchRenderEvent(context, frameState, opt_transform) { - this.dispatchComposeEvent_(RenderEventType.RENDER, context, frameState, opt_transform); + postRender(context, frameState) { + this.dispatchRenderEvent_(RenderEventType.POSTRENDER, context, frameState); } /** diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 59f199a6cc..09949a6605 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -246,7 +246,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { this.clipUnrotated(context, frameState, layerState.extent); } - this.preRender(context, frameState, pixelTransform); + this.preRender(context, frameState); this.renderedTiles.length = 0; /** @type {Array} */ @@ -294,7 +294,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { projection, extent, z, tileLayer.getPreload()); this.scheduleExpireCache(frameState, tileSource); - this.postRender(context, frameState, pixelTransform); + this.postRender(context, frameState); if (layerState.extent) { context.restore(); diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 9a31ef1982..810760b228 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -123,7 +123,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { context.clearRect(0, 0, width, height); } - this.preRender(context, frameState, pixelTransform); + this.preRender(context, frameState); const extent = frameState.extent; const viewState = frameState.viewState; @@ -174,15 +174,11 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { } } - if (this.getLayer().hasListener(RenderEventType.RENDER)) { - this.dispatchRenderEvent(context, frameState, pixelTransform); - } - if (clipped) { context.restore(); } - this.postRender(context, frameState, pixelTransform); + this.postRender(context, frameState); const opacity = layerState.opacity; if (opacity !== canvas.style.opacity) { From 1cc49e0b23159f942f7aa0121a1e64193206669f Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:49:29 +0100 Subject: [PATCH 5/8] Clearer function name for getting a render pixel --- examples/magnify.js | 6 +++--- src/ol/render.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/magnify.js b/examples/magnify.js index 9193b2f1d2..f3822688ec 100644 --- a/examples/magnify.js +++ b/examples/magnify.js @@ -3,7 +3,7 @@ import View from '../src/ol/View.js'; import TileLayer from '../src/ol/layer/Tile.js'; import {fromLonLat} from '../src/ol/proj.js'; import BingMaps from '../src/ol/source/BingMaps.js'; -import {getPixelFromPixel} from '../src/ol/render.js'; +import {getRenderPixel} from '../src/ol/render.js'; const key = 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'; @@ -51,8 +51,8 @@ container.addEventListener('mouseout', function() { // after rendering the layer, show an oversampled version around the pointer imagery.on('postrender', function(event) { if (mousePosition) { - const pixel = getPixelFromPixel(event, mousePosition); - const offset = getPixelFromPixel(event, [mousePosition[0] + radius, mousePosition[1]]); + const pixel = getRenderPixel(event, mousePosition); + const offset = getRenderPixel(event, [mousePosition[0] + radius, mousePosition[1]]); const half = Math.sqrt(Math.pow(offset[0] - pixel[0], 2) + Math.pow(offset[1] - pixel[1], 2)); const context = event.context; const centerX = pixel[0]; diff --git a/src/ol/render.js b/src/ol/render.js index ec8d3be91c..f0e92541ca 100644 --- a/src/ol/render.js +++ b/src/ol/render.js @@ -99,14 +99,14 @@ export function getVectorContext(event) { } /** - * Gets the pixel of the event's canvas context from the map viewport's css pixel + * Gets the pixel of the event's canvas context from the map viewport's CSS pixel. * @param {import("./render/Event.js").default} event Render event. - * @param {import("./pixel.js").Pixel} pixel Css pixel relative to the top-left + * @param {import("./pixel.js").Pixel} pixel CSS pixel relative to the top-left * corner of the map viewport. * @returns {import("./pixel.js").Pixel} Pixel on the event's canvas context. * @api */ -export function getPixelFromPixel(event, pixel) { +export function getRenderPixel(event, pixel) { const result = pixel.slice(0); applyTransform(event.inversePixelTransform.slice(), result); return result; From 06a0a7f33bef4f4e9030765a2adb2bc1aa9e1815 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 14:53:50 +0100 Subject: [PATCH 6/8] Use the inverse pixel transform when clipping and getting pixel data --- src/ol/render.js | 1 - src/ol/renderer/canvas/Layer.js | 7 +++---- src/ol/renderer/canvas/VectorTileLayer.js | 3 +-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/ol/render.js b/src/ol/render.js index f0e92541ca..330e5aafa6 100644 --- a/src/ol/render.js +++ b/src/ol/render.js @@ -5,7 +5,6 @@ import {DEVICE_PIXEL_RATIO} from './has.js'; import { apply as applyTransform, create as createTransform, - invert as invertTransform, multiply as multiplyTransform, scale as scaleTransform } from './transform.js'; diff --git a/src/ol/renderer/canvas/Layer.js b/src/ol/renderer/canvas/Layer.js index 6ae13eccff..6417f7807a 100644 --- a/src/ol/renderer/canvas/Layer.js +++ b/src/ol/renderer/canvas/Layer.js @@ -7,7 +7,7 @@ import RenderEvent from '../../render/Event.js'; import RenderEventType from '../../render/EventType.js'; import {rotateAtOffset} from '../../render/canvas.js'; import LayerRenderer from '../Layer.js'; -import {invert as invertTransform, create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js'; +import {create as createTransform, apply as applyTransform, compose as composeTransform} from '../../transform.js'; /** * @abstract @@ -112,8 +112,7 @@ class CanvasLayerRenderer extends LayerRenderer { applyTransform(frameState.coordinateToPixelTransform, bottomRight); applyTransform(frameState.coordinateToPixelTransform, bottomLeft); - const inverted = invertTransform(this.pixelTransform_.slice()); - + const inverted = this.inversePixelTransform_; applyTransform(inverted, topLeft); applyTransform(inverted, topRight); applyTransform(inverted, bottomRight); @@ -190,7 +189,7 @@ class CanvasLayerRenderer extends LayerRenderer { * returned, and empty array will be returned. */ getDataAtPixel(pixel, frameState, hitTolerance) { - const renderPixel = applyTransform(invertTransform(this.pixelTransform_.slice()), pixel.slice()); + const renderPixel = applyTransform(this.inversePixelTransform_, pixel.slice()); const context = this.context; let data; diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 9630ee99c5..1496fc60a0 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -22,7 +22,6 @@ import { apply as applyTransform, create as createTransform, compose as composeTransform, - invert as invertTransform, reset as resetTransform, scale as scaleTransform, translate as translateTransform, @@ -555,7 +554,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { return data; } - const renderPixel = applyTransform(invertTransform(this.overlayPixelTransform_.slice()), pixel.slice()); + const renderPixel = applyTransform(this.inverseOverlayPixelTransform_, pixel.slice()); const context = this.overlayContext_; try { From c169fec4a8cfe5a1dd4334247480096c583b6619 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 15:00:27 +0100 Subject: [PATCH 7/8] Invert and set transform in one step --- src/ol/renderer/Map.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ol/renderer/Map.js b/src/ol/renderer/Map.js index 281d1eb070..52056589c9 100644 --- a/src/ol/renderer/Map.js +++ b/src/ol/renderer/Map.js @@ -9,7 +9,7 @@ import {getWidth} from '../extent.js'; import {TRUE} from '../functions.js'; import {visibleAtResolution} from '../layer/Layer.js'; import {shared as iconImageCache} from '../style/IconImageCache.js'; -import {compose as composeTransform, invert as invertTransform, setFromArray as transformSetFromArray} from '../transform.js'; +import {compose as composeTransform, makeInverse} from '../transform.js'; /** * @abstract @@ -66,8 +66,7 @@ class MapRenderer extends Disposable { -viewState.rotation, -viewState.center[0], -viewState.center[1]); - invertTransform( - transformSetFromArray(pixelToCoordinateTransform, coordinateToPixelTransform)); + makeInverse(coordinateToPixelTransform, pixelToCoordinateTransform); } /** From 5d528dca3b630c0441c2f2c5709aaa5d36dc9bab Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Sat, 17 Nov 2018 16:28:10 +0100 Subject: [PATCH 8/8] Target, source arg order for make* transform functions --- src/ol/renderer/Map.js | 2 +- src/ol/renderer/canvas/ImageLayer.js | 2 +- src/ol/renderer/canvas/TileLayer.js | 2 +- src/ol/renderer/canvas/VectorLayer.js | 3 +-- src/ol/renderer/canvas/VectorTileLayer.js | 2 +- src/ol/transform.js | 4 ++-- test/spec/ol/transform.test.js | 4 ++-- 7 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ol/renderer/Map.js b/src/ol/renderer/Map.js index 52056589c9..dcd4f96a69 100644 --- a/src/ol/renderer/Map.js +++ b/src/ol/renderer/Map.js @@ -66,7 +66,7 @@ class MapRenderer extends Disposable { -viewState.rotation, -viewState.center[0], -viewState.center[1]); - makeInverse(coordinateToPixelTransform, pixelToCoordinateTransform); + makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform); } /** diff --git a/src/ol/renderer/canvas/ImageLayer.js b/src/ol/renderer/canvas/ImageLayer.js index 8b1d80f7a2..4c4143a361 100644 --- a/src/ol/renderer/canvas/ImageLayer.js +++ b/src/ol/renderer/canvas/ImageLayer.js @@ -100,7 +100,7 @@ class CanvasImageLayerRenderer extends CanvasLayerRenderer { rotation, -width / 2, -height / 2 ); - makeInverse(this.pixelTransform_, this.inversePixelTransform_); + makeInverse(this.inversePixelTransform_, this.pixelTransform_); const context = this.context; const canvas = context.canvas; diff --git a/src/ol/renderer/canvas/TileLayer.js b/src/ol/renderer/canvas/TileLayer.js index 09949a6605..8f389cf15b 100644 --- a/src/ol/renderer/canvas/TileLayer.js +++ b/src/ol/renderer/canvas/TileLayer.js @@ -233,7 +233,7 @@ class CanvasTileLayerRenderer extends CanvasLayerRenderer { rotation, -width / 2, -height / 2 ); - makeInverse(this.pixelTransform_, this.inversePixelTransform_); + makeInverse(this.inversePixelTransform_, this.pixelTransform_); if (canvas.width != width || canvas.height != height) { canvas.width = width; diff --git a/src/ol/renderer/canvas/VectorLayer.js b/src/ol/renderer/canvas/VectorLayer.js index 810760b228..452c8b82a6 100644 --- a/src/ol/renderer/canvas/VectorLayer.js +++ b/src/ol/renderer/canvas/VectorLayer.js @@ -7,7 +7,6 @@ import {listen, unlisten} from '../../events.js'; import EventType from '../../events/EventType.js'; import rbush from 'rbush'; import {buffer, createEmpty, containsExtent, getWidth} from '../../extent.js'; -import RenderEventType from '../../render/EventType.js'; import {labelCache} from '../../render/canvas.js'; import CanvasBuilderGroup from '../../render/canvas/BuilderGroup.js'; import InstructionsGroupExecutor from '../../render/canvas/ExecutorGroup.js'; @@ -107,7 +106,7 @@ class CanvasVectorLayerRenderer extends CanvasLayerRenderer { // set forward and inverse pixel transforms makeScale(this.pixelTransform_, 1 / pixelRatio, 1 / pixelRatio); - makeInverse(this.pixelTransform_, this.inversePixelTransform_); + makeInverse(this.inversePixelTransform_, this.pixelTransform_); // resize and clear const width = Math.round(frameState.size[0] * pixelRatio); diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 1496fc60a0..b9a8a28e0d 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -394,7 +394,7 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { // set forward and inverse pixel transforms makeScale(this.overlayPixelTransform_, 1 / pixelRatio, 1 / pixelRatio); - makeInverse(this.overlayPixelTransform_, this.inverseOverlayPixelTransform_); + makeInverse(this.inverseOverlayPixelTransform_, this.overlayPixelTransform_); // resize and clear const canvas = context.canvas; diff --git a/src/ol/transform.js b/src/ol/transform.js index 126c92129a..c7511480fb 100644 --- a/src/ol/transform.js +++ b/src/ol/transform.js @@ -222,12 +222,12 @@ export function invert(source) { /** * Invert the given transform. - * @param {!Transform} source The source transform to invert. * @param {!Transform} target Transform to be set as the inverse of * the source transform. + * @param {!Transform} source The source transform to invert. * @return {!Transform} The inverted (target) transform. */ -export function makeInverse(source, target) { +export function makeInverse(target, source) { const det = determinant(source); assert(det !== 0, 32); // Transformation matrix cannot be inverted diff --git a/test/spec/ol/transform.test.js b/test/spec/ol/transform.test.js index 4c7ea2df81..5a8308ad13 100644 --- a/test/spec/ol/transform.test.js +++ b/test/spec/ol/transform.test.js @@ -149,7 +149,7 @@ describe('ol.transform', function() { it('makes the target the inverse of the source', function() { const source = [1, 1, 1, 2, 2, 0]; const target = [1, 0, 0, 1, 0, 0]; - makeInverse(source, target); + makeInverse(target, source); expect(source).to.eql([1, 1, 1, 2, 2, 0]); expect(target).to.eql([2, -1, -1, 1, -4, 2]); }); @@ -157,7 +157,7 @@ describe('ol.transform', function() { it('returns the target', function() { const source = [1, 1, 1, 2, 2, 0]; const target = [1, 0, 0, 1, 0, 0]; - const inverted = makeInverse(source, target); + const inverted = makeInverse(target, source); expect(target).to.be(inverted); }); });