From ee5553debb3f13730c986a0b8662cffa412863c2 Mon Sep 17 00:00:00 2001
From: mike-000 <49240900+mike-000@users.noreply.github.com>
Date: Sun, 30 May 2021 19:06:36 +0100
Subject: [PATCH 1/7] Rework TileDebug to fix reprojection issue and allow {-y}
Add setImage method to ol/ImageTile
---
src/ol/ImageTile.js | 16 +++++
src/ol/source/TileDebug.js | 130 +++++++------------------------------
2 files changed, 40 insertions(+), 106 deletions(-)
diff --git a/src/ol/ImageTile.js b/src/ol/ImageTile.js
index f6367490ac..741982fac3 100644
--- a/src/ol/ImageTile.js
+++ b/src/ol/ImageTile.js
@@ -72,6 +72,22 @@ class ImageTile extends Tile {
return this.image_;
}
+ /**
+ * Sets an HTML image element for this tile (may be a Canvas or preloaded Image).
+ * @param {HTMLCanvasElement|HTMLImageElement} element Element.
+ * @api
+ */
+ setImage(element) {
+ // asynchronous to accomodate reprojection listeners
+ const tile = this;
+ setTimeout(function () {
+ tile.image_ = element;
+ tile.state = TileState.LOADED;
+ tile.unlistenImage_();
+ tile.changed();
+ }, 0);
+ }
+
/**
* Tracks loading or read errors.
*
diff --git a/src/ol/source/TileDebug.js b/src/ol/source/TileDebug.js
index 36353da531..7f14bcf9a3 100644
--- a/src/ol/source/TileDebug.js
+++ b/src/ol/source/TileDebug.js
@@ -2,82 +2,10 @@
* @module ol/source/TileDebug
*/
-import Tile from '../Tile.js';
-import TileState from '../TileState.js';
import XYZ from './XYZ.js';
import {createCanvasContext2D} from '../dom.js';
-import {getKeyZXY} from '../tilecoord.js';
import {toSize} from '../size.js';
-class LabeledTile extends Tile {
- /**
- * @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
- * @param {import("../size.js").Size} tileSize Tile size.
- * @param {string} text Text.
- */
- constructor(tileCoord, tileSize, text) {
- super(tileCoord, TileState.LOADED);
-
- /**
- * @private
- * @type {import("../size.js").Size}
- */
- this.tileSize_ = tileSize;
-
- /**
- * @private
- * @type {string}
- */
- this.text_ = text;
-
- /**
- * @private
- * @type {HTMLCanvasElement}
- */
- this.canvas_ = null;
- }
-
- /**
- * Get the image element for this tile.
- * @return {HTMLCanvasElement} Image.
- */
- getImage() {
- if (this.canvas_) {
- return this.canvas_;
- } else {
- const tileSize = this.tileSize_;
- const context = createCanvasContext2D(tileSize[0], tileSize[1]);
-
- context.strokeStyle = 'grey';
- context.strokeRect(0.5, 0.5, tileSize[0] + 0.5, tileSize[1] + 0.5);
-
- context.fillStyle = 'grey';
- context.strokeStyle = 'white';
- context.textAlign = 'center';
- context.textBaseline = 'middle';
- context.font = '24px sans-serif';
- context.lineWidth = 4;
- context.strokeText(
- this.text_,
- tileSize[0] / 2,
- tileSize[1] / 2,
- tileSize[0]
- );
- context.fillText(
- this.text_,
- tileSize[0] / 2,
- tileSize[1] / 2,
- tileSize[0]
- );
-
- this.canvas_ = context.canvas;
- return context.canvas;
- }
- }
-
- load() {}
-}
-
/**
* @typedef {Object} Options
* @property {import("../proj.js").ProjectionLike} [projection='EPSG:3857'] Optional projection.
@@ -88,6 +16,8 @@ class LabeledTile extends Tile {
* the view resolution does not match any resolution of the tile source. If 0, the nearest
* resolution will be used. If 1, the nearest lower resolution will be used. If -1, the
* nearest higher resolution will be used.
+ * @property {string} [template='z:{z} x:{x} y:{y}'] Template for labeling the tiles.
+ * Should include `{x}`, `{y}` or `{-y}`, and `{z}` placeholders.
*/
/**
@@ -95,8 +25,6 @@ class LabeledTile extends Tile {
* A pseudo tile source, which does not fetch tiles from a server, but renders
* a grid outline for the tile grid/projection along with the coordinates for
* each tile. See examples/canvas-tiles for an example.
- *
- * Uses Canvas context2d, so requires Canvas support.
* @api
*/
class TileDebug extends XYZ {
@@ -115,39 +43,29 @@ class TileDebug extends XYZ {
tileGrid: options.tileGrid,
wrapX: options.wrapX !== undefined ? options.wrapX : true,
zDirection: options.zDirection,
- });
- }
+ url: options.template || 'z:{z} x:{x} y:{y}',
+ tileLoadFunction: (tile, text) => {
+ const z = tile.getTileCoord()[0];
+ const tileSize = toSize(this.tileGrid.getTileSize(z));
+ const context = createCanvasContext2D(tileSize[0], tileSize[1]);
- /**
- * @param {number} z Tile coordinate z.
- * @param {number} x Tile coordinate x.
- * @param {number} y Tile coordinate y.
- * @return {!LabeledTile} Tile.
- */
- getTile(z, x, y) {
- const tileCoordKey = getKeyZXY(z, x, y);
- if (this.tileCache.containsKey(tileCoordKey)) {
- return /** @type {!LabeledTile} */ (this.tileCache.get(tileCoordKey));
- } else {
- const tileSize = toSize(this.tileGrid.getTileSize(z));
- const tileCoord = [z, x, y];
- const textTileCoord = this.getTileCoordForTileUrlFunction(tileCoord);
- let text;
- if (textTileCoord) {
- text =
- 'z:' +
- textTileCoord[0] +
- ' x:' +
- textTileCoord[1] +
- ' y:' +
- textTileCoord[2];
- } else {
- text = 'none';
- }
- const tile = new LabeledTile(tileCoord, tileSize, text);
- this.tileCache.set(tileCoordKey, tile);
- return tile;
- }
+ context.strokeStyle = 'grey';
+ context.strokeRect(0.5, 0.5, tileSize[0] + 0.5, tileSize[1] + 0.5);
+
+ context.fillStyle = 'grey';
+ context.strokeStyle = 'white';
+ context.textAlign = 'center';
+ context.textBaseline = 'middle';
+ context.font = '24px sans-serif';
+ context.lineWidth = 4;
+ context.strokeText(text, tileSize[0] / 2, tileSize[1] / 2, tileSize[0]);
+ context.fillText(text, tileSize[0] / 2, tileSize[1] / 2, tileSize[0]);
+
+ /** @type {import("../ImageTile.js").default} */ (tile).setImage(
+ context.canvas
+ );
+ },
+ });
}
}
From 6304b56501290a3c63a0448040ccb7f6ed3fb25b Mon Sep 17 00:00:00 2001
From: mike-000 <49240900+mike-000@users.noreply.github.com>
Date: Sat, 19 Jun 2021 11:55:51 +0100
Subject: [PATCH 2/7] New example
---
examples/canvas-tiles-tms.html | 14 ++++++++
examples/canvas-tiles-tms.js | 61 ++++++++++++++++++++++++++++++++++
2 files changed, 75 insertions(+)
create mode 100644 examples/canvas-tiles-tms.html
create mode 100644 examples/canvas-tiles-tms.js
diff --git a/examples/canvas-tiles-tms.html b/examples/canvas-tiles-tms.html
new file mode 100644
index 0000000000..28fc084ab7
--- /dev/null
+++ b/examples/canvas-tiles-tms.html
@@ -0,0 +1,14 @@
+---
+layout: example.html
+title: Custom Canvas Tiles
+shortdesc: Renders tiles with TMS coordinates for debugging.
+docs: >
+ The black grid tiles are generated on the client with an HTML5 canvas.
+ The displayed TMS tile coordinates are produced using a custom template
+ for TMS, the vector tile source's 512 pixel tile grid and the
+ zDirection setting for vector tiles.
+ Notice how the country polygons can be split between tiles and vector
+ labels may appear in each tile.
+tags: "layers, vector tiles, tms, canvas"
+---
+
@Q&y2V&|$S$vzl#mX!i&jv#D zKc+127u%md2d{kZi-^E>Df~`K(oXZvIzVRbf&i*47*7riP&Cp-DOU_FRcYW55slvQ zp+!K3Arl=Q&lOqD)%Qs>cPW#lC@V9VNtJ4Idp**zva;%Sc_e@$FwfriE~`9qdT0pp z>*(v9h;Cw!cl!mYK@)Mtb=D5&hzU)j^YBEYiW|TufVEW-~B_k(C3|7e5nUzvL zJHN9NPmZ%Z72#Wqxf{rFwLu=1i!AsaKR2fo8XCIV>-W{QxK~(-`{JG3>3&ss_R3;% zWK-8I-mY8AI$t75p0w&_riN(=)-3%!xa0&{T~s1`Hf!&VA=3^mB2+);KRg1sp6p9S znDa96>Fw_Ub2;VN=C+zVrP#gx1}$5l3vOC|2s%S6hEeCAhJgtqq{GHvNN-AN(g&7E znZHZ%G;?4yj>8y4-=-uHl;g=dS+T(h?U<~LKYV%V`(N0wl?`xi)cHQp*6MYRM4(eX zF9?390F~*nnQFL%`(Eyju (cYTh6|RgxYbrknG~Y~A+Fa%!J!wplqoKHj ?poTaIdx3%` zkMGCejdEwUWQtNrP-|nNF;Sk`!vJy3Z?R?%TLM1V#576O*x0Ds<`8gm<0zjeFcrnv z^Ie*8>DD@J10xW~!lGhAaiv`S>;0wbqWp|*aNHD%KLf~|C%3Vebmn)( -N1dM#qaZV!CDGJ9V<7YV0wRY*KVs`^_u*B1#ybtvWeB zC&P_Fg9LMScGm6n&509u4bKB{>-(VKJH*t~6jw8gFT`2XRi`Q~RJCTL`_`{A2Dfbx z&w`AR_pz2Yx4s^Awpgwv6Rt)Bbz%-Fvh<&Q9##w_R$M_issP&LP@|m=hNPq<@7pm- z5cOXt<-G@A`95`~Cp^PL1MXS?3;*Hwe<36hN65^_C+p`Y*g?qBkH=|esHLuFU8yGX zhq!#*{hS+yzLEs-n$Kck`DHExH j?X6~2nTXHSDYhn(<*VD#lqw; zZS{f=V6OF0>8TJ(&9$&IZ)$*>kY7-yAUdaU&|vv0WZrF6c|EG?S01vf6juKtEk> z{-@Y@-7l|87=7T>IPq8jh63E>;(UZhv<5HmUyt@*BOtKg_I>99Z3)!CR5QxMa=B)B zMX>!M1Ps#b_I6w$Re9uq;-x^1JbGp20?1iuQj84^{YT@7SecoH+}$}VE9>$(VZA|y z2bmiL=kK>^z5kLF1PXe4iGp_yr?OOOF!g<3%o4{;`THx7h`>)0x^>9@S{ZTJ_uQ{~ zEDJ%SRfw-`6O2Ca`F`F#wY#2SB}fL_`@OB-KRy;#!lxLw2=pr8alGG5(Fwy&6G#=> zQ#G;$C$P2X_Pg^o0KW(&53|Ec`x3D$ZB_cwWL0UKn#;W}nz5!`2~G2sM0%Gdc2zaf zp{O9G==)C=;RM as*HUmg&k^~Zq+4TFT>;*7h z&v(iEu8oPp-dI#=%|0ItzEWlczp_EHqvxsn%5kR;Oxic1YG0#%^Y8EGhBZiBYVum_ z>-}x{glH@8llJ>k4nbfw=Wh%6nq_kT?s(u2bZJfXE*}9SNj(>#(HOC!aclA3HnfA1 zWf5J%KTgI5fz#&BBFGj-sO6afmWpk53UUxFEf29k5b z5qFzWZFNF3iiseIeeUnsPFym3dIaQ6{ ~bMp^?nJMn3!}u{ E z2>8dxM?qBm3mN(}-CJQdRi!vce(5rh1`{WZ1)J!QD+ob@)v63Kk^C2{|AA!`Hlx$O zKd9#B=3K6)7!|5CY}3CO%*k5lRNcWwsH6O^FYrCkn){g%G;z%dQZ1vH`1mH{eD6tZ z*AFjRw-4W6?x-TsVy9BrvZkUvl8T!#sM#aZ4RrBRAZgh1ZmOsLWlu$gCEhpL)`%C{ z!%%e$V9Bu9^0KXxYN<*=h3cikk>AyR=uT0XSJ%}v6(jcC>#~ZVs~tuXzVXs2H$2R! zutCtK4%~SQydIM>81ziu?2rC>+H_~0av*(ZBDeY(NgCWYi?!FL7D#MpYm4Z=ygUpq z5l19=`0=z|R#X&J=W}7>;_e=Vh$38|Tywi-k;lx;tn>s6EQb(;D=61&AcGB&NfS8u z+iZi+@0q-!@AYkg?SEYO-zt4y7xHe?{9e*bS#bDP#24h8+VM-2;TG7AMzI7=Xf t zxE&M_Ahs&690!qez;J7C>3{kKq|a*45@jil^n9iDwBfy%&!tde=-VP8g_Zu8H@?q& zy(5G2s{dA$&G+j!gPc`nY-!0VwhZcH3*3pr#6gF2 ?YcQAPdquX0_nK_wnM6HLA5FcI!o42EU7%RAKSpYKa9v%Qbq>B z?|sxS+A0&WXSBg&G(9V8KL}Z1r~7GZ-~RK^{#5o1#N<1tOI08Myah$T5u^}EOm{sj z>-=-#w%hC&2E`NTj-o|M;|DAtQ8+m{IlHhhxYGOSiXmooT&Nov0!~q(8mUqye{)in zcY8cXibNzJD Nk?R1phLj~mLpeL#F zv->W-`SF^y{T@0tCRI2`g-j&y50nm9#Xd}NZj)g}F`pyORWfw^T+#meueTwlntQgc zDS4;uAdOUN!^g_lm!$dV>AfuLuTF62eT=jXIRMa=GJ_aqOcPdvx{!lz2Ri+FBs^jX zTjBHV2cd*O?A6=DpUx!^dY&QzrKLEspa$}ZVT+zg)U$h^qk4DlPZo4LTp~ac6(s#Z zdABUZ;D162 _;Q@-nVEZ|f}hO7ust6a_DPat^)_bsozf&3 zyCA_};o_3~A0=*iUEP309RjRg{F-g53s1EgaS&j%c?_i7L242`&+n7_KXm*2c;ku< zvdVOEbGv;#t8>2nCk4Ro{9W)bL%Ug2m-E-h!^(fjixA3UH}TT#xa@#%0gxlBL|sRp z*u>Mb D(gqLglFqt!>aa=4Vf?3y3GEXNPC z))xijl~OF~>=^?r7xAvOn88khJdXSN#c~XIevoplEz8pUe#v#!xIApw^miUL`CgSw z7)74RnbXsWH9j2wL$sPJvJwr2$?_!h|7QX6BgORbAkh>$Am=T9^Ywc;MoVy_CF_Mt z5RlPGbo}LZ?yA~-;9n_K9tSHxvK>ye9m;Nwck0@q#Ew+9@Qs4)hGl`Rw>b#)fgv`{ z1a+463OZ2xoAwaDeY+w0x*@uMdb$G%?59750)mFVVl^BqJx6wDteVIN#;Gz%28y^= zhX?yO;5g!5g_5fLeN|S^0slY+tL~bFZ`g@?$jw&R-CEn}6Asw3ibB5Xi9k|heJZFv z$)4a+vT&R%9Wsl!;x<-g)BIciq?-{q!CIAd7Z=SbxbHa?4ZVZfN;- u&WFSqV?JQ-jX+S&E8@lwH1BgM6c&j>+Oi;9SV^L=d0Gt$EHdk*va z9@~u7L6H{QI;RWM(|gG3AR`b7U)jvhD*-J~nM9^>^Ky~H*Fke^sZQmI^s6r1h|>gz zX4K2X#eQyQ1vX*1d%+BDIUK^n{M4VJ4?6XGLrHLZ0!?mm( DQ&*)x+4 zvB4uQE|kW)<=LDdtBxs!;An+U%o!|fpQDXvi1?5i@Y} VaV#gR!wOf?RdV9!uPxOM!%SXCeojoTiOt} zsgiQm-F|$y!t!2h>!7Tp9^`QZ%oNTRp3fR?7->0WBY}tPb+aH7Vz&!0kLp@Ex1Ww0 zhdrOG$L4+5g}#~K=>(t6eR=z3-&kci)ilHmD3dm2)!<#utt?n8)zCEIO}vpKs)nXJ zwv=hlYJ2G7={$bL@O>FK{P{2K_%FLEPJUl9_`p1x&Jh8mIOSe=hFB`43 GX)DczW##C?{arpew{0RH%eAoT@#HX9Rj~MQz3(Y5L*#b zcps|*;j$v gC9Pv**Si%0mR<+^gd^sMmalg}k$q9BIWPaiW*a8nu@5A!`!w?Xu z%}n%w)SnaedcD`p0&otqke|Xy-#Vd3SC`0N@N0S1Qa{|x+NDWUavh9)X7q_b^~dwY z1)qVZ-Il{Ry3xL}Fv@2y#|g>>{HTeAp6 g^Ztryt8n-p@ly#kc0JZp5k8Ir?J0xEEm+KL7>+Urq6XOr29pVl zf f|C*TRSzfzqqU0kN7R^yZcTgB!Y%H< znnGERma|A>7Ad}0^O2n$;;}SRI_3`=^Bg&J35riOJIZmjGxp1F8IjoR%j9u$wnqC> zo+;s1DthXI{W#l)^Cp6lDjx2W3~Qzo)msGn?Kl zGYh~N%f(WgHgY2V+9ZxdD&Zejm>ErF5fxakG<7-=#nj|unBWw5NG05PeW;qu1ajCL zo|>Ze8U0DV-AKKFE@^+lr3kl-GO@kR7-jFw`sFm$7QcHk)lq zR_w0}jyb_4%C%4%-nxafCU(>(A{v;Nu_@e(4?`3fV6h2htjk@eg}&OLb`hvvd@stQ z!EbIKTo LBOFygLlcw|Cd=zA%fkw~L{+2yplLWv(;AKt*qUIq zR+?l&qrc!rBHkraIwMKbOSx0%62(;&A;wZqs_XLTEKl=c3h$(NS2nVD6~ z^%*fi%w^o)_ f$!tqDVKD>TqQZA>T z?1vdJQT$-Tis4Q4X{l@l33FM0j;lCRP+_%W5Nn{%6 ?V8%CenNIZEvY z+0RFhavNq=O?{af)aizQ^+ KE(aT@dcn4LE%t?=xEb*Nq- zVQ@PH-mvGrJ4coaN7nn} c_$RS;9ra-e^AR>mxlu$$#T-)H9&VeVxu8;x+N~@JG_PyAQ+$iAZK@@_ zDSRMKUV(5zVYg#%7fN7y$?X9v{rh?2lFi)8l|kJRV*`YR+G~ja(d!-tEg||^Ot+Sr znxdz0Sc>xHDZYJa#-Y9`xNxvwgM8AhWyEQ++z$PGa-GK{hVC?>RL$Rn(Ii6YAbMq- z=8EVLp7M(CUCBISSMV!OvJmrAhU)|4ZeFOc=*LVb3xvsmp6Cb#fovG%eJ*Bqy6x;{ zC|26MU){Kir!kV?;FoHl>2BsL7&!)hJrNV`&Uh^_< KgTr$y z(3a2<|Kf_(xp(+25P-*!OzV!2&EMq4_{Yj36|3mi@KNr?{#w+GI693K`*e0Ex0*ep zq0YXvyAP_UzZ*dUa( as z>)N*n*LZpw;{k+;NK|#~L^*hYYr~f4iWSfVqJ(xLUL-oBTv`1q{hqLxWB`WK+B#<~ z!^}4YYq&)1z(9>ctkn&gO)(W!Z=8Jil22X&g@O?uUss>ZpfG&x=tIn3h&1q_#tzk- z( qWM4t}b@|N?= z47mMxc`-1>GS?P~qVEl?NXL(SbZ%tp%lH?;FY#r)n(%w4laLMrHJ{e#?B-X6{G=f9 zN}5L_;X(MQ#U 18)Ht_N>x)EyQOn z$=k7xU$G-d^VzeGhpy_p4h_jMc!y5 qGo;E|=#K?87HLM9NqL%QD-#?`V8>^%6Y<-c?+SfZy^|CO1T zE@JUaa{P_P0$t<2AyyW#kp{z~lsZmKm_AE40uf Eyzc z0qp>Iu!(ccDVjnI#p%%u+Ro@T^ws|HaeRU)R2Dd&L3W7c0qy&*{s^|U#EGfVi6RsQ z^4y|-X&J6Z#}|P!mq!`XP!k 60#vX&RtS2YBpXsz*$bE+^$2tQ EY ca2*-WwV9QdvsC>^nbe3Wuck;Yc_7m> zhk-bN@d|{i4Uw~eu*2-6fTIf53N8ia_f;b|yoe)8bD?B}8EWsTV%Vy%*dRI)x2%?^ zuV8>f4lXp)bNXvC*Fxu6RTASYS;}O2ds2p-$!H%f_^TC!R Uxp>EK&BO^NFu%U$*+AlG(Hl>}^WTToU+vbJ z=tkTRVOWrw6y#nR*PT1y 121(U>AVWcPp4@8Y6>C$ctByH8!`mG?8^L&PqXuHdSYxdPT3r8u^ zrQh_!Mn%)%MUz{~Wp#NF$HWb`q2oHp;uK(I6l`vIOJ8YgMt$~hL>Uk7_lshxsD$g_ zHiVBSY<;h>3i2vqk9{0wk}F>ZA34GgEweesrHbrZHRU=}Hr?bSuM^fN_L*2&g>AWe zQ851r8ttlB=G*f4A!ne2aYx ytHo{9;r1usTr zDQvcpQRpgAU`e^`H~g4E-Ii=4FkCrv-86Nqn{uNCqlPL8SGwh)@7B$G&FY9sE>uWT z>T|3k{2RHFfonCJtgy=EEXQT8e^i82wGsYE-maIci|}LSi87s 7u zmE)hsDpiIWmy+#_0~5xo8_&C%9a`W0vC&2&DtR?*O{sGqU$(tf2OJ?lQ$NP+vq!BE zkx1s^AV|zVLWIsD T-xN!q(Cao%ZD zsr!VE(8?YXc(PKAdYTN$x{Aq*&=r!D6rVzJ*#Ub_9e)wWRr)iMSE9^>g7vY&V$J*i zMxeXdbg^XGbCj4`z;foA#g~AjiKUIOSAmFJswez#l-ZwJ!1;Vzpe{@uFPNsvDDKx> zw$tpUvZEIm=Txw0bE@n6dbLcf>)ntxjS)+|8vxJjY<|J6Upo4Vnz6X?9_zGd)nK=Q z6w?TQ5~t!1PR`j`*swTn^=v2^1fGDU;uf%PO$MEl+FC!~`5x7=`B@D&Bjp6sKEZGN zO5Q)Kb8)t>o}3ZL5~2d1NfUJm(TFXP8cnkw^Bz8WEJ7n~WM^~z)RZgfr5#weSibV2 z4u&m(P$4H+S$h(F=?tyucSG+SgZ!uK?;zAdPt9-&fzIG^e4Gg&a%u!u6V@3iY#q+$ zZg7_3!YlY%F_@goWC_opG2o-SjnUv(F0*r4-aY-`o4JZYj|#Sj)x%uO2K*4#IPv#M zV{FbbY;HN@jft7PdPxLDQ|xP zk7xWi2SK%ox3pk$##uog9TVf}Qbp(TNN{>jgk0==D|nEo{dtlDcj{@5)(7sUh9*hN zbRr~AqGI%*UNBvTCGs8Y7^v$>RRb*z5OH?KsC0Z?Z&^8L@sFAPf|=pGdkF&1r9Ip2 z#}jfN0b~$sJW{Fh=_(Xf-lc?K ;%!-(o_?*>UeHZx#1GiDFojoiZT zJ1~# zpNa%8LndpxYm2^kl{L$8WnIIX-9#(!($}tC6{y8VX=S6>q^2>CXpn$c6AWyQAR%6l z`QL$z$syaAL4IaLdc?gGD`qLtybC8xp6_zFOK^CcM|&xo4m&kxx#OEREI%toX3n(^ z< Dm0ncVjhlX_r`Beq`;ZC3(srG3Ji*kZvhSK310+L`oS7UYJW5Yr9;8D6DGZ zcg%35weePI_of&m(!t>!zk}u$fZ%CYhg8WBndrE6_zE*`*R2;=>)>M8nmH8Ba4_s> zhAnoo{Mlpe*@C}4KLSc-1RFy{n`(?_Kxv#9MZSMHTsV%yc0e%L!(Jg;1(4$RvpAb; zh#+6eE)0>v?R@`GC8lXE))@jEH~aQh8y+-bQ) zQiMOIPwLg}hJRaDNS;mB QbgkIIJFu9a~2JUD{R``pWMFw6x@FL NmhZ65+qzaAxae)-aOP+^Ym77W!YC6BR?bj5mS)()2(ze*zCw$$^3D z&Jg}lzzz;$V0z%JQKc@q-EsQeuWhlq;3jy!bT+qSu)f#(ymJKypYov>(hB;weoE(Q zmX%#~6eU>@W$Z{HQ#!zz`jcQl!YBG~Z;Z_)a!{-L;4=cK!@mc%Py_{+%;hjkjjH!x zKEb1x{}m`|WY<+N_CnJ`^$_w`gzTX#IG@}5IqB1pA>0VZF3w*5vl4npy@3)G1$!h+ z80Bc8h$5CmfWu0TpQ&*;$efz&<#SsXXvtBC$rh=Y;j3`fVtxuX!C6I6zMPsn&FEF` zy;=x8j8a1_M>jUYA}SjC6J>n}Z|FwgsgT=Y2^lmYkrM5vtSo9G<-13z6%K8*;uJV6 z!JDSwDVZ~x%caT>V`{p#8imy0YN#$|vdWGz Qj{1X5}cdP*0g#jnyx5F}Fs9Rzc6xP9+%AToo{;_Dm2@S8<8>2@w zInPKA6N@0F q#QI;wgk??W(y^cy*BD5ZeSR6l&1KJW5>P3-@&)ca&Q$J0 zzrRLt^JJ2C)%%%rR96n%`8eiY>F{mcfD _9I z7^HhBesf$#2U)VuiauAfVRq=qcC;$0kW>s)dl*fH<>-F(Vj}|F;^Ek&1MC-20>~=E z78a_@KnG)LX7^u7Hj{tm?Phq@v+jbqR+GbdJJF8Pjw&}*qgl?w&OD9292_~XbBh8l z<1{>;N~T7ss-gANPUrl*`k7W?N8k4T0Hm!`JmQA25NH@h($=PdF9M@`VGS70qsw2l zn2>8o=aNbx@F+gUxGuA#@N#p*-%^+}aZ}elnbiC1-8sU1!D5c><&V8zLMTAqx4GD? z%uL{##k;maK%G>tO6P2mx@3p7v`QC@rjA)TW!uC3lT=hKYX64RJF#2&%a-!^tJ@e* z50SJZ_1t^jZIPram0J4L_LlO4m898U{G|5Mnw!^}+k~U(fFZ_4ZvXb{-azY?cIw$E zTBK!d^88QE$>qsBE)<5ps5L52t=mx;o@B9j IL%( FH3p{BN{B2}!W7XTn~G=r=~~zZ;~`iLVrA0MkFA z9lYZUZJ6(dq($ARH=iqK-aT7}&F&si4Wg8`j|xg^ z;)fsnmoCB+%buTaUK*$OMDJRO?3|r{92kAU#UR)vuvf|hG4q)&(5sOwumFk;H1CD4 zgj2 x+Af8ggBhz~5kRTpB>Jf#BdsYm$ICN1YDQOt0R zuoh;(QwLpBwJ6vAkaow?x3k;qR$%i& s->P zB{<=_N>F|49sQoheOQ)j5Xhp?co$;x2U%ndA@VFNw8I+AW-}DhD#>UYxwjb=d7FTz zJ7hR2Y?aT4Mmh5>OC=?<$T6}!{>#Fc-O;BBuGArC45h _MD(QkwPg&x zsNYQ GH*B}Iu&Tc3!nqcaSfOoo^gDMPukAqO3b$;6WF*{g9 z)dJ*p)V?pH=rA--d@?z2E6C_m*irnS6M4GwDECa!ndtGU`Ak>FXlXT!I$S+s2cHh9 z;mUsqb`u1@zrpp|_yv<=EKCn&yco2T%+@nS3mLMY{QS0w$ZGck-on5t KgrVabAjW<-MVL#iur{UrLm LWEG|7I>8mC z`i_>(o$rT(^rfRd6lHv+Hq#Lcx(1=X=}PpPq(<*do~!{!RG =R-lliFhZw>y3DI}H?e4lV~S>Xh9;uaD?jW!V4E0<7&- z4R0yhedOqfrM3un2=yS2$+{K9h{*>kZ4$t?l6K5^>WbQ`5~n*-tcABo%DGv8ZfD^1 zIcLAg)fe0am6_&F`t+j&9g?NLU*$3~ fc(&JjPSgzg1jxt~{(n5ZV|Zj;6D}NdY;)p{ZQHhOYvPG*I}>Xr6Wg{u zu{kj&m?WLApZ7cG{ON1|=v8~I+IQ8es&(($ni_u{>80{2iO4x{ $3P)M07_U3Ph<1!x^(491fx5hZP+oTxZ4mO)so-TF_&D)A NRlsyMUC~m&+6gokM_!d9(lmHEj3*kvHGL6Egtm zn(?Z6DD9Sj;~Lva%b)J^rW!hU2@R_B;ZFnQ!oqxXvFX6@6ls1}`VCZ>l+ >g&wXfx?F!~1#j^4&%#?g z(sG5o9H(AxnxTU=P(w?CM|-cu<`zN*mjF5n71m=u_7RVz*o}e*H|4RnQ(}bIXs~a+ zhukhotLJr*R9^8SYA2i4QKoz)t#;WR9HU{*ab Rz)kR4q{hrk_LgEWOBjKPUo#O1xDm-Yd#;j$-mkb9<@Jy_8f7hl)e-HeU#L;Z zr_iPEMz1K^Dum)gGNh+v&~nQ{M!z!ZyG{FXn2aKp+dZqx_Z}pyQxu9^Vc57@Oj-mk zT9szpdXqY{v7OvL #=b=oBffMzV A;{wKRD|IVs^P`b1vTqC>?&pn`yk5k?49Svd3XcZhob zh5Pfhr_2AJQ`G0Z&4Ygz?)(&TpHGu`Ti%_>=N)IE@YVfa^}?uMkSeQh?;|SI80whi z1fPd<)UN|q>^-te2 2 z CJnD}D - z+}?|kQK_m%&mbe?%Mk1B(3errA%=2N+SzK8a_ZT8u9Lx7p<}X}B(LHa$t ?B`WM<%`SYJdt1kgy4gagtxM*4?s5x9CcV2Y48auBWk8 z<@a =@ zTQD2R1_+3@aXjU4&MP4=CUCKykjU2;dJd5W qo)eMJ{&L8%&^2ycsmsy4?3v|t zbWRcRM4DI!V6cTSj?Yi5P>baQ9(Is-VO4zRgQguKHv6AlVQ-090 ?>9;l5DYl_d1lola+G%`;u z@YlNk(2vqV+*quzeN}w18kOfp!Xio1mJt5eI+TB&HHJ1DYF3~&20Nvr8^N$69*7W* z9 ~!sN&av>{rnrU9|1OG96AgeP(qK P=>9Eh#N !R6y=(P86G|j?m6|5)&&U!Op9OSr)t1Tj!Tn!*n>TIH z!5qj?dH&k-6Zf#CIbvn7m}K1Oxgo_wlGPY7!KOueHL!Wd7SNO|a;|U+r~;o~Z5{h> z58kCOFVT;l* #%7eJ-paV@e3h7?%Um zOV`eZ1ht8pVNwnFKk~Z#s#?TV+EB_T%~j)-@O!44b<0uHF^>H@)^8LTQUD0e*UD zI-Tj77$&}J2S)~$QYv?&37A)bllR)gItl^tY>z|n)*_S>$gQa~x#VRzW?gxW>#=rT z8u}mU)-2^%mb6x`)lGdpp609#Vx2>UKMk=FCoAnU?(zF+kCjchXVckiA=7Y&$wHCS z5F|4 ?Si5Rk-zWIg3}9rtlfbbOO3H+Bzc!k)as*u~ z@~es4@R>` <2R6x1wE1)s&fAT>3K1&h_Fp^zg zM*w>lD*%d;K>K!=jvax- %MB}*2sGl3=N?Fwr9f8qUVVbJ0%gTKa!K|~oE|F{U`x~hd za!Cht-(Ue#(#dj-J<_14yboKLXn97BOO`nSK94 2Rk;OH6(@oVnUB$%pXd@AM=1aRXsoWW_-YLxC^*!VMHnZv@ zRfhcD^{J^_&l>}0zlShTLTG aK`X9!afk!|4H0PcueQbbJH#Fab( zF128<(Zz#GA=kWX)lZO}YO|5^OOyZNN2<4ii#o4O6e(~-*}v4dv7Il&Mx5Ct>b)(g ztzOgk=lQ>)cyYP2C_-|w6<7uQROHLQ=^b)eq`Ni9=G=2#*k3@Uium(bzB;A(Y&K-^ zoJp(y{2zZve76_W!IaLmUof|yK0ZnJwpNPr+9 q)|s_g zdW)ISL+wXHM>24;|Im#h`kc)QM(Afc{y9`R@--ETHsp?}u~j J+-kxrWCn&Q*okKhu#2OH{#YfS z>ow1?EmN{zT??+`&4zQm0z{6Bu-DfNKymy+cmKUvg=Q`=)AnlEpUEPR?niKv*fhqH zeI*Ddy8QfM8D&`@9CTspl=vMd8vw6V>vR?yLWp?=u!Opr2~X-W*edvWdlSSyYXZ8u zkD>j%6W~HDI9M7p3iQ7*Uo>x7z{_Ov$=x-fiM&pO=(0Z~T|Dv6&i=8XsOhxR)AK9H z+*)@#QP&BE(dBqf0wLyfT Lis6)O@<1}NFap#mZx7jv+@-e zEhiAK-)EI<9}XUw76n?RH;6~HS$$2h2;^Q$4~$LK 1J+NR!*UAS4MA;E8;S8~2kxGwIBY{;rg z#pv|q9+1i)I4k>Y9Z3mG^Nia*Yw(+i=Mn(Wr6E^JX7o)l{^c&moJG(Pb3^+iI?%W( zgKEUeUh$R0$U{0OSulwd8NqyU+7y{5Zvilaj5yWaZ||FEw!Nh3En#j)1mcWx;Z8f% zv~hT81XUfcp*(p?J%4t>@ 1ux~Re?#1bymN2a`f+JSaKpifbgRq1 z2f;Jp{g%ZVB)(6#zM#`PQEesKNuKT$%vFY0d$PX;SutZjNj!ouw>&F-8doeD){m}; zaQszB3K9LU0J8&qb;bVTl;}rGt~y8gv8|GU{&v5|8v)BtABK>xsQooPE=6lA!`$sS zQ9RU>iu^F0{D;44sAG0;qUy(OXoXO)5L;0M6->!R3h6@TlgptTxGMO~9`<>@=x=+> zX?lqC>ixO9*%8ho8<%4{RK9olP#IT@ ({o+EDTK)#Y);ZrqqKUD8fc(eYQf9J zh)6v#`=DzZt9&3ko>IPjC-*mTvj(jav;mkPmoWWf5csy ?v#ZU%FW6V$7397b#B}j#&JDjR%}V9CEK(%RBKO-f5@xflM7LnVy|( zIV0Ew4f(qBH|ohSy7hX7@OoUBA7MP#ZcKXh#Ass#l?AOO*-rkg)$XKp2`-@bctP3h znIzB8CKd>L3|s{-!Qr^=eG?DSRr#8-IDZ5=;(A+&V9pi72X~@bK-O%A+RUHSa`Lf) zBJ9Zda&`xsm!MtHR8Qnb+5vV-zZ_9(1&YXG`<0LY%hXKq<1aTR+}_Pl mG0`Ar6XYnd_Z>@1x<4d46#!;BwP0bv_vN6My( zt(jpy@RW0|JAO@GFo^5RZFcJ0pqlyFfNVXxGx5Tqfryzu_61eUyqroS^@ R0XUz;J$^;nHiVFkLy;-q1gH0;q84 z$cbOtP%}gU_f7*<;chuu#5}OdqQO68En#sK=AB+OtrFU-zhb2925y^Io8E!KP9| )0`cbNzT=^XzG*4fzXd{=yE20s`?P^`cFHqWacsB8^3c1$K` zBokJLd@}0t;U;V%nB-MRFxHH6hNvXdWKc30k7R~+O_^=Z0*d0)Dgnu! cFO0cCyHFAHw{1P)#Ln4^y%ql(u}{z+LrrXg=goo7E-o5 zy25!}f6=%Nc_u4uu}>!nS^3^+ozBa{^B<2dBfEj^p7(LzvHE^|B=aCW`z{+D#qB_c zGEyyLoYxy<>iHg5#&Gd3;OC1(=|F#j8||P%u6+O~PXrl;ij4n}2&Vjsz@liZPMp)d z{9DKO=Z&7TyaZheKuubIT??l&m_Pte@alN5xYFy>icF(EbHI>Uiy9`oqC&gv =si?5m6a3oP zqZX9aO(4e+Mmw}TTV$>=b4Wlvlf;E7S=3;kTTQoSOT`%mpd*uGx3;OJ);KBnq>#9^ zYgc4JT0_=;8Ci41OrLCvvrM5@K&~n}t9eZB9sU_#%c#oXM0$qCn%?z4|51kzxSH)v zX4i^2!~b!`9~COS;7W<3$&brKv)wgh8iucvoj7YyG*{>jA076a3nwDJ_)_ovA`1n# zLQwm+MR;&%z+ab JUfom`F8tzQ|W_VU%40St@f>9?2xPKyi@xB-;X;$M|`@cIy zc_okW3mUK+x9DZN|7b@wh5Z1IuGs gwDkE}StVwfClC%%YvS;;-pLMRjZ(UFO(O@o>&3!3e&e7qAd=P(jb@ z)EvOV7B9sS9Zr1&>LpEkW|wVRaL(e!IAOW6?(6deQ?W)kEy{Hk&z3o)5*q` r z{kn-M9@`QaCBPH6m3#a8XqPot=}9(crY^3v_t6eauwUR;?>MEB)sJLUZctdA5Bv;FUqIq0sEq =Go&X|Kbsm4PbfUbUqqQ##UopeYVm)$*bKdO|H zqxeUi#SAAa`iM+4BAkh&TpfcU`Sauhjwv1EN6B7-fYr&^L)$W1(huq_$1(p~r96=U zo;e!cN#=wQvRPXXjYY*YYghzMKe|NV!YFz |3hs$^iO0EmaU1_27EoCoPv_tNEhl(q%cm z`|0D-Z|2&umk23Fu=@hud&4fhCSY^4xCHHzyD&C>f;gjVkU5H#MR1tox*cCS&?BK> zrNq3g{WCNF@v@b{8|U5mb}pV)K2J>-l6`Y7IY_pQtSk5%jTv?-dos42-)c2?XIehy zB~ZRcH#&t&mfUZ+U2a&PtX|Zzu7)bFuCyFD`0Z~uhFKm z9pno|=964d`Ih0^=~bTx#q#88tw&8Y!cAOxT^gv9n{U`APj7W?nBY{(Ir~~uix67Q zS{L6t=U11av3T4a5{jO&K*-b~%OtytdShyTc#ln0&|WX6ugpPg#O)mG-
+$?Zs_ikzMJ;SRLHQ=`LZS19M#2GmxR{7is`8Q&qB33idR8^lZpXWkLy~-2 za9Ac*-C&eW-^Cc;^&`Z;8ymc(b&FS4hP Y|1N6 z Mp z%b)k8&dpS31C_;#rFs;(4rus(`7y860muoO<%uV+(^!KrOrs%sJ?e~PN}$u{?G@*R zq6urSqa%Y4#YTeH2up=BI8iCzRgvp@)y_cG2q)oG+h`+lg&WwOpcn)<;@i*rD;&`{ z^b#u5(9E;lmiPC?y(5J7>Bl$VzlyPLfuZjLGg&=R-Fn?JEGTUHWEsMH=*X}-{ND(3 zpA5+FK9XrCm*P&h2>`c@hWj)t-rff|&o(BK>z~^OzQ@}?5 w(n @h!3=c~-S(-&m1ruI z9G2OG5!3{#eZ8ikvKXIbJuw2LKEjk7K_LSKDQk8>$IFj8K|pG(R@s+Fx=rS<*Ks+D z9Cn8YNuh$qG;W$>pXC)y34bKo8U1x$;;yhyF8w=AHkdq}$yS5+*WJfwI+HYz&&q@j zl=77FOPt^wrc3w>8@8Me;q$!zXrvS8xet^q&3!}k7>XyG-ORT${pB?7A-j;~5sEyQ z`M& J9itJc!r>0b~hfvUW95rZO z6$n?GtZ0%_(YLHYXJ|Nk^&K%20aM9kE-0@@X+fZ@f;Qe*w0-uw{JpxF{R2vv21 1;w{HAXa%^R=VSy#-U9gV!Nq zhVL0CTiDA7Cj^?}H*SJ}F;k^a=*&dBaG(qXU1P+Tm@1ANe%;Ktd1ftxyQVgKpTL6e zUomCLY5ihLDq-nrPP=#%XivJ+V5oW!h^TzZ`Na{Zb;(&ixFT&Sf%>s$SSdaP5qfCH zJ%V-S>4BdNzYOuqqg-)(%3qN} >bCOkEodQ4dxclCR=s>$k+`bpmDc;UK*~|t9 zk9JL`T%c24xh3^4CqI`KaiYb9Lz3r?*8rgJVIo;`%zkkg+haoUkai04ZAfpueR!q! zZzgurtdS&BT7xC zGTGm!@RX>>zIW$c3$x9r9o1P#xUltq@peT$AN3$kXQ6$0O%%n&Pc;@_l#_jfwF{xA zO;0 ~f;DxJapDrwU3%9$D>1@0BhO%3gL6AO^9M|8Fl)C5z3PAbsn6^4 z03@c}$gklf$axx5_oSe=VTGgX0*Qj|Jp}M@`{9EA>PYndbubJw OZHRPNd1!y#Q-Fu2A8%GyH1f=qLZph<9;A6ELE-}b35u_nu zYr22?6LiwK-_r%m{LN7XY!|pV{550)&>0Xx;=GD7+Uis=TkTQ*o49nVqEEM=t%zAB z3v_c}RyGPjmu=x;6 4eWhWwNGE4J117Q`)1F*rCOvq?p+{wX<64YgHrt@_vF^^78ptud+f|D1A==d~5 za!R8v5jt3B89p*vC-akhz#a%VH|_0QM_VY^uiy!~w5uIOh|V7@@X9uQE+Vbev}RHM z`AqvgqL0J+s*Gc-CY^CwR)7FZDC_laA%^H4lxC&sc7M+Z7WVxNH5!i}Xu{qQt>ALO z+a1_06!L(tO$|ye)0`A`KznQ6V9OvVRJEgyCHa$j065*h(Pa9eUqp`5C`Os4gI@O? z1DT)>`?E6x4`q9c2#yu@K#@a(QPrJ^8gVBk@2ersC+AYL$MjJTVvX{!P99S;QVs2a zalqvdpVN6aXAow!IdiZ(SB*hb@G08 Wp#wr4~eX491yn}YVu=Oc7Ed<7TU=nIMFp`14ct`%?l@9!oPz<%d$ z^`(8Jey|kz0dvH+KNn7PZZ%ChTSmB_ibN!iEvSL2Y4xe04k>23=a1``5!2d;)0v2C z_qX1Tl+kN{qS`afr>DAJGL7EGZ%88^?t_lMKy-^syNdZ(y^ua>W1~|MSe;(BJZBB` zVMsTZyzIeYW=}&qM8EIGtO`1Ko{!O46b$(cY+9_%uvQe7QR$}*=Q@Ait4eNk(0DMU zj-yG6>VJI+q5(g||D@vkf>I5YbenAUb1ZYmX1F)-t>tNSes3qmo$My0m5O)- ~^-Ds$CYuVpJ&*oSNKF%8Z(9uf((Z=*5?O zIGb)eV=YpKGpgCM#04jW^r^!S?}Klg)4v8|R`xnK{tnAC6QY)Dnd_B)`#Soh0Bt+A zU-Clp4}f{%Y05Wc!}n(D^}&bGIl;z}XyK|4+U0|TpmYXg1*e>d)Qx|0zmPyFFSG>f ziH-6I5YINeKHxMh!B$JQx3!d JZ&w{A($sk|-%6=eu}0pJ;w?`A8!Gruk?hn~F&LDfuJd>w%!M zRedcMX0WL*g? iFb-Iaj#5ZINV`9q4 zA!bS~w9xUdDl8?b41Nk+L70Xo?4`0czB~12`p*3GgKB$rhOXe>)gb-)#U3=}07x8U zeJSLhGf5@_>BBbJtEk>KpV81EQ Ykkv;XnTu#N+6GxXV8l@jQSpVT~+T5wjT2I`d-P zHFKlW=CgH196&7d@M#R*1pkk&5Lr+A-Tn5oR^l`^_Q?@=D~Ekw3Og26QUpRDc0mo% zOYs@Th0gBL@P`mGcb_}|Z(tCbC^4a6(~4{4x!!9QEP (wz7%Pd qfUZhV_rQbOWq}wZJx;{{b2t7?-K s5~7<)LuD?W?kQ>w{X=w`wwco!(8O4zY>>kAFk96V3YhhVF-1 zT_GsB;F$?1Z2(#EDF-GE_jdQ>9LI`81)Ktoa0@x?hlzuFFL;+66?3$viYKV1 od>{kWf>y!PlbyewPXElVEPr%J7|cJTAh5fQQR*9U7K ev8)vGj)@S#V=hU(&`12tt4+hbC;-vadaFkIbG+n0> z^Jfvnh`C0zpNLSr!>D4ZHWs_F+It!Px$wPZ2T3e_dXI;NNZeZd+9sJG$dr^}wwAU= zH^iuYO@jZN7i9^F2oqzzfO5IDdjEBOe$<&5uCT**{#}`DB{C}E>1TvyBFdLUN4j$$ zc;z?`JpJ~F4^IU;8R&cKsKDP6^hm7uPOK-%JVofVcI4rr7sxe9iA3<^80r-0_?*&2 z;S1kh(Pq6}8fVk2@t`H;Lb0KKx3Z1SqezrIS~g+P0gl |p>1KSm zHB?7S<>gpv-)XZtMED|5+08d^7Y;NU)6URHLTGAGM{TKNLATf;wF!H (YgDA}@$-XQ|-`OV5=#-z;#;8N-P$mxvM?iNU=p{tRhdgN~R3i&It75~$_G z8#zbZ;&`1y#z=)KdUi&=oI;iRKTNhN1=Xmh)WZR3cIj7(`c6%tD}E#wmU+L%kt@>O zlTwo)$zpxeKiAkuSe|9+l6LX}@c1m)DKd^ YZzvD^UA^-Tr#5WNn ANRF2fdbwk%E{FOFJN3`pF<9~uvwU!ulh~smc2j|G->~ QCfavG7KlZTy`*g!!dz|RCxcqQl)`7PQ7OMX_5Op zjXQ1fv}RpzG=3=Cm6btg*=so4)wCvQ3!ct*XV!O-H=;%O?hqGi@NlfnSxs1?ntYaX zZo`N>EK49s!-~_8Xn^Ze;h1FtIOH|+XADuQ481zAEB09T(IB88;E9n(x2R!*Dh88y z?&Rk4VmD0^!Q_1i4<3+^F tLu$e5TcumD~6 zfsC#tNnBWczon{xPOu=j!PjmUp@X_1NuU2LNP=$hr 7E-MR z&UZ_n?;0n&-)-(!sq*6T9ECOy&_16 }uLxMn3-`;qK@aaqCD_=8npTx%c>= zeej*i3S0vb&J_+2Y$olxxkDX5S);p<*7=6K9#g6;xOO!yKjL-TKOeqreViLnyQnnw zbSqhu58Qm-KTr1vk0rFZn6k>!xglK_7j^*g6hS8WcB!lbUjBw{h#SI>_@yY$>%hw> zpOJ1*;Ke%bUm{O^2d2q1D^~Qs6#NEX5Hp}6 58Aq*0eg55PWcC?XbgfujxA3L%nt^J3gWuN%c3WnXkh;hpTxLjpgA%US zVF2Oi)n0FkI3JW+8N>gzlYV$G0o`BX?Y}tyTxUMjU!!i}>b8g2BA=v*AgmZ-)2urA zi~qcG7C4%-OZb*3_N|;Qyd||i?0m7lo~yr~nVhweCX&aJ3U$W%%}~NIv3h`O_x->J zwdIvC(V^kq)oG5cwar^)k>ML>CSkiqxgcp##{ByA90N#YeTAOaF|e!mR9|o6z}rMb{MUof{zT}Q!=VK+wXMf>FT`(`LGT0T!+P 5z=Wt;Ujkb$ z?PW1z-d$eC_p}9DEKJywezvZQ^ggFnggin8c)vIl^_rhP%unq~lqkOc95H0%*rDBW z4>oagLRjToGX~W$^^Mq}*IP%QnaaXj0-=FLOR@7#`KL_FbH*X<1mRob?1)j*P?3xH zNB^@T+)rh~MWw;+SZBTwUY1DL p$3 |@>7-rWs2 z0ySNJwh3SIB4sz3Dh)lZ=LdU+*Z)!Ff~+e&{Qb_7@kx${9qfXpBK^(_Z`yfw<8jx+ z3c_V|6V?!t7ce_3Df%r9#?0c24gW6n7R*>``)SH0KhVBcVdkqZD6}P`8y|dvy8e}W zJBbpw%q)rX^1n&q1d#)#@`Zbl77=-oy+`S%u^*mBTh;N#OwxYA=MNwduPp8jS`O6x zx0h+%qNT;lBycAYIxT*6@Xkl>t!Wq1KCx~ICrPI=fe(uFr>+n9XFtF?15U2wo~&Sv zZB2q5DBDkhir@1~iJY1Tvz F4P1sp~D?gM^3(V F*gIA&M0>QJuc#3J3pA2n6z)+4 z^5_(auK*C*0s($*1w^byk2&-t564KsK;T0LMS;^@^E!|?6U%kH3$+lEVH>o<3(@|c zzm_;K$@C2izGB>^B-M!;1vF2z!II<6UXCJY%@v>c%1}=r6RE?G24s~uHLN1(IzJ~K z-)th*JkY&0&_?4;h{+5~pblj)LV6wk2dcunJ~AE%6|ubT3+MEZRMo~JuiIqarD~72 zYENjxuCX3{U!MeFV< tgWoTR8f-;QBN zlZGSi`i@0Yk6lKeg5Su$YdC@PEhUclGf9LVs(_!_C-va-)!S>2{M^%`Cnv4dcRW4i z%=B&ny)ofhE?*d0gUU(F?nQ77!cZlOB{)dh`7$O%QPjHs%>Q#M+P~)v3bfL-8#jRk zVXe7iT2@+IJfKsgxZ~&lTeAae#J{s(3|>${?ZJq?R%!bg75}7Ot)6M;d-YxQl10bL zCLN2hqo=P^cPt01pNw2p!B?_;Z!~*R*L#Pg;s0P{10``p3T2=tjNd$g5}-Jk4ueJi z*~L1)?8`m@zbAfi?f`vl&I-N3&tL!4?Rqkx9arvkBg>U rDA>So@kSyRa)=* zRYYH0>)uN=MwG@~zkGeyzP|3uU_u38HMj>)xs&5U_XgJSNn&t7x! p7e8 zp9~xeim&J+5I^TXow2~pP6P>sHH0kmP3QVU_J+64<`2N{4F-V`|4Wd$K0El=Juu{; zzrfEL`PViCIykdq`IG2nDmM^*({TB89?q7-=D+Ev(d-n+s%6o*r}k{rJW;sdCsO38 zyO2hug0lmgXvfS+*!M!-UV!jDB?va0AYD0yKwER3h{^lgeqSHVG7RIIYPzrdl{RA1 z!Dn9&M?h+o;O^(?Wsmoq$6W7VFl887YBXU>@4vX%NUB`j^+_E$P|7=kZ-x$=7IjA1 zBz;Y~ntWJ{zI{AJ98@DRJTh{V_w!?*a^dmw!FOltiY^=I$Q-j;`l{fa*?@x6j@gH; zDbJzH_qL71Azkjdwx7tWgj>|xjpKeT(0ij7OThdEMG`UeWGM_SOf{;MqD8V>76>Cu zOS~lKY6GZXCQRLo4{EaCsK038AEkyoA}>7R|28nU8918Q4}c1#_A3qkhdB2 l{D-Y|J=MjLa7=`2;ygpS!Mq+1fA&;}WxbEEzz zmvIvmZAeLMC%~$~XvU{}*#5+i0K+|KL>|(v t8 zCY?a;v^{s0Iltq_!AVe=bMKt{_XMf`v^&)(!Yp2~s;0@Qq&QVumw3qQnICn5;-CT* zO2po+7U_63wOi2`Z-sPpEy@%^3!j~+q?$rt8;h=L4;-6nRjLX(2|^Js`L>+*@Np3| zd|?^~$gDRRPH +u)42{X=Ktn*dhiMyN1+=QLv+1-X=&HjgUs=bt!T zHe~p8s O+7+2}W1@ci23oS6pFmsB%&^cYim!#?0k z0yBL2$4n`tgBatRv!DAgG-WelzY7cWG$25<$`%!WU_jolE;f90>rihtvsDh}CI$Th zfU^kH=?$)pci_^2x_c|g#s#`_Q0zKRCdL-giCkpE{u>50730#*3jo4^O7%BL9%d_j zU6+gdbfg1o5f%~tx4F_-Ux@_%AOmgHp(9hCf8J!#ZipngT6W?1%F*vX8+A+v^GX2! zOGQa?a;GD+!Xzfl9~MEn;XjTtdlU0&EwxE_Bzg5CLl32qanEa;)LeB+pw%#l5i0EQ z{^_>%XJ|%#R~u~)BM7@9*V$?wWjhnq)JXmVPom#?^-uZ8Qy-;W-;oa%Z;fS78}N_n zd0M~TC?7&E9CrX`X^S%{xQi7;k&M0-JDB-u)q%=t#F%m)>-W?$ws5q0WBGTA{iA_Z zXK~#ZY#&|Yn_-ZPz<`1yJ$;^WpTJn9|6$JaD$7-h;{B`6+sPIS)3 y8sowWh8Eq#vb@zxKI(h_Iug4V#| zamcAIiM&JzFz{M0pD$g~Hyrm#!l=fa=ohIvW*0+`|49xuGL$uLwQK-r5##me=|lD3 z)*YJo5Uoh__eGu9R+%WOI{ZR$7E&V)`*ddpE2tpW^a0P!A6BmJ+@Yw6?YHkt?V&$r z8uR`bgpfwdn#$KQi|QNdSyBPk3i^P-7vFN4W}BpQ#Mi0H=!gB=OhUUUiOKYq>C%+| zkl1R2?!?u8zEHT%M>06vERg*|z3}ZaS8Z;ds8Vp1a^myDuTKU$-w3(pligaN#~67y z+<_?J6u}f?lTcGjXN7M|i9?pPJ~Hq{EV$GsOW7+ZmSUnAKx@QWw30|bh0^%?{7+|R zsNioN7}EnnHlOjw+T4-bgd2o!z(3ZqvthwRg!!!7ASi|q(qte$$95kJZ8!FfDiH-_ z^s8oxa7*VMJUt@E$j^ *pprlIkOm*-_Ttv- Ke{0RFt8YouHwoIcSYyPpi z6)05#+$&`=v@sjC%r=TdeipZc(5hayljO_*AGn_cv_((6&%i>i++_vx`64_cgH_ZF zPq=5?($^S%v0lhbaF!`0sRhsC*n?A1+qsxJuJ6n=3grN~h zXbWu>YKxW>Efv80o`rG-A#qDQoad0@>eF505)m(JDec;Ng@qYdGB^QZz2vBT3j| zY?V)2ZOEvFaj|Nmh!>YWtwl`d47r_x-U~B)0ug#88t3nV3E_AzRgdhb|7KBQP{ZTY zvEqjk?ng}aqY9Z*%DG_bVjEpdH(k-*bdQ?~<#(W7)2_G9wQo-e)fnVJUkp}AX4p4o z$ySKG#Xv}JJk|Pb_0y7LzfOIJxuY7$nyPY}b?yoA{EECxp}Lr}lJUbQY}-`( 2Om zhtQVXh^n>k;RsVgV5ZZzj|xSvQZHO$lNUTGCa+YW^pQg$av9C=k-Q)S5v-lEAh?gI zbRk 7~`m@i>)!_aJE;@dB@40;nh1}_qo4Hg1f&FA`ufPQ7Go}BthhP zVKQPFJh_;^2~f3Lwlgs3zqzls4mg_zDOgPzWBh(j9#eW{+GHLGw``+K &*d&pzYy~1zO|?yv%o}hFYWMM2_H~?=GttA zqn7f8fFRhElN8frYlJPKppd6%wJMc1!o`4DBZ*Ee;F^cIuyzhLfmq79fnHlqGbLDS z48q#ntsC?lV!A)C(i;4+*5mjV=0j1H@DM9erD&oNZ7D~Cp0ZAYP|7^crF!z6j!H6J z_fT=*%+v`QeGEbk2cw63KM_WGVYER|y}|KO4?4iG&n`Q7lS38DAwM|J50eoZyms|B z;MQp2Z^8Uw7!H#ZD#p!GcVcX{VXyD@zE`n9^60k=>`<=u6mkpAXQ*)Jeb84U3}X=; z2gdHU!av8&PzF*Q#+L1h5WDRpB&UWmKl0YV8(-TlxPkw8L6mUWq(|h3Bv*!YpLCN6 zW!a>yvBLGpbpmxvGr(wN$9%oaR$n$$bodv9;gn)OqT^UGP?rWkkVO~;$#a!vngiBB z+6F0Xt$`}GgM0wP-M#<1rGZBHD!OdwTRdY9b*G)#VQgTgVqB^nIYc9sdaGk-m7<~s zf&)D~R7Kkwj$CyngbpX {X5JeR$TVi0f1|Lhyj-SMy!IH|D(VqVQb#&kHQ2&1bz%L_P z93d;?GB1R(Bawah5(ydEoW1wVCS;bqa%Jmq2+1DNrR*7ptgLLm_x(Kh>+tz}?(=%T z#^-Z)&mkIpYa6eKRC`@1GSA3ABBN}IwvsU%qzN|e&*pZ71?gP%5aBn?2QRg3+C$%d zEGDmdU_KD(?e*d!coNP3=eqv@jAKwqKRs^(ifm%!ct2q0{yNDu^us!9@uV#0(?WR$ zo~J+T$*PcIPn4nS pY$0 zwboZWpUeokL=&={zrWTOOc>6V>G_isSm*v5`0PkJnP8-JXhezfzIT6^jVBwv;*| z(f8`sV!1nAW-h)a>BmBQR2jI(To&t$v9EWOx 3Q&@$wY?tpRTq4nIyRO^a+%RUU!MQ@4TAd;3-v;GC}-wdt+nf zs(DT4hr^U1+{t`*e51d;#!`Q0=gklsU(4{tzkfH{cMgsz6ks$3671z-3?DeLU1mY| zcjj~8SbECu&{!G@qSX|WF_FFub 4Cj_bNACb#?PNKF)=meW};z$g#jwfv%Mff zLc)fIh95y&h{O 8roJx5a>rDZ-@moKIrK!p_cam`vf97tmbfh#qmU zI={ 9+jH@v-D9ivm9K757_@XkvPoXF{$nWY2fID80Pg&Ii& t}g_T~yjSHhQ4B z5^v=hv86?ubHP$QxN(;v-03=$^dyiH-B^7|(ONgsJWrwn$DF#5++cTV8dWSjEi4WD zX?`m`L_?ex{}2+I`CS#s^NMw2`z+K`@@~K z08ESSN@@9IqGwKL5;Xy80B~U4fDKaRNdxjqnkLVm;IjMBLOEt@OUrPd`Jl|~>|1zw zFo{h@hn{$_uE~3gIX`fZ48V9wT(m%Uv`g+j_I7vgcl;9Fva3g(kj`1s^f^q*6*Ak9 zCGcijiy$;nn*asJGF0mE`p5J6;f8@{NDv08?>-HGUEggvJn1Q#W>HW{)jaZr`XmtM zA?1m+vNdL5)6yConEmG4uG?G%?k50TuMC;?%Taj~zB8r1a`Ndn#{OrU8G6|jX;bE4 ztAky0aDHJR+^Sijq~O)%dOP@-Gq^n;FQ84Mr94(OXTLS56qAN`0RJjGJ9{yVgngl+ zJWp{ mJ`sR z>pBhVd>~B*Nk~lmJLOn?_vCYVesGQoyC0D&BNo8O0gxAdD>wc9{UJ5*_&N#xz`3N3 z1{1gD|C%++o>>W`6|S|}7Dh`O3%H$5-9I`!v|zek{rOY?a8|6+o-uL(M>UP*(eY_% z2R+Mgs3PPq{{q-8d*crTkC~YTpWF!w3c^dcs9+y!5}jrtS#7@+pZadDv`MGKD+Y#| z1fH}_Czsx8zVj`Yke9%T<<0XA$N$XvzSEl%D(E#n2RPr#{MDs|oSYn ^@+#($Nt*E4=I{FU8BiPtvj~5~+Z`{~l$u!%Wc$qv#m+TSj zMA=ohX6FF@If#YWsz0*39fbSa+2b7I{{Td2DKnB<*+7Vjv!8B2e;S+mX<#}*h(uC) zdoQI~Yhr(6R8&n(O+#6Jn%rweNRPKP68t3oNc %8z%uZb$)H z8_)d472&Dd&*ys@Q`6H@o@+E2NU`+c@9c?t9fUVV=jL7 bo@(B-ZABJVKz9NBR0_yn!1VQ$kPtJ5FB#JJ z^!7HpEnhFxi76~B+&K3I`@zQ$-ypo(_6)6s*0+S`+8Em6ik6S6vE^hA&kwT>j)VRI z52@6N0Z@K>s%JylVnCfUj9u|3%>Poy8NZ!kj#x79ualIP?w>>3(5oH5dS=r($iJjo zc{jSM=!Z!#lf4 l%7|>E~y9 3aL8`Lr+^ z`-ECHCz$D?aGQY41>UF@3<^+2m>O3uLJSanAS3#2H{+UiKA!>e`^4X>WHrwSJzU}V z%lCbIelL4K0zjPbN-D@Flg%Eyz-McZQR2b_)*ZNgH*5c#a0{BflbEl|N=t4Kcg*%f z Nd76@mnB2`Iutt-MQ0? zB-n94AztlE;l|^7Kzu%hl6{XNfB pJHpdh?Txa}v)L{D6=7AMd zE5n}Zl!o})p!aS+G}wse{lMT}^v65fS@7d0Twz5Pt`>+Q4G$4jTRpm07P|lfblaS` z=e<4C@9|A8nnR5;Iaw?NVfd}jgZAjGxxJY1>C?#;AK`G08szkY)3Y QMSdfy(NCAhR-WN@n_ z?Z%s(hi_F@nrQPlCh`ADRl~e}J6Ugg18gPa)~#C>pw5kqAgt6Be|e4M%0!ph T>%80<5=&^3! qB4$dt|{>#RuuN+HsKM{mkcqa$GCS?kla%F3N|NdQ30qanO zMC)*552lbtPqqa}m<9eN##bYJebR-+is435`mH9w10YwG?D_S4Uw?&?6jX~cfK^~L zNF5})TtGPn2g*K;=1*4#ydl2O0sycdx8HicH|XSow6?NY{rSTWDynH@?vEkxI* s|t-?W_g=mC`Mm_DlW$eSxzo>x2XcgWS*?J>JIwt0T9l(;%q zD)_7Jin=L1D!>|BrNU^l>J!_{zxW#=zo0Qk*K*1*s2Eikbo1#obFQC^((YQ`X)J z=}+{^oN4{95#?$ys5o)Nc;!Du@Kj`F=6ys7pl}C*OxGECc~B1%f7-nP(E|FHD8(>+ z0c8yhjV{L)+55^|tTtDd7pyYg3H!KjX@e`IQHp`U@`H>M<@vY7jB^#BX6DDPg_aE& zPMkPc5xEu<5zfv=c3I$`hA0ZgtlZqvii+5Rvil$TpE1zSutV%A$}~xTF*0V$T;1(m zoN~&mDO*}Fe@=Z(`MICICA9$c{J5o-G$E1*`dTT41k(~5-G#S^ug-Dupv?j067Qk= zi}rWNk_~vEFJ^~__gg25IEG|eHZVyXr0-E1i0_uPgXj t~d1qv}HVI{0Y1|Q| z+JkLyx-co72ebArE`!(R= XEyHWFZG@yi)l}cPG4lvN7jsEx%S(os; #qf?MFxPw}$H+8nywDw&Xv4YIfN^&}$}BQoiO-Cp`;PE$Wk) z4}4squb2vxZY_5zcC2TMcI=0NvMcGj0O{)LVwDem=k!3M*#sYKed(&<)?=BfKkmNC z>9bn(8~CKmum)J%g;f(~c6J*elbeh50Xn(=aZu1WA5jOGNy>0OG5%zlhvyO>6z{8a zT+@iWMFH>CxWh1u=&U{24>8Ek7k?umx>lxU=Cp$9)Qf@^@qG*-2tCvwkdfmx0VNeQ zxH2FkXTI={Ws~vNpT~aZNdHv_PhyuN@7SJg`M}>U qa!#Us*~D(v`pcSi@LjPbK^%qnOQMiAhnCrZq5WDdHmjTSl_Z{iJ9!zz=-_NxnF z;PE=!)i&QUN^SB#6abhna7w+mrj#e^bYQVSC&rWE@>eI?pwpX1BR}wr nv9UoM23j)ri&L+M=ev);EQ*{RZGAW;=HcP-1t<901c+;ZyB1}} zcujLGcoU_%9TM#|A-<^dnm-Qz*|R_I&RS)?_cbC|abO^$#KM@#D#V(Q%H|Q!Z6u zCO+-9lzZglq>=v96@Xp8lM6s^pIrpYgVMqUS#i()Hy3at6yzJQS^s7{F#b(;pE5t_ z=oWq$xE*vr3liUd6-q*xk29=KPfw3QBOkXVX~J~7+E3u*X?jpw8>qP?w*xzXE*lXM z5%{lVzPkZl<{<_0;ETY&$}d7Lyg&jE*~P=GO^l~90Y`AWR0^KTmq06}ry_iW^<9eP z&C1JL1x?aQb;yNar}=9zj{%cZU!V{ra6|5ZMqB N4;|KvyrlH){qsSkn3*H>3X@QrsnPeR@;!y^Z)cMe&*P3kz3-YCqG}j5t1cw zz5VjA`kF6TJZd~?_%zzOKO!?eYPa%2FisI5;lgbPQ1tST$UqmF@Ftm1@~TYE6$eVm zqEHV1Qf`XyYZ9V<-r_0_MMPj^yf<)shfFJjhB&NM*9N2Go*VZ;_F;$V26ZdD8iWHH zJBmXJYs5>&e3e2l>e7G6A8Rc~+)@4)kSsrfMovrmY_kHL9n^eD)+(MU{1`tG-T{VZ zK? J~;P(@E+Wg#o1e%FetuV zJ`rZR{*6txugbIqZ)*eEcRZji=*$}o2Dg}*3Di&l)jN`yn@o)}>=BP>RXk|mt^`Z1 zYmYD`V%fs9 kiop*!`kc;)jr^?*KYCB3YHOmP1M^My0g*!3fM``PTyyJ$22 zb%whpE6Mc_RTswCWDMX7wM>^j>(DZvIjXb3 CT2=Ds9rYDqh?dsAd#KJ@_1ph2-j<%rxR;0RmU*~R2vY}$gF^03Xd(7~)YAa@97 zD0kf~@a!(zi=@YG0j6m99%e+J$K%gpyYZuIe9xTg6#5^ zuW z|Bg@qLEg -+oc4V$GrQF*?)PwiZDUZa)VR3!t)UM#O$*rl*Pkt?}xq7wASf z^Q$*r6ZoXuq>6Y~r6-!ed`3KjJT$qP*PL~xlsjT0CI8^T&Kb*#OhaGsdoqKdO6qaw z)SJi6Eq$YpkCz@eM-5bsAT(XV?Bl+G1&hDT5~dKk6SNZ$%EI%mWr2D2k7aY~#=Wc& z8?{w;s+~{HIaYDqIWPNixFJNcb@w}N334ARy(89*@a*rX5e0XL))lu9; 4%MtZTxF~Y1N^3!j=2ZAtsDGQu&=d9Vgc^{B;!Hn_-8u zJ%2vq2V%r*Poeja(N={@Iw`s(=_^DtUZ9XXBJiPOnY=U+>Q%WN6ltFWE+W0~T_ir* zoP0cqKC$s^D2sW|{-ExnF*1utnT6My^9|9vuX~Kuglid5&PFle3aAn+^MQ*dxLxN9 z^__Ts#0w=0KAWB=a6T%Y-|6*a{mg#Lo-g#j8!Y3O#^Ev31xg;SJWi2rEal1{=iOTC zYAe!^b~4n;*d PLMgpXw7Nn*z7t)b@g { zlp+WiT52IRqCatv1@>Gbj~d-gVdm>*0aE`O=~%iiWy1L+b#E3z5F^)T3EGKfJ*F~N z!fw&oIIZcL>}3gRTFR7Yykfklv8Om8gQuD_Y?DH^|EhIlT>NXjxJE-@8FUuWl&DeH z;XCPQ$<@@Y=J8tC_|1?kHFevVjww>@z46zkhdR8v8+l(cE{u Date: Fri, 25 Jun 2021 12:42:49 +0100 Subject: [PATCH 4/7] handle synchronous loading correctly --- src/ol/reproj/Tile.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ol/reproj/Tile.js b/src/ol/reproj/Tile.js index 02fe5c75db..a44fcba169 100644 --- a/src/ol/reproj/Tile.js +++ b/src/ol/reproj/Tile.js @@ -334,15 +334,15 @@ class ReprojTile extends Tile { }.bind(this) ); - this.sourceTiles_.forEach(function (tile, i, arr) { - const state = tile.getState(); - if (state == TileState.IDLE) { - tile.load(); - } - }); - if (leftToLoad === 0) { setTimeout(this.reproject_.bind(this), 0); + } else { + this.sourceTiles_.forEach(function (tile, i, arr) { + const state = tile.getState(); + if (state == TileState.IDLE) { + tile.load(); + } + }); } } } From d8a5b91ad5203bc0f6032cd5ffc7c81ce4f71984 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Fri, 25 Jun 2021 12:42:52 +0100 Subject: [PATCH 5/7] Make setImage() synchronous --- src/ol/ImageTile.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/ol/ImageTile.js b/src/ol/ImageTile.js index 741982fac3..b7f440afa2 100644 --- a/src/ol/ImageTile.js +++ b/src/ol/ImageTile.js @@ -78,14 +78,10 @@ class ImageTile extends Tile { * @api */ setImage(element) { - // asynchronous to accomodate reprojection listeners - const tile = this; - setTimeout(function () { - tile.image_ = element; - tile.state = TileState.LOADED; - tile.unlistenImage_(); - tile.changed(); - }, 0); + this.image_ = element; + this.state = TileState.LOADED; + this.unlistenImage_(); + this.changed(); } /** From f7bd8102c53e1eca463da788d56c79fc93ca2224 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Tue, 29 Jun 2021 11:01:30 +0100 Subject: [PATCH 6/7] Add Show tile coordinates option --- examples/reprojection-by-code.html | 28 ++++++++++++++---------- examples/reprojection-by-code.js | 34 +++++++++++++++++------------- 2 files changed, 36 insertions(+), 26 deletions(-) diff --git a/examples/reprojection-by-code.html b/examples/reprojection-by-code.html index df386d4864..d09702f50f 100644 --- a/examples/reprojection-by-code.html +++ b/examples/reprojection-by-code.html @@ -10,18 +10,24 @@ tags: "reprojection, projection, proj4js, epsg.io, graticule" --- + diff --git a/examples/reprojection-by-code.js b/examples/reprojection-by-code.js index 2926a94486..2e169c1340 100644 --- a/examples/reprojection-by-code.js +++ b/examples/reprojection-by-code.js @@ -2,7 +2,7 @@ import Graticule from '../src/ol/layer/Graticule.js'; import Map from '../src/ol/Map.js'; import OSM from '../src/ol/source/OSM.js'; import Stroke from '../src/ol/style/Stroke.js'; -import TileImage from '../src/ol/source/TileImage.js'; +import TileDebug from '../src/ol/source/TileDebug.js'; import TileLayer from '../src/ol/layer/Tile.js'; import View from '../src/ol/View.js'; import proj4 from 'proj4'; @@ -10,6 +10,16 @@ import {applyTransform} from '../src/ol/extent.js'; import {get as getProjection, getTransform} from '../src/ol/proj.js'; import {register} from '../src/ol/proj/proj4.js'; +const osmSource = new OSM(); + +const debugLayer = new TileLayer({ + source: new TileDebug({ + tileGrid: osmSource.getTileGrid(), + projection: osmSource.getProjection(), + }), + visible: false, +}); + const graticule = new Graticule({ // the style to use for the lines, optional. strokeStyle: new Stroke({ @@ -25,8 +35,9 @@ const graticule = new Graticule({ const map = new Map({ layers: [ new TileLayer({ - source: new OSM(), + source: osmSource, }), + debugLayer, graticule, ], target: 'map', @@ -41,6 +52,7 @@ const queryInput = document.getElementById('epsg-query'); const searchButton = document.getElementById('epsg-search'); const resultSpan = document.getElementById('epsg-result'); const renderEdgesCheckbox = document.getElementById('render-edges'); +const showTilesCheckbox = document.getElementById('show-tiles'); const showGraticuleCheckbox = document.getElementById('show-graticule'); function setProjection(code, name, proj4def, bbox) { @@ -125,22 +137,14 @@ searchButton.onclick = function (event) { }; /** - * Handle checkbox change event. + * Handle checkbox change events. */ renderEdgesCheckbox.onchange = function () { - map.getLayers().forEach(function (layer) { - if (layer instanceof TileLayer) { - const source = layer.getSource(); - if (source instanceof TileImage) { - source.setRenderReprojectionEdges(renderEdgesCheckbox.checked); - } - } - }); + osmSource.setRenderReprojectionEdges(renderEdgesCheckbox.checked); +}; +showTilesCheckbox.onchange = function () { + debugLayer.setVisible(showTilesCheckbox.checked); }; - -/** - * Handle checkbox change event. - */ showGraticuleCheckbox.onchange = function () { graticule.setVisible(showGraticuleCheckbox.checked); }; From be6c757ff60d0a06c0351ebe19732047c09a3377 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Tue, 29 Jun 2021 14:19:58 +0200 Subject: [PATCH 7/7] Don't add setImage to the API --- src/ol/ImageTile.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ol/ImageTile.js b/src/ol/ImageTile.js index b7f440afa2..a2fce7f973 100644 --- a/src/ol/ImageTile.js +++ b/src/ol/ImageTile.js @@ -75,7 +75,6 @@ class ImageTile extends Tile { /** * Sets an HTML image element for this tile (may be a Canvas or preloaded Image). * @param {HTMLCanvasElement|HTMLImageElement} element Element. - * @api */ setImage(element) { this.image_ = element;