From 6902791dc5c1e82c2379ad19e21230b9fc6ea348 Mon Sep 17 00:00:00 2001 From: Ian Schneider Date: Wed, 15 Jun 2016 11:12:07 -0600 Subject: [PATCH 1/4] layer extent example changes for testing - add draw extent tool - rotation control --- examples/layer-extent.html | 1 + examples/layer-extent.js | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/examples/layer-extent.html b/examples/layer-extent.html index 52ec7210ef..f844b39fb1 100644 --- a/examples/layer-extent.html +++ b/examples/layer-extent.html @@ -14,3 +14,4 @@ tags: "extent, tilejson" + diff --git a/examples/layer-extent.js b/examples/layer-extent.js index 474469d4da..1772d5db2b 100644 --- a/examples/layer-extent.js +++ b/examples/layer-extent.js @@ -3,6 +3,8 @@ goog.require('ol.View'); goog.require('ol.layer.Tile'); goog.require('ol.proj'); goog.require('ol.source.TileJSON'); +goog.require('ol.interaction.Draw'); +goog.require('ol.interaction.DragRotateAndZoom'); function transform(extent) { return ol.proj.transformExtent(extent, 'EPSG:4326', 'EPSG:3857'); @@ -43,6 +45,37 @@ var map = new ol.Map({ }) }); +function box(coordinates, geometry) { + if (!geometry) { + geometry = new ol.geom.Polygon(null); + } + var start = coordinates[0]; + var end = coordinates[1]; + + geometry.setCoordinates([ + [start, [start[0], end[1]], end, [end[0], start[1]], start] + ]); + return geometry; +} + + +var draw = new ol.interaction.Draw({ + type: /** @type {ol.geom.GeometryType} */ ('LineString'), + geometryFunction: box, + maxPoints: 2 +}); + +draw.on('drawend', function(ev) { + var extent = ev.feature.getGeometry().getExtent(); + overlay.setExtent(extent); +}); + +map.addInteraction(new ol.interaction.DragRotateAndZoom()); + +document.getElementById('draw').onclick = function() { + map.addInteraction(draw); +}; + for (var key in extents) { document.getElementById(key).onclick = function(event) { overlay.setExtent(extents[event.target.id]); From 44a4fbdda2e87c2ee3018b212bc07ef0079e747c Mon Sep 17 00:00:00 2001 From: Ian Schneider Date: Wed, 15 Jun 2016 11:17:34 -0600 Subject: [PATCH 2/4] respect layer.extent in canvas tilelayer renderer --- .../canvas/canvastilelayerrenderer.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index feaed6bffb..1d7f2c812b 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -276,6 +276,41 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram tilesToDraw.reverse(); pixelExtents = []; } + + var extent = layerState.extent; + var clipped = extent !== undefined; + if (clipped) { + goog.asserts.assert(extent !== undefined, + 'layerState extent is defined'); + var topLeft = ol.extent.getTopLeft(extent); + var topRight = ol.extent.getTopRight(extent); + var bottomRight = ol.extent.getBottomRight(extent); + var bottomLeft = ol.extent.getBottomLeft(extent); + + ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, + topLeft, topLeft); + ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, + topRight, topRight); + ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, + bottomRight, bottomRight); + ol.vec.Mat4.multVec2(frameState.coordinateToPixelMatrix, + bottomLeft, bottomLeft); + + var ox = drawOffsetX || 0; + var oy = drawOffsetY || 0; + renderContext.save(); + var cx = (renderContext.canvas.width * pixelRatio) / 2; + var cy = (renderContext.canvas.height * pixelRatio) / 2; + ol.render.canvas.rotateAtOffset(renderContext, -rotation, cx, cy); + renderContext.beginPath(); + renderContext.moveTo(topLeft[0] * pixelRatio + ox, topLeft[1] * pixelRatio + oy); + renderContext.lineTo(topRight[0] * pixelRatio + ox, topRight[1] * pixelRatio + oy); + renderContext.lineTo(bottomRight[0] * pixelRatio + ox, bottomRight[1] * pixelRatio + oy); + renderContext.lineTo(bottomLeft[0] * pixelRatio + ox, bottomLeft[1] * pixelRatio + oy); + renderContext.clip(); + ol.render.canvas.rotateAtOffset(renderContext, rotation, cx, cy); + } + for (var i = 0, ii = tilesToDraw.length; i < ii; ++i) { var tile = tilesToDraw[i]; var tileCoord = tile.getTileCoord(); @@ -324,6 +359,10 @@ ol.renderer.canvas.TileLayer.prototype.renderTileImages = function(context, fram } } + if (clipped) { + renderContext.restore(); + } + if (hasRenderListeners) { var dX = drawOffsetX - offsetX / drawScale + offsetX; var dY = drawOffsetY - offsetY / drawScale + offsetY; From 265068e7826a50514185c0a9cef487e445428d2a Mon Sep 17 00:00:00 2001 From: Ian Schneider Date: Wed, 15 Jun 2016 21:13:49 -0600 Subject: [PATCH 3/4] example - layer-extent uses country bboxes --- examples/layer-extent.html | 14 ++++++------- examples/layer-extent.js | 41 +++++--------------------------------- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/examples/layer-extent.html b/examples/layer-extent.html index f844b39fb1..74169f8cd9 100644 --- a/examples/layer-extent.html +++ b/examples/layer-extent.html @@ -4,14 +4,12 @@ title: Limited Layer Extent shortdesc: Restricting layer rendering to a limited extent. docs: > This example uses the layer.setExtent() method to - modify the extent of the overlay layer. Use the controls below - to limit rendering based on an extent. + modify the extent of the overlay layer. Use the controls above + to limit rendering based on an extent (approximate country bounds). tags: "extent, tilejson" ---
- - - - - - + + + + diff --git a/examples/layer-extent.js b/examples/layer-extent.js index 1772d5db2b..4e46ca1daf 100644 --- a/examples/layer-extent.js +++ b/examples/layer-extent.js @@ -3,7 +3,6 @@ goog.require('ol.View'); goog.require('ol.layer.Tile'); goog.require('ol.proj'); goog.require('ol.source.TileJSON'); -goog.require('ol.interaction.Draw'); goog.require('ol.interaction.DragRotateAndZoom'); function transform(extent) { @@ -11,11 +10,10 @@ function transform(extent) { } var extents = { - northwest: transform([-180, 0, 0, 85]), - northeast: transform([0, 0, 180, 85]), - southeast: transform([0, -85, 180, 0]), - southwest: transform([-180, -85, 0, 0]), - world: transform([-180, -85, 180, 85]) + India: transform([68.17665, 7.96553, 97.40256, 35.49401]), + Argentina: transform([-73.41544, -55.25, -53.62835, -21.83231]), + Nigeria: transform([2.6917, 4.24059, 14.57718, 13.86592]), + Sweden: transform([11.02737, 55.36174, 23.90338, 69.10625]) }; var base = new ol.layer.Tile({ @@ -27,7 +25,7 @@ var base = new ol.layer.Tile({ }); var overlay = new ol.layer.Tile({ - extent: extents.northwest, + extent: extents.India, source: new ol.source.TileJSON({ url: 'http://api.tiles.mapbox.com/v3/' + 'mapbox.world-glass.json', @@ -45,37 +43,8 @@ var map = new ol.Map({ }) }); -function box(coordinates, geometry) { - if (!geometry) { - geometry = new ol.geom.Polygon(null); - } - var start = coordinates[0]; - var end = coordinates[1]; - - geometry.setCoordinates([ - [start, [start[0], end[1]], end, [end[0], start[1]], start] - ]); - return geometry; -} - - -var draw = new ol.interaction.Draw({ - type: /** @type {ol.geom.GeometryType} */ ('LineString'), - geometryFunction: box, - maxPoints: 2 -}); - -draw.on('drawend', function(ev) { - var extent = ev.feature.getGeometry().getExtent(); - overlay.setExtent(extent); -}); - map.addInteraction(new ol.interaction.DragRotateAndZoom()); -document.getElementById('draw').onclick = function() { - map.addInteraction(draw); -}; - for (var key in extents) { document.getElementById(key).onclick = function(event) { overlay.setExtent(extents[event.target.id]); From 9d5232d9af9813e63dce7519ad33eae506de68dd Mon Sep 17 00:00:00 2001 From: Ian Schneider Date: Wed, 15 Jun 2016 21:14:37 -0600 Subject: [PATCH 4/4] canvas tests for tile rendering with layer.extent --- .../2-layers-canvas-extent-rotate.png | Bin 0 -> 2394 bytes .../layer/expected/2-layers-canvas-extent.png | Bin 0 -> 2429 bytes test_rendering/spec/ol/layer/tile.test.js | 28 ++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate.png create mode 100644 test_rendering/spec/ol/layer/expected/2-layers-canvas-extent.png diff --git a/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate.png b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent-rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..806e331357876a9e47da39702683113417682281 GIT binary patch literal 2394 zcmV-g38nUlP)O|<<54;TJuobRR`&|bW%YCFg0c|V@_d5;sErr}#* zq6Usuz>@j*6aV)Ou3@aa9K^Q*2utRJU`Y_Aw+)1qHE`udWURd5T16F{G<8k#!EvGn z-Z0P~Ts}MyRt{cXRKW?sOUn)ae_B}!kneOELtql{EaVJBYaLewQw^YMD}1nB2TUGI4f)5ME`G;exc`sbXoN--Y{Yy9t=nb zV%m$#SZ2l~ZD|y^awA&L?Rswq$h=6fL<4uYoHEx+)yaryeqBt1cn~0Ly)jdekq7II zsvd@hKGiAYhM<#_ov73M{TCBZWs0mqS8G^6Xm=1&|Ows#(})7t|= zE31JnhzxHSw~bAj03zMq9}fFV0sK#Zu=SuJPT!L>u&at7G?>HSj6_iE6nXysNn1+=*cYzU&;zk3bbj0eaII)=kOQUwB8ckfvv zp@g203~L!jz>@j$VrlBI2C|HfEN38BXdufOAl7VSoC_rKcp$xFo?kJkEwq597fFn1 zW9z5LmCe{S)9&1XwZfE{GYoC4n*@Jd(XueUS`J_|>Oqj(I5=)@M!&IHVbfZfyf13E z5e?|MKe(K`iMH#ZB-tpvmchEr%&f6KkYF=+9!JFhjIQ`Laqn}A#`B#Wyt}=P=Q}&# zt2|7*14%nWO?6PHHnGp>NYfhrbf`d(+cQjdHz0zxu%Sh%Bm^D~G|^;=@umvpLV|K3 zfprA~fe%0W2wPiQk$w2%PmpE^vYdfbfuQ)Rg>K)2+x1|3=U`n1!|U!nfGjB9 zxoWlCh}efW3{;#tM7I_#W;kcqqZ-(w8hG+_I|k(G_BIUX47_0=NfAh=7I?#m-k~@q zSeMxx$V@tg^eXr%!@FgOZVkL!2Je>fPx~c!w+y4N!WrDMiXgXXJ-#=RXf$~WV$X9_jT8K4CVNs2(UEHILV zKkOdjr#qkG>ATzb;MvFcoT9;L8umE@RJ8`yWguGCEf`%{2xNHO1@D&E2ND)z1)%fdcqAWdsXGXzPBAj{}TQY01?s-2J3h~k*YS4`}cRa82q zmGzT|A`wcAW*y{GUJ0V@de~=l2yz=~T0@c|C@QnHCbdqzVN5 zi3PXoMd_woNRT`c+1Fo!7Mp7;fd~j&Z-95p=)PI6^QH=Z8l@QmPHII(JQ)eYIYWlg zk!5u3Q4Q2oC$`4HaWjhM?vY<#%7p}~o!_9?gSnb_%WKmgEm)uh3;n?*(u~hQoaXm~ ze<-iPX&Q2(iZm->_sCDZn(81;YcZK|aNLBXogvHl=Ts%h#=&tDl}>51VlP?swIdj+>yxCiVl5j<5Wbdr|N^_Vn*x{repGiWx;U%@7o- zetKmBh1=`(kgu4atEYDaqG>St>e?Ve%P=}l92!%oB4RG+4IrIA* zYhaIR_>rU<$TB+It~aBKTYU|w0zqET;ax6228sa@EepFxzK8h}U$FJA&!JpMX!SLW zuLcoy{^ctQA3XaQzfT`xIP7CI>LJ7Ek*7loqZFo5meFH#MBDX{DiC!0UUZ5Qo?Q*E zyC|N0iJYh+!{{hUtJ6NgX&Pw3iXN6c5mYRL z8uhSyM3834%)+^{2|;cnNf8`YTXSi2moZ^DXK=e-Ox}-1Jt!9vjK1nSk=8(qO_+8E zrrkkJb&xBYVC$zSzG{IMEFVaQ(Pu`-NlVijawT8vCDSErZEfMn(`~#c+)^hk+)D4m zYRj*s`tm&A=Zpx*vgg{a-+1$aj^e8pWZi|VyAd$Gb&dpY7;_6VG^4L#_lO`{t^3{k zZwfy9^`G&pKjx5QjmVSviir%PBUdt_Cb=pd!aBPP(JTU;$Z`hwlf{!;rBm`ZD2h>` zPkMhEbeQLKA+u;2Q#8{+B)6^(zJ$>WP@1eFzpV!%N`P|KyXqEId=97(JD(b z1kS*mq4w?@8+joRnbkUszIx{)((p(qUoml5Z6V7U%Yl?68@t@|GcaQ_jP0GH+xO5PT&{iU9$HOxVky25NUm%~a$*w;&tz}L1CUEOqSH;+TjZ>T zKtg%FiaOV^Nu9OoL(L{OdG3{H_5DFASN7@i;JAsdw;qeEvi%Lj-(4&-p%xO#nF{4h zoqG& ztu?2wV@ZlcHFiC^SP8`K`p2cAyb1N!^mCyA%`iH~R|9lCe>yeo&TVRiviUwIeK+F) zc8^FjaAi4vQ`tEM?{+=Vf`7WgR8OI|7N4@~t@D|WI-!M=BrRC@FM@{69fcf++5i9m M07*qoM6N<$f>ly%1^@s6 literal 0 HcmV?d00001 diff --git a/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent.png b/test_rendering/spec/ol/layer/expected/2-layers-canvas-extent.png new file mode 100644 index 0000000000000000000000000000000000000000..2ec76c289f61b273b1c4e21114a9b0ff1b388874 GIT binary patch literal 2429 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 literal 0 HcmV?d00001 diff --git a/test_rendering/spec/ol/layer/tile.test.js b/test_rendering/spec/ol/layer/tile.test.js index de14eaac10..25eb53b874 100644 --- a/test_rendering/spec/ol/layer/tile.test.js +++ b/test_rendering/spec/ol/layer/tile.test.js @@ -29,7 +29,7 @@ describe('ol.rendering.layer.Tile', function() { } }; - sources.forEach(function(source) { + sources.forEach(function(source, i) { source.on('tileloadstart', function(event) { tilesLoading++; }); @@ -44,7 +44,7 @@ describe('ol.rendering.layer.Tile', function() { var options = { source: source }; - ol.object.assign(options, layerOptions); + ol.object.assign(options, layerOptions[i] || layerOptions); map.addLayer(new ol.layer.Tile(options)); }); } @@ -112,6 +112,30 @@ describe('ol.rendering.layer.Tile', function() { IMAGE_TOLERANCE, done); }); }); + + function centerExtent(map) { + var c = map.getView().calculateExtent(map.getSize()); + var qw = ol.extent.getSize(c)[0] / 4; + var qh = ol.extent.getSize(c)[1] / 4; + return [c[0] + qw, c[1] + qh, c[2] - qw, c[3] - qh]; + } + + it('tests canvas layer extent clipping', function(done) { + map = createMap('canvas'); + waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() { + expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent.png', + IMAGE_TOLERANCE, done); + }); + }); + + it('tests canvas layer extent clipping with rotation', function(done) { + map = createMap('canvas'); + map.getView().setRotation(Math.PI / 2); + waitForTiles([source1, source2], [{}, {extent: centerExtent(map)}], function() { + expectResemble(map, 'spec/ol/layer/expected/2-layers-canvas-extent-rotate.png', + IMAGE_TOLERANCE, done); + }); + }); }); describe('tile layer with opacity', function() {