From 39fc6d78169d426019c8d3f0f882fdfc0fc34268 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Wed, 9 Sep 2020 11:02:10 +0200 Subject: [PATCH] Avoid unnecessary transform in MVT format When using ol.render.Feature there was a mandatory geometry transform. With this change it is now easy to read features directly in the native tile projection. Since there is no needed transform, there is no need either to define an extent and a world extent, for that use-case. --- src/ol/format/MVT.js | 2 +- src/ol/render/Feature.js | 52 ++++++++++++++++----------------- test/spec/ol/format/mvt.test.js | 9 ++++++ 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/ol/format/MVT.js b/src/ol/format/MVT.js index 08a77e5f97..9052c919cf 100644 --- a/src/ol/format/MVT.js +++ b/src/ol/format/MVT.js @@ -194,7 +194,7 @@ class MVT extends FeatureFormat { values, id ); - feature.transform(options.dataProjection, options.featureProjection); + feature.transform(options.dataProjection); } else { let geom; if (geometryType == GeometryType.POLYGON) { diff --git a/src/ol/render/Feature.js b/src/ol/render/Feature.js index c6eec77379..c0193f099a 100644 --- a/src/ol/render/Feature.js +++ b/src/ol/render/Feature.js @@ -276,34 +276,34 @@ class RenderFeature { /** * Transform geometry coordinates from tile pixel space to projected. - * The SRS of the source and destination are expected to be the same. * - * @param {import("../proj.js").ProjectionLike} source The current projection - * @param {import("../proj.js").ProjectionLike} destination The desired projection. + * @param {import("../proj.js").ProjectionLike} projection The data projection */ - transform(source, destination) { - source = getProjection(source); - const pixelExtent = source.getExtent(); - const projectedExtent = source.getWorldExtent(); - const scale = getHeight(projectedExtent) / getHeight(pixelExtent); - composeTransform( - tmpTransform, - projectedExtent[0], - projectedExtent[3], - scale, - -scale, - 0, - 0, - 0 - ); - transform2D( - this.flatCoordinates_, - 0, - this.flatCoordinates_.length, - 2, - tmpTransform, - this.flatCoordinates_ - ); + transform(projection) { + projection = getProjection(projection); + const pixelExtent = projection.getExtent(); + const projectedExtent = projection.getWorldExtent(); + if (pixelExtent && projectedExtent) { + const scale = getHeight(projectedExtent) / getHeight(pixelExtent); + composeTransform( + tmpTransform, + projectedExtent[0], + projectedExtent[3], + scale, + -scale, + 0, + 0, + 0 + ); + transform2D( + this.flatCoordinates_, + 0, + this.flatCoordinates_.length, + 2, + tmpTransform, + this.flatCoordinates_ + ); + } } /** * @return {Array|Array>} Ends or endss. diff --git a/test/spec/ol/format/mvt.test.js b/test/spec/ol/format/mvt.test.js index 660ed1b579..5951727fcd 100644 --- a/test/spec/ol/format/mvt.test.js +++ b/test/spec/ol/format/mvt.test.js @@ -65,6 +65,15 @@ where('ArrayBuffer.isView').describe('ol.format.MVT', function () { expect(geometry.getCoordinates()[1][0]).to.eql([4160, 3489]); }); + it('avoids unnecessary reprojections of the ol.render.Feature', function () { + const format = new MVT({ + layers: ['poi_label'], + }); + const geometry = format.readFeatures(data)[0].getGeometry(); + expect(geometry.getType()).to.be('Point'); + expect(geometry.getFlatCoordinates()).to.eql([-1210, 2681]); + }); + it('parses id property', function () { // ol.Feature let format = new MVT({