From 1cc9fdb6ec73882dee3dd13045402171ffc7c122 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Sun, 10 Jan 2021 17:46:04 +0100 Subject: [PATCH] Fix handling of VectorTile renderBuffer --- .../expected.png | Bin 0 -> 10282 bytes .../layer-vectortile-renderbuffer/main.js | 59 ++++++++++++++++++ src/ol/render/canvas/Executor.js | 9 +-- src/ol/render/canvas/ExecutorGroup.js | 8 +-- src/ol/renderer/canvas/VectorTileLayer.js | 13 ++-- 5 files changed, 70 insertions(+), 19 deletions(-) create mode 100644 rendering/cases/layer-vectortile-renderbuffer/expected.png create mode 100644 rendering/cases/layer-vectortile-renderbuffer/main.js diff --git a/rendering/cases/layer-vectortile-renderbuffer/expected.png b/rendering/cases/layer-vectortile-renderbuffer/expected.png new file mode 100644 index 0000000000000000000000000000000000000000..95fadf80ba28ae4d3841fdea38b7b650a2e16108 GIT binary patch literal 10282 zcmdUVXHZmKx8`Y}$&z!uNh!P|VB3Y8;3?fNU8k^iG zIVm6#@9y{g?l(0v_s7)K)KuMH4RzMu=bU}^TI&frPG3*!3NaHg1VLAHwABqE2nPOy zL4^3=$HJ@35&NIFp_VFCHO8_IK^%~dy2?Fd&h}h@={=`#zP%=ae5jzAPCDTs&AX3= zQaw+#`yh#KLS5;}gVOBv8*UlNGYoEnJn0Cj6v?|1amj8}{9`sQkMqd*(w)VGc|Jvi zhUM2O_uFw1b6VUce$!0XUs8s?NE_jaPrLm^cD3Ty`Nf@;oN4aEuPuQKkMX3kNAcqe zk;75j5RFD{3>~Dg&maQDFN>Q&H2wDPAc6QnXP7=s$|O#{09z4U*+4;)B(xBj_}?J# zWbB4mnXW&;9+>VTaU_?;hUX_NUbk=nqgH&$}G!XHaA+ToK)&Z{7$^8Jl1X z-9(to&1y7-`rE09mV*K*Hh0O(O%wIq-SLqAs=`#=y@#DAeglZ;dFQ^NgX{RD_+^Lw zKFP_2Zgx1<8$QjY#@w=;u+7h(QZv)SK7PD|3<#({md;c1M+~Wu*udVIiQKw%OW*GY zsbXc7X6BvfgBmdf3dXpM?;}g1G~e8;>*+|C9?kcywzro}I_uATi;t0%NNsgv{`u<{ zB?}9pDQE`wrj$b=T#US=q(nf`m$+ng+`hsh`3z;c(${~!W2M-d5!MaFa3Z3_3%iBk#F@n9 zOu9C248Eo?9nH>6#9ZrRNk7XwDM`Qb;T|LvU*daX$T4dLYDh6Trn|%6Q51~BesAU9 zY;O0Xg=j_n9@{U}k1uzH;d*#_e(YuSN92%;gtF@k&>+8me_pGoz%tIqYwPALfKL0d zz0n1cN#7{w=w!dfrVyJe|M;8l=>bZH-wc8_HaGW|FU~!_Z0`RI`t5mQzWr#!KfrVE z18r8nU7Obmp`nq{^LIDF^vt{CF;>WnCuf1b9BJ?fFg-;nROcjQ5HlCI=hCE>0R>Cq zEBEeuKiC=RMg@=K9B##ieu z4)_rsz8d(UY~W?i=XTe`X3X2}8AZqyQ9kqa)eE@W@7=o|-x@4|z~KXsS1G^R9`pDm6uD{euSxEle^Ff*}Av7g|Jc_xe(Mn zKS%v#9IaGs3QLi#I<&O3NNuu%fB5iWVqsxiRdwg5hj0I@`uf_3)1udJ+^A(8tjgJ7 z>pE9DWdz$sz@jO6TOh|f#DKCfp1`t+!K!;#YjPh`R$c8R zA8#qs&)XI8doCt?(MBOHYsimg?8)AW4vnyRG(Vk8p>FwP{sS*6^ebeK%J7h{VYzy( zaYBMgRSoNd;aDYHkkTMK*JDD+h)bxdG%?{yXHY5w9X@?gnj&phFLhiTxSYFO4ox~i z#uc=+hJy2>V|>94Oab-Z5V7YN_WhlBTGZlZYnj_YVhYAWiy-e$FFOYX;Z{y6!neKs z7#&aS^X7|sNA>e8@_SA z@O~mCNTfy18b0h`C;y?4(i|F0VIPc`oKzRNJDPz>Nu3W#K>hSjL2d0M z*>KLtw+Vd(2G%6ZU`jpfgUMKt(88wq9wRSVw75)pSpn>BR3yqRV3?EB+10rQeUvi{ zF2&FLCu}n$Xga_$GBdf91&XIHyan7Is)Z`o6hFK)*Z6bNW5l6sZk|2YxGpTEt_eca zU0ejw26RzFIM`Z`HmS6e$LFWL`V6%bTJrWQK3qkEooLME^vz%3ay*z@)dJ?+V3v`m zloB3^*I49{?B_*Q!pbU8gIT|POr@$i@pUq6cvz>^J=+JAe1V%GY-W|2+X5t-7O;$r z44VoIJ*U&rf|V0r#1*0!-i-@}E$^F^>8Qdtr>oIH=;B{sn;W;V@bdB^wC;;76X$Pz zWL&wl5hvN`%xGxjT3A@HMO$z0rW}1Wj&XbC@Tay`K;Aogn}J009*lt$KhVrFDW_Qm z`&_nubg%q;Ir+sVY)@lJNc&7IEwgfSeNl?q&R?p9RTiZP&)>p0YDmH+ySw$4Gq z|3oR~O_ivF4iA~^`DJoN0*M_jm5;BlEP}llWS<7;rJ#j376}s?!1c{7lYIECUkBB? zw!Tk&6ceWOn0k9ViOmf1zC})==H`0?Elw9%hSPk{Jb_@X{!-R*W4#;KFYqXYKdqx< zZFAl8I9U5Y*?~v&%hx(qdzDy0D1A6`Ad{|G*m?})3D``|EG+8rrdxYKI{kLDEG)&| zxIa?s0%ZYqh<(Ydde7`>RyO$E;@cb|96d$_0A5poyE~VJm8ADyP&CQ9+-T+UiO|`LoMMUMd7I=ZQ zT5$lA>c9(VIyzExEpAraoSPN9DcOq+TU?I=*Bk9WGK<5-#BadGBVM=gybycA;kdV7 zrY+DXtTO)o1rJ@En99Tqr8wLsC%42K+UatxmGL3#slo z!fhJNYzw%@e>gPE*w`+8A;as`>siu1vE(g;EG#TIc#gl5B(HE$C=d1AmS0Oy-AOE7 z_{;8T{Op{#y;MDTNOe_CM~1Vn;^vheC2Do6*X^a$`WC5QlyH?ofo*O1(o8eS-8zbo z9!*FhbsxPmT^w69B6zx%qj>M2q#EQlN-kc_OTqmRDgsLgIUsc z#L9f>OSi-M?u+U0r7hmZk9oCGTFSw>Cih$iAXxyG{}mAoD^q14X_eT&bV z;v-#a3JIh5l~yVGCuT?Jk7mLE_p0elm{-IJLekRGJp4TQOFwk6d7hm>@>ETAqN_{S zu)!+jJ13_Hr}H~zBY<($y;N~#37NQ6raG5T-dzuzM~{H#HDjlZ8fP>uE_xiuLTO+? zwm=@IxVzmC0vheHsf~rzOi7@mU5CGxlE5B!>uh1SmJE_h1f= zj)ip%&&G(d)Ew`S3i-;#j1h^MSFTO1Q>c+FN=Z6O3YnXyy?8O~mjUN|1GTlc?|W$C ze;_jRNfVsk*+I(i;eRKycv~NYWVmW?x2QMaKwk=AHD)Q16iMBPU^Re4Pz$=TptwFA z`!HA23;Mz$N~%(lxsvm>Eba)cZ>jGzx*-NlL7C)GQep>K+@Db_=Il#_r=Q0J=X022 z1#M+SglW5f!(5Z@djR~fXnl1Rbd&DbtD%dFHdyEmz&Kb%y}h~zL*}(O{Sgs<3w|Su z9LpweyXqc{Y<0MOqHTJ|;r`1JkAUExkq{(+s>R)%ZN`3mA?-VT@@i^+3p-y5IESdI zw>vDI_QsN!K?qo;1XTyv%J=WKeRe9WtkfRaZO6z&6r!vilNFk`?|BD}h~;-qls5v% zTimXeXhANY64$%TLY3`b4V2Zx0bl9EQMbE!BxuN7*cX-kV2 z-JTIMZ(V=T)ZiF72Tx_k_dP6g6T;&PG^oJExH%LSb~S-qGkX`{-r82W@4_p^sxHTsk; zC50R$-dZl(m%}1p{gsu+y$k1aZ6w2D@(G}yP5JpQ8QvvlA|R;M6dq`|vWlgTqu5-6 zm1{@pKYonY+@c~(bK!jd7h?sje*&DFj~XA`Q;KO)Rx(1Wh|*e5cj={7%1SE5+mv`! zvpb{`V5^Sy6b)D4;tnZ#;|Jm5s$aQ0=d>e%Aghpb-?Fis?f_ZY#4UF(FRJNkYpsBX zS35Q~RNtzHI|Foca-u3khxYZg0?7@sb$;IyBp1k-8VNppPYFijYOA2>Y|rZHX*J(% zrg`(_*@KjCXv+7FR{$Lg`8n>w&u`#$F89IAeBZ@{zK(~gI3NH6v$igd?e}QH)V^q# znaH2U{Mz@NVjwM>THo`yL+bTFVx`(D$tL>Iy^GQ|79w=xQp;+dy+cT{vJcF((zx$d z2~t`fUGN;o&CN|;@R{@GTBtA&Ud8!2B|XD&k-LwUqaKaJlitJrbJ>RyEOwm>Y!YHN0GlGf<}o2}VO4=y4z*s&GUcpAR4vVsn#q`k$f z*c`}6|Ml(tso)E*ZKj>}%V3^)uipy}4a-P-?sz693JwaJ0DTH#RaJ)b2|&re#4mTN zv`Jo%q|Ck&B`Ao>%|ZMQz|U4Zqv-tBL@xh$=iR2?3(Y_n^lvn88#8!MD*MWFQOln1 zC;kAma?0}H8L(JgRyhT-Bt=B5u`&0amzSG%2A`*NRI)2Pp@NTOF2&WLoQW6LWZ2e6F6acTE~!=4^q%S*v$x2C>Mar6ullrJr*w}1n=$?m#c(Y+7r?q{v*jO>F>t~cItQA)7;6H-!ABA0sL2R?qw2MX?l!Bg{OohVa> zN8cg=rD{8#?(F&E+&5w<__}j{w-hV_!57yo4X(DI6KdL)eH-nag4eXBN_CNk4bv>C zsZaEbAjso#JUDvWP>^`KGW+-VJ>FDUlcrN3yRhJzP&xGG9 zp(2jLdDw5KKt;cr!5$2m{`e8CwY*$oEIe>|dTf8@-oldd*yp3H`2?b&@LdtEV+#v; z$eB1G$ug|}j3D&$?p<$|LC`0pz13GPxHrE)K9)6#Y%9d!*URyEL$0*w-~=tqbUwcJ zUg?ySeNWR6sDCTVq~nYEk~cM0~z# z;rClS#y`_L% z&c1$lw!QsK^1%DL>dt{*W+FesBht7i7NfdViU|lptO)~;e4O|%KD+kMSYI-^OI^<& zb5?&~$y#fFzB}Lo3V(ET^q#bfOYGKWuVh%5c1p6NJe5<1pWkv^w)7H?jTTbIs)YSw zw|#0ZX?e-^SVKL(u8~efMFpYd#qe5bx*nzvD|3`59GrrQ;iTenJmh>hIMO9O*dP4) zdGm-1Ntc6!?L$2>FCMDvihp=EJ~}Gs(o@5st&5X~ZSpd)b4yDocDCdSGZDq}lZTD= zo;`oY^bWu`+#Tkx)!^#>n!^H!dZWE;;%6(IS%2yYPzP(t6+?BaSI?8Ge#8+W_J0qe z7xIomejZLAyZX>9DJr&gsu0&Qn1>uz?D8ASp6V*UK6^e7_5i~5@Hcz#V)pOV+@LLS zbuA6fk`nkW{Q1IO-dhncK@pKP+?uh$)l+gM2m!uPlMtwb-ikfC+Jth)-6<->n@S%8cXWlk}sclAzt2i>8`0%TC!9i zI{-mlU?z{HSy|9dqCd;#8Cl{0HORv#L@7`7DrVGUnt!*I{L(v5EiB~Eh;`xq&j<6Q z>GL_+2_AW5aKAS=rXL+RI_@Cv|NWEk@|qlDY;UFnD{AI-o9F|%n)G3CngmAgu@bcRl^ziRcX(pWCbN%7pKf^u&`6J=pU7OXN$(fQ)biNpO zac%!U{hNn}&Mkg!^U@bP4jtFom_3SzB2HAx^#v* z=mtZ=eBdu#i;EHKz1@};gchu;lHR6cW+HS%i1s2VZsB4<7CoO#*uo;15U3*X+$zV_ z{j%sS>F>*DL?cvRdp3qWv{&h@#LbNm$WSM15+A1N z^Kf9_zJ1$j9BoNG0#f6Zv@}8rVgoa?4}KXMoOMwA-Q1p|zba6GCidUrZIrixXE&&* z=%4p}XbEf#`XWU0O0FMZPR=R_EBueY(o#{yK^w?ufldYR2fzxbAT$xshyXfSSt-Wy z03h1{^@hCCcm(hg?kWhl1vP((#>7-y1>;_0g&E%o8(tH7`XNtdhf4RfQ6I zUQ}Eh`7b3WS2iN>ecf&jKw@dTySp{p)knVp)T`)iyjus1f{a{QfP~@PZy-{9T&xd~ zoXh4eOWnIAthl|Qs%Mkmdj!x`Z1wy1V)F8vH9@ID{Gw#9j7@r#QLeZCXF60WFgj}$(F%-eYUYmx5_%t=uv)Tg*2=cXNFD9K`;Y#xlWHH1a zhx)iE4=@<4{$p6nu+gFTk9-2;m{_y;mpb3d1tTSzxssb&<@sKhV#N{F_VxnawF^QZ zu}DZoLwD~2mFUyZM^YRHi>Dtxk6!sKDT$p7mY2uC$ZRh^&_-zlQ5zXiNFra}ehN61 z9X@+Xe5C3}s)M)LI)M35ek8 zMcn1u(4(rAH#+QE-`&$wmmDd|J52aA*d$H>qNk@Pl&vEco^B?@BeQn$5ap>_7^J~o z(-HD|JeWB15inIMqNps}J@Y|CL(em^;k?g@Go+Lxy8@=dcEnwSBP9MsX@F&~V1D4= zjF?^l#BV3EgRpnJJ z!NLE?862iu-H`2wh&V55gans#{)yDbF*`<;1+P0yVhj{_CW>zWVT6ei)?hUb9_uNf zM5Bw})8?Hcv%>ndw2QxPawf&v{IhP8o}OzgtPg-9t3iNYnBJZCq)1Y7&wFvXh-Z_9 zRpYu!!dEII2*@qY*;zIqsvnMDnA9y93dmyEJLt!hlz3S4G4h`;%8@?2$E%VqoW+x_ zy~i8Td)L>#J{4Rk9dNfB+MG_&-}z$plbav>w%3=UcY06akZAS zb6M|ijhFWm;L}sCL*Km`i?B-DBEVcLk$Bf<+lGO1>FMpM;-yW<#L%qs=Idsy0uP=j zUXq{vt=`dWZ9VN!W)*v$*b@_rSDDe{0Rh;x+$<{Glf_N&IY>_7<`Vj_bjmpiyh+nn znFFAL0Nv!1goJ+4Bv!KgWM`+}+a(kCC<106E{+v$T(2_~KX9nQ3aCP%zze+##JMdb!n;@$<+}Atw#y-ji7giW$W57%i3I?wf$`TDU?Pk?Ubl6_?#FUiyCmZkeOVAKK; z2Pnv32;io(^#tzJ2Xw}Kf9omoR`}P+$hZV~`yZjb`P?h+f$K3?4*~((nr~;OZ*BE_ z)=_#Q)ta8}>4_jU*%lLX2F&a?is5N``gZEa77JE}uKt}zAUGSSKVVpMON%Ym$$IXyjSe88VE11Ly{zl|EaSEWp^sMp4~3x-?e5tYDMzfS#Y6uD6HEvY2+V zJ?G=g^tqM~$Y>BXHDICbtm(2b@8_+ie*eY*?-+OsRD~p6{rzyPF&u&QoT9uf@Nn9) z@{%K54-1?2UzjDmJMcLn1Jkv6VWYIqUQo`g!?tEys2yt=_@CVZs@d3BpE}@YITn3* zLM58G721*NCu_S>;36=QL1a3xiT(EtYU&=%&U_N^je)tCGZjln!^dxLZ8F^! zQd(F+qBA@k%i-*6Ub(2|0PDMH0IFV5-5#x%0M{5D#f~(Qc2j*l8eRCr zg82Hw>wui4wzyE^4i6bl%_f4V>W(8Ow87SZ3pj|9EJ$-4^h7qpXEGJdGBVn~i$)im z#nr-?B4FRQw^2FSBf#hrxWRPR(Z(`JL)=(|dS*lm{A?<{9GNg+M6V&b&3U3?FzSy) z*>=~myc_dpTs2&@2)w+#DcRV@fS37FJbNFh0msG{7xOe?P|v!4L|*e>_)n5WDW`}| z1O97%>uUn`If<&v-bSfoO^v03Ekx#1&uQ+GlGyoXO09Wh#I}InY6j3r&B5GK65;mu z?_*!Ka~8f%zUF5Ga6L2KbNutOXA{6+M%-sa8?f~J%`G?|_TnQb z;`UP3*AatDH0fXB-zuFGFQ0Ut?Zj?zf8QeF~I`CL{wfqj; zR!vO}_4GxY2n=?t#4KIM8e%Id(aQ|Tx9tDxw+nwon$f6<1A zhoh1)VtST;0R1^`F2s42n7GI*r@5##k8lpPR>$+_=Gwb^hD9piFD`$KW{$|!(@9;Ce@+YJ8ZF?pQ3K=Kvej>C!OKg(`4KBP z7Eo2z!q|E3+F%?t|BhTl5*u^y(gPTzY-B{8H{U`H?B?Xs*W4(g=dEA$^z5v4ugHne zu^0*bxET*ZFBV66yDFbPed_Ti;TlDQ3$-ylt?ZmX4oIfAqC%=b_GmuqrzbgqzaETM zLI&XPsU033B0VpIn>P-Te>zTUI3=ELYbO{_qZ2?rcL~#Bo^fksD!4skV_wxHStOt# zhFd-P^Po672BU09^)))Wj@4zpii~s-lo`>(-Q22yvgMgr* z%FGMN<9F|w?n^L!>h0MBexhOKwU}0Y=cb@hGhyfEC)BTg9~EjAsesOhZFayf7#bg6 zoy~S$ujQl`3DuAQI_aA?s=%)VMr2`a3H)KPAutFzfW=pPagiF|Pk4Bw8Ty*Pk83ie zgBI)^;7tKP%D&4c)T~--bxq(KAKzYyUd%(+8&9dJY7|ATxG*vfef$^+x@$rR=1|Uk}G!vj3)2 WJrp@{TmXmvARP@o^(s}H@c#h4T_@)N literal 0 HcmV?d00001 diff --git a/rendering/cases/layer-vectortile-renderbuffer/main.js b/rendering/cases/layer-vectortile-renderbuffer/main.js new file mode 100644 index 0000000000..439c671a65 --- /dev/null +++ b/rendering/cases/layer-vectortile-renderbuffer/main.js @@ -0,0 +1,59 @@ +import Feature from '../../../src/ol/Feature.js'; +import Map from '../../../src/ol/Map.js'; +import Point from '../../../src/ol/geom/Point.js'; +import VectorTileLayer from '../../../src/ol/layer/VectorTile.js'; +import VectorTileSource from '../../../src/ol/source/VectorTile.js'; +import View from '../../../src/ol/View.js'; +import {Circle, Fill, Stroke, Style} from '../../../src/ol/style.js'; + +const offset = 1380000; +const points = [ + [-offset, -offset], + [-offset, offset], + [offset, offset], + [offset, -offset], +]; + +const vectorTileSource = new VectorTileSource({ + tileUrlFunction: (tileCoord) => tileCoord, + tileLoadFunction(tile, tileCoord) { + const features = points.map( + (corner) => + new Feature({ + geometry: new Point(corner), + tileCoord, + }) + ); + tile.setFeatures(features); + }, +}); + +const vectorTileLayer = new VectorTileLayer({ + source: vectorTileSource, + style: new Style({ + image: new Circle({ + radius: 50, + fill: new Fill({ + color: 'rgba(255, 0, 0, 0.5)', + }), + stroke: new Stroke({ + width: 1, + color: 'black', + }), + }), + }), +}); + +new Map({ + target: 'map', + layers: [vectorTileLayer], + view: new View({ + center: [0, 0], + zoom: 2, + multiWorld: true, + }), +}); + +render({ + message: 'Vector tile layer renders tiles from renderBuffer', +}); diff --git a/src/ol/render/canvas/Executor.js b/src/ol/render/canvas/Executor.js index 058961edaf..38722993c0 100644 --- a/src/ol/render/canvas/Executor.js +++ b/src/ol/render/canvas/Executor.js @@ -110,9 +110,8 @@ class Executor { * @param {number} pixelRatio Pixel ratio. * @param {boolean} overlaps The replay can have overlapping geometries. * @param {import("../canvas.js").SerializableInstructions} instructions The serializable instructions - * @param {import("../../size.js").Size} renderBuffer Render buffer (width/height) in pixels. */ - constructor(resolution, pixelRatio, overlaps, instructions, renderBuffer) { + constructor(resolution, pixelRatio, overlaps, instructions) { /** * @protected * @type {boolean} @@ -156,12 +155,6 @@ class Executor { */ this.coordinateCache_ = {}; - /** - * @private - * @type {import("../../size.js").Size} - */ - this.renderBuffer_ = renderBuffer; - /** * @private * @type {!import("../../transform.js").Transform} diff --git a/src/ol/render/canvas/ExecutorGroup.js b/src/ol/render/canvas/ExecutorGroup.js index 12f5c7ca1e..540dc828d4 100644 --- a/src/ol/render/canvas/ExecutorGroup.js +++ b/src/ol/render/canvas/ExecutorGroup.js @@ -30,8 +30,8 @@ const ORDER = [ class ExecutorGroup { /** * @param {import("../../extent.js").Extent} maxExtent Max extent for clipping. When a - * `maxExtent` was set on the Buillder for this executor group, the same `maxExtent` - * should be set here, unless the target context does not exceet that extent (which + * `maxExtent` was set on the Builder for this executor group, the same `maxExtent` + * should be set here, unless the target context does not exceed that extent (which * can be the case when rendering to tiles). * @param {number} resolution Resolution. * @param {number} pixelRatio Pixel ratio. @@ -126,15 +126,13 @@ class ExecutorGroup { this.executorsByZIndex_[zIndex] = executors; } const instructionByZindex = allInstructions[zIndex]; - const renderBuffer = [this.renderBuffer_ || 0, this.renderBuffer_ || 0]; for (const builderType in instructionByZindex) { const instructions = instructionByZindex[builderType]; executors[builderType] = new Executor( this.resolution_, this.pixelRatio_, this.overlaps_, - instructions, - renderBuffer + instructions ); } } diff --git a/src/ol/renderer/canvas/VectorTileLayer.js b/src/ol/renderer/canvas/VectorTileLayer.js index 91cbf57935..39b6676075 100644 --- a/src/ol/renderer/canvas/VectorTileLayer.js +++ b/src/ol/renderer/canvas/VectorTileLayer.js @@ -282,17 +282,18 @@ class CanvasVectorTileLayerRenderer extends CanvasTileLayerRenderer { sourceTileCoord ); const sharedExtent = getIntersection(tileExtent, sourceTileExtent); + const builderExtent = buffer( + sharedExtent, + layer.getRenderBuffer() * resolution, + this.tmpExtent + ); const bufferedExtent = equals(sourceTileExtent, sharedExtent) ? null - : buffer( - sharedExtent, - layer.getRenderBuffer() * resolution, - this.tmpExtent - ); + : builderExtent; builderState.dirty = false; const builderGroup = new CanvasBuilderGroup( 0, - sharedExtent, + builderExtent, resolution, pixelRatio );