From 9ccc5ed61b5dbfde29206187fc655787cd7aad8f Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Thu, 24 Oct 2019 11:07:12 -0700 Subject: [PATCH 01/15] Change Precision in sample code (discourse issue EditAddField bug, https://mapwindow.discourse.group/t/editaddfield-bug/304) --- docs/Examples/src/CalculateArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Examples/src/CalculateArea.cs b/docs/Examples/src/CalculateArea.cs index cf3c316d..62178b2a 100644 --- a/docs/Examples/src/CalculateArea.cs +++ b/docs/Examples/src/CalculateArea.cs @@ -67,7 +67,7 @@ public void CalculateArea(AxMap axMap1, string dataPath) } //adding the new field in the end of the table - fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 12, 12); + fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 9, 12); if (fldIndex == -1) { MessageBox.Show("Failed to insert field: " + sf.ErrorMsg[sf.LastErrorCode]); From 51d73c3b86bff6f57c51afddf5d8758645922873 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Thu, 24 Oct 2019 11:18:44 -0700 Subject: [PATCH 02/15] Revert "Change Precision in sample code (discourse issue EditAddField bug, https://mapwindow.discourse.group/t/editaddfield-bug/304)" This reverts commit 9ccc5ed61b5dbfde29206187fc655787cd7aad8f. --- docs/Examples/src/CalculateArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Examples/src/CalculateArea.cs b/docs/Examples/src/CalculateArea.cs index 62178b2a..cf3c316d 100644 --- a/docs/Examples/src/CalculateArea.cs +++ b/docs/Examples/src/CalculateArea.cs @@ -67,7 +67,7 @@ public void CalculateArea(AxMap axMap1, string dataPath) } //adding the new field in the end of the table - fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 9, 12); + fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 12, 12); if (fldIndex == -1) { MessageBox.Show("Failed to insert field: " + sf.ErrorMsg[sf.LastErrorCode]); From 0a89066dbcde58d36298215219ba500a405cdc85 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Thu, 24 Oct 2019 11:33:15 -0700 Subject: [PATCH 03/15] Change Precision in sample code (discourse issue EditAddField bug, https://mapwindow.discourse.group/t/editaddfield-bug/304) --- docs/Examples/src/CalculateArea.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Examples/src/CalculateArea.cs b/docs/Examples/src/CalculateArea.cs index cf3c316d..62178b2a 100644 --- a/docs/Examples/src/CalculateArea.cs +++ b/docs/Examples/src/CalculateArea.cs @@ -67,7 +67,7 @@ public void CalculateArea(AxMap axMap1, string dataPath) } //adding the new field in the end of the table - fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 12, 12); + fldIndex = sf.EditAddField("CalcArea", FieldType.DOUBLE_FIELD, 9, 12); if (fldIndex == -1) { MessageBox.Show("Failed to insert field: " + sf.ErrorMsg[sf.LastErrorCode]); From 058d7db463517838cf01ee4d0779b7bb0cb8d470 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Sun, 27 Oct 2019 21:28:44 -0700 Subject: [PATCH 04/15] Initial fixes to Shapefile locking issues; --- src/COM classes/Shapefile_Validation.cpp | 2 ++ src/Shapefile/GeoProcessing.cpp | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/COM classes/Shapefile_Validation.cpp b/src/COM classes/Shapefile_Validation.cpp index 0544faf1..b8e4a369 100644 --- a/src/COM classes/Shapefile_Validation.cpp +++ b/src/COM classes/Shapefile_Validation.cpp @@ -168,6 +168,8 @@ IShapeValidationInfo* CShapefile::ValidateOutput(IShapefile** isf, CString metho ErrorMessage(errorCode); VARIANT_BOOL vb; + // have to release lock prior to destruction + sfLock.Unlock(); (*isf)->Close(&vb); (*isf)->Release(); *isf = nullptr; diff --git a/src/Shapefile/GeoProcessing.cpp b/src/Shapefile/GeoProcessing.cpp index 96a30b68..4c77fe54 100644 --- a/src/Shapefile/GeoProcessing.cpp +++ b/src/Shapefile/GeoProcessing.cpp @@ -9,19 +9,23 @@ // **************************************************************** void GeoProcessing::CopyFields(IShapefile* sfSubject, IShapefile* sfOverlay, IShapefile* sfResult, map& fieldMap, bool mergeFields) { - if (!sfSubject || !sfOverlay || !sfResult) return; + // don't check sfOverlay, which may deliberately be null + if (!sfSubject || !sfResult) return; + + CSingleLock sfSubjectLock(&((CShapefile*)sfSubject)->ShapefileLock, TRUE); + CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); + // fields of the subject shapefile LONG numFields, position; VARIANT_BOOL vbretval; sfSubject->get_NumFields(&numFields); - CSingleLock sfSubjectLock(&((CShapefile*)sfSubject)->ShapefileLock, TRUE); - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); ShapefileHelper::CopyFields(sfSubject, sfResult); // passing the fields of overlay shapefile if (sfOverlay) { + CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); + LONG numFields2; sfOverlay->get_NumFields(&numFields2); for (long i = 0; i < numFields2; i++) From ef9c8ac1ff6c30d143b7a82943071056f3220423 Mon Sep 17 00:00:00 2001 From: Paul Meems Date: Mon, 28 Oct 2019 08:59:58 +0100 Subject: [PATCH 05/15] Updated Delphi files, provided by Valeriy Sannikov https://mapwindow.discourse.group/t/error-related-to-gdal204-dll/305/3 --- .../MapWinGIS.Delphi.Component.v5.1.0.zip | Bin 0 -> 178284 bytes src/InnoSetup/MapWinGIS_TLB.pas | Bin 1196273 -> 1218056 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/InnoSetup/MapWinGIS.Delphi.Component.v5.1.0.zip diff --git a/src/InnoSetup/MapWinGIS.Delphi.Component.v5.1.0.zip b/src/InnoSetup/MapWinGIS.Delphi.Component.v5.1.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..12ced5bad0e8661f1fab66d87196456b2865ec9f GIT binary patch literal 178284 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

QIfxlLy|y&A&-mk#yhFx6hc zN?0~UR$*YciLNkSup8Ny=X8+BRv`J(sy|iZHks|unx=#gfI5*27!KiB3yzC^ z06YVEPf}G#j-l^aSdi$SEWWwOOsjZu>*k!aM~zt>vX-|rpiX#ouxC+VF2M@?Z}Wf7 zibBMR!X{Ab>%39m)P9k8{WOYENd@pm29*J84seNEWnanrVfIKO8mN@675T z6`Icsvq?@>wS)3c@BL7b!9@k$kLISxACFA|H)pd!@e^U8*gIF3Q&;NSSgXYj4{;RQ zxuX9>MU`-L<+>!hO6)Bw!X#ft!DQ}sL+7)Sq5#g%@uja8d3_$|fz)Jvj4UBbuYZ=hFp%4w#yq9B!axaD zD0ap?wK#$f)VI1d<|TXUO(fsy-k6sxPQioZRcwxV0pf6ctkk;QF%Kl}gJD~)dV9=C zQ@)Y7%>I~16CG@o8)ROH=ymwPVTmjf4WmZ3cI0xs})Ke8s~k)Vks7ozov$s}-MH3o1!;xP%BSe7A7k7!JSCMIL# z2Q0+U;p{&onCKzp8=CYcaKD{44Hec3y3PBOv-VaZid(N=Jl=S{^JIPd#mimK=P|2Ty&n@e}Bv~7FPEG}B*Q|l!jvotaErU?Dm zVl{Xlo7IkW73(0vUHBBjKBQ2B*q{$9{w)n^9)|bzp@V-@b>y(RjQ+ z`38J!+9`@^W=(&tz0r@R5B>4i(RA9y5yl_g9&xNew3yF1b*qe=F`sj0Z8I__B%D7s zaKT6;R+^p%E10VWhGxvbgyBX;m&G|cY&Y^dTW0LK^+qn5FGXjpm1|JF_BC3Vqhw_Q=LwV?-tRe_e z9C0XT*o+ITnV}|O5_XjxX%aSTR(Ifv;~EK?=g_E!ZFM^zLEnD7x3#(X>iPPs7tdd= zKihh_vA+3yV{85O?%u1XFSj3WZEihZ{Sc#+uFDm#Qk0A`ZgJ-0qqy8sjxWD~ty`-C z^be_6;h?d72Xze$2uTy*WH~IoGP-sw`+12)mPv!sd7ZQ(mO)ANWl?LCyVFa&(g0xC zcY%%YJB3)@5JEMfki0$Q^$k#dn02bojn82xWC$OXY${PEDD5VTC2X{achn5#6;>A5 zkO@B0P?U0ex0k~xFNb%OjLDofX#ZI+=YQ#T5>Z1EM@A;Z%0qJ%BM(QrC&!FK2gsL6 zg9~ig>UTC*fTjLOTJxFJ7|*x%+}X~7&D(QcqDAC#dmekfgXIjCE1iiU`>*Y5fR@?i z%%A9JcrVkLO&A>O9Sw&-RzInu;qt{2r|kBMrA$zIiJ_4Ki^WZ>x2lnmVu@8x1+3enWSnmsr4a&>M}}i73$< za>qVxKe&U{-{JY}{ouNp-O4b$xA$t}@r$k9^;b`yY^*A!-Y-xT!#x!>xGTgvhZcS=E_&^ z!u-+BJ9cyApjMy`FIk77B~O0TjNSXq$L-Y&I!O1b<)|4N)Ja3n(oLH0$N!U-xCY8- zyWLJE4gRux)y1?5qY~9Tf4ptlkF)l_tw2*n$?q~N)~1b89$!qMT5&I=$g?w84EEAqjEV%+E96g8)C`;34IkBE8^H^MSOfn^ z=CmGzm_WoTLo^+@M$NruurNab7HsXTHPG;^y6p|IC2Ejx-db1-7(<1-1p4rERzO{Q zm_BpaEN0hz4HS5fucp&>wwSx~;A@RL7cOnGN}amr4+44BnXDSQa3=)@O*#ac|1S(= zmS(=h80lrfSn_2s_nOy;!yYFa$O_2+8T+tSzJzhujzQZqB$OH74hQ4lAedg7s$Al9 zA5aknEx6L@I%QjPkuG1}vdDwM587q(zDz2Tu{oLEkt&PyJqJJ5kzAW7aDBMC^z>EU z77~NOtj*zHZYb;L>EUwNO0Ch-F2IrAS$0sOcUOTT;K#mlXUiF5+B%HWY18BV#vtCm z9u8fAe*~>Y2~X|}MER0hg%XFeks0oB(Si`hW8>*Hx)AcHj)GNG$$lAb+x+jmH7x#u zTxP*;*-L-hu)#e#8=azPKibIDH;*P)mzbP%fo=h(@HjADg96}#!PGt)ZPRxr#*d?^ z-FWlUi{>&6i^z5ylIjOn?}Bca6=%H@IvaiKbBN7PIB*0sG?aE&^(OPg=C{FU3~T66 zrsT6f9n9vRX3VH_$WxnUtj?qfe@EBapMx7Un+(Pg+i<(v5aE%mO=e<2Uf9BzN$D3Agdc3OS+#rL`a_MY2R>7`hEc=8(@B3oFCOEr>Wu zc9|G45)#f|URp&EovsrNtW>UvGFGZ_cS^weMRZ+IXF(!>s9WNxeb$#u+Fl~z;)rem z_PPJsjE8ekl;>em%FDCJF6lTDTdaM~FV|-W#dqNWqzPCoZzae9qb7X+;QyP+%1t zF9MWOkt$+29KP&aMFAQeV%@>6z7J$V+Fx)F2~^AO-}l-;3a#qL-rk$OV)L`$uu?v; zziIr5?FEM<0dN%iY&j~-+Migz=^Kly#Ey}CK5Sv?Cf4nBmko8 zEWe6KaDAtW9iw<7KfI?C=zDMecqGvwZe#by3ljtU{oDTWs>&-V*lTFRh6LH3qUUuk z=qS5X2KCOPthr` zX!*#CUvQj)2IhCy+kLqbpuSj>-3Cx`9&-N@ymg#up_snClUo-zTPt-IyAxp!inx0r z<>w2k#}30`r|BUdK-T94im02zTu0`G2R+8>IN;Cr2H$N z<@iCDd(0#RFV)x8&$B7wYznrG405`{_&m;~Ps5Qj=Iflk(|scwC4rp_=!`5O4yQttyV+2Ts{_dRtFC-NzwFjxuVqhYS>IOwMq7)?XkIax zC*!um@^KSVdUbH3B^QC|rI#HJPy|M7M^?u=s))7+iO9g&z4UM>>V_o3tYq!srFc6F zQu-`DJcu{C0McXi;W0#zbLr)WM-(CMhqM0hMG$=o6~@Z!wE*#WA|Ck{UV->BiwJ2t zANO`Vl2JM{MtJV>h$T07rK?cuX(V%i5?fu_ip0wh6I7=Ylc*?$jNH1!Gbo!Nt6!LS zVPfc5-O9v^uwDBOg4UlV!xkP2zZI|T>E`x}&Fz<4>(8D&dAj~=^VQ?^t<9Hv>o0aU zc6T?Qy?(y6bqn8z^F`_kRaa?u&qCF=87&TipaR$a*|wJ_Ee@j@Tg|Z_H8*01VuA*4 zbgZft5ZQ&0q(4-!J~;_{s874rzChIplFB zX?&3>~j zx$|UqedE=}=95?3TQ6U~*jfG16ARVliB{>SdZO>z#mQ`N`ZYN-SeV{n-XlEyo{fkF z@~iALr9*B?9B$*M$sH;jUMNrNZ4%u4Y6?jPHS?+=eUBvURYH?S7m8MSh8MB#N$ zyb6-a@w)0SLbLRUo@Q_Xnc9iClz^bpWW>A!e%ULtmx@2n zwiZM#8LhPKvU@p&y}!EVaINpVG5Oh{BB2caD@m&`RzEcNuvN>_&sDcPpC%)?QMdSN zf5H?q9$cg6SQbmzLpcRThYBzR1qI+oz4*Wygfspw(UbFWV-~r_2|(ufvrBNKjG|*& zjac#x?OX>{WCkuL)(;LH0!^*-mq(d;iL(~aTOecWB@*ZA`7egiOk~x)CgF1OYCDeN z_I8!evp7kGrDY;&Z!{kF6ct#O5M|a46XRmen#rjdD7UT`UA>SqIhnv&QHlP;@n&dL zTo74{Q^#7xdsUOPmDG&zQ7l5`FZL%P%-QaPpK?MH@?Dax$4^rX-sm*^W4IT&%j zH8he<;7F=0QqCu*B}-{IhWF3^i8H21j0gOH{blv{o^Ta}b9Z44wRp ztTZu-C#f7141f=R5iaI3o6-BQP0f495tvXCWRl9Eq0{BO-Uu702xv$XkkJ7}(D;)8 zl0*U-Q&mvu$}z-1z(GTXR{kO^&1a?0g4+5n!7>WbR$1u8Ra8eeNZ7qciy@9%@t6o2W5=loadH++0U4uZh7EpkP-Jx>dnZAhCAo!=y%QzQog^+ZbfDC? zc5LM6iCe^oK)a)qk7;nXTRUhHsB^A2WgmrtEQk-J0|s`7kPxDXK-^A5FV5hsr_XR72y0o^f9^bs~taE(2WIQ1Xh zSlMLqnKnxqJW%_S`k5RXl& zXBzb*mE{0v?U@K%mPDECz7gCYszHeQ)dL7GA)9Ys#M`>2dS=dkW-&|!e;oa2#+eGX z4{VZzqxO3NS5_a)g0k%Jbe_vBV;mVDp_%=*Wc6F_-5m(!bbV1yS~8AAy4L}uBlD2j0V zYkN2aAxnXDs&o0o_3uB`ISd&AxZzaiaD|VHXmw)~tpl-|s2Z9mf>>cxjZGAR1|C*6 z?|E!tpPeILqM9(*n(;3|xU=)jJF~%ev&uL!W5oa#YPT~2?(M$bc(J*){$%gT?)tOG z&tI*-+Iq6R{^IfG&c^26>y5{+U#xxvJWtF4n6R6h!7#64jF;o$;q9-3S(^O zggBa_%pYU}O8DiWe?@w_zbG~oldcnaFq!b-Z_b@v_55L_04a48(4 z+pr^OLQ9~NbS@whBMhKCpWyN=4lM$e0Tgox68`4wG8!59Ll(gZX^3+N%MdGz5KfQ&Q8-0NrZa#4w1W4c!4a}W~nHkbzYHgt1>tm z9(%;DD8Vu;S$Ttb^J$iFbVzd?%Zb|`)>hm8uvew|E#&HAScWA_(eJw0!C>mls>(h) zzO`_-r`(f*6u&=MW<8t^PVsfkij|S0tzQsr&0w0JG;>qIRm+vg(6L@g#B8^d#mo%b zl|npu9}&m!K`xvXD}_XcK4RWo!Skav_=d6%@Y})V<)9K8Y5RbGnm5~n(+lFKbx80G zPKf8~5VO+)Q=c2bfuonm?8871dgox=Q+z5L43KU6%P`R(*=tK}zcm|G8gi&=b zz)_1(YC6X|DiJkR=5t3XBBt8B?Px{Nl+MnMMjoSlX*TDk zrXNO;pSCC;YnC6bSn^o2a$BO)BS=an+B)?HJeh1~Iq7>^(avI4_mrZwm8sj&%1aV- zZuUf?dDE%blZjra%(|Xd^h9lH^~9n#%BfB4CCHl(_Z##&Ib%J3{ld&xr3vZvv)%1iJA2R8U%YtoZ2j4brFpnJ=otHL_&8^+dC(oZfUw`~+b8G$C&hu^K61;x4 zzVr0)lb0J$p6qVEe!hC+h&pFYqe?Mp8arRc+v5>D`sUhU{l#N4;5n*;_G;ejwBILd z{wB`xk08JQ=thJanWT zGyF}PVWDe91bJ@No)9*!)!t|_7_W^RP$_7EQzH5Or8R}PBngXlswgUtzXmZov%&d_ zq{suZ&fD3(7);KaVIU+Eg>RO@^cb9xjw85a-gk_L6WE#G8k~OJx;i^+W^3`E3P14% zd_BNn<9DXKV<@v}HBEu8bJOzB>sE8t&Wt7C8H=@xoo#~k<6uM&yZ$&BBzBhOTHxH@ zb;|o~FneTGH*W9Z>%n)J&6@!PPra(LyKSDC!Q-|y?XRfpx+kV5&EL0!p=qV#i7}Xq zmRx4`vx?aDKAW|d%=02*WETz>x}DXo4V<4#E{1Pn5`mHZ*jfPE&F*ltsJAOyJKKZF zX@fCvt#V{fbDuD?0yDyF1tEq1GFy!>*;~vEkmGQ7hRuP>Wb;ZVjJN4jSYX8)S0`L5^Ir$X*d89E|3d;4>~GqPyhg4-k$T zBN_zeG?d*4)d_t0_PIJe#Z|W)FX<(83Tg_{X)p9bda4lI#K|cG!?&f_9FLJiRg7L? zci`X&oX;Ru1(SxU=VQ|eq0}dX`PbxtN{8OE2MTEW7Dz32RU5m%4_B9a4a6*9AszTl zs+|cnedQqVb~YNq#|N{uY{$BDL#8hUzZeGIV+&;%*#|*PkN81iWkf|e_;5#VW6dAx z3h#d~?$qABW#WO*xj>k=@$i{qdIQI|)uvoTG29CsU=Q zc7>YVL(=}_w7s0d44JW1WBG)yN&_W7Zm(fMdG`j_cQP+UG~ zg*0Viy1VBgc8`ztp~oK#CdO&Go#VRCpKm?g+t}G$-`#rrdi~kn=IiyXm(RA=UvECy zdb<1U`OBwIUafwghLx=A)NYlM_w3Z}+uTz`9S2%czT{v_%`^PQ2mLf}eEpIsHqT-m z*}zhYchtZcx6DB;i4?-l_vDODwk0ELNs!yCY`uQ|dVBlH)-9ZRpvCI^$W)DnVk+Ib8jXFcqO>#9 zw7x>&-Vb$+DbAiTSOR=T_K0Bv`VxSWl{s$D;_(`>=23;~2Q z=5j_h5|m%nK`_R_0soq-ID*X2Wd^*?I~-b{j_f3tz>rjgyMyH`J-B3EhsFHHoB%BfI@))C5n2X7W>M!Y2YT*?BZ! zBRh4Lt=BA?K#?6a3soD85@&;Z&7BDp*)FqC`N`9>2vg&;q9+u_rA~sL+8b4{_?!8s z4mO++53s^P^_13-?jSbxX)zirXIED+vp#+Ccx!k2>C^R>FCRZ$fA-?_)Ag+v+nejJ zAMfpMZftDtJ=wa252;{zx}s54s)O3rjxwS-cvCoO<_n}X8Tj9- zwF*oON6mB$DqEblGuWTB6UO0qXjW2ipTM-hFN4`=00&GzG~bm}3#|TC*lI~XG@NNW z9xR#GvH15cy@oQ!`z<}>n+<^UO*yMJ?CfnoD)DIGH(AoW)oN9D!cJ&2LA-L=~ zidZ=H&oUALq{%&dw)C)f)y&SDHTak5OLWYzz?iL{;Mt!X4K8W#$ZBZ@1AwqEpMfa< zt1vcngp;vkR(Dr*kidomoXQU;)RHmj&`B*Mj`k?GG+us{9|z5wKR6|+KMAW3T2;inLv=5}oizvP0};%5JR zMY&b3tF5J$yzu9BF{_?0fEM+z*BhO);%~@wxB11^XmL51p0poFr*MXG%_Y!DXW!+4 zn^!Q`W&*=+^KLXA8y$zf6~D|EGtfaF^*YMyD-b{sR7d%zzusx;!RQt)g;wAX{uPM_ z<8VK<(oeBPhRdz(m3K6z^M4)BPIW~C#m;=ORD}%Bpj~F)V6OBwGd#1tVoceeKQ*g_ zY9k$f8SlN{oXrMi=9Y7o(!;u|1~0FI8*2kY#1=a021u5zoQP1k)won~4&NT(X-7Fo z>57_x#E#6#h}EG!{AG2l8PsqB$0=>Twm+F(E#SofQwblB4Fk5XuLLuDxNNF-RaJz; zoxCRWW&7M;AWh$&si+If@9$-#{FN1gUclBhlyl7%cJcLKFvVm8k$>eYA{b8)Mlblx zWx6gMK?Oq=sGu2|S;oPgL{zg!+s~T$)i?wEwQ1s01-_}OT1_d(1}_Mk%6sd7s|5f& zxPdsDFGi1HqG#G0yPkIGi&D=ZrJR>mFqrkK>WL!H`}K8%?w&% zG&yJ%7cKc7XH{Le28{1S+}4ycGN@aFiP7))_v8H!CvP5oXb%Q+Gc-jd13qN*6%d%s z04tyQNR`I{m=9T1;2%dnjAMk2CiyMZQnSL_oz3_Ale5;fLgnnH&P};euo0;MavhVs)BK=?U$K-VX1v-O4|{pHY&ZDVQ4u#NiWyRFw{u1=dyS`7b3#wHR}YzM~T4$!;cdmp4rRVW?r@~UM@GIy#Iq6J#N)&S3h+M&Kk2e**675 z{lZ=b+zecN#U&Q}1UJ)fZWQ`V(+->Y=rk19tb3ls#n^aqPJay+8%bXHRS{H%DK=S9 z>FqsfzJF|HFmbz@!Ka(6x_{zjnHf3tc@-y1jcatYS@^RMaH}ymh4Ec(n~DBgKQ|Qq zKD0x#B2Em$-u^OnHDSrMn8-fj+?YB52cxeIw$p2(X4r_qzEbMz#@N)3Ufsejmg*M( zN~@lZTtX5@EmhPA5WNex_zJvuyVSjoD#P1OkQ`pRg0g;xWN+499%6vsmE*L%+#V0$ zUUb}%OzSTP2`^W~#pOwxtTor-KcQqPE$GWuw%MA;_ew86!9xXR5#1V>=4t?%KxMx& zGfR!ZoG&#h)i#xOdPRaPu*?CYP?!9>Kc;47W?u)R;H5?lU9`n`LCGl3hl8<=DrkOu zhmfSV`e>YPAZ8VIWeVeLfJ&({|D)ysl0^XPs1-HgjF zhD@8N3-;4=sx$fx>YjKtZKl_MRW0w&Pex~FFa{Lrw{Ey{b1T`2ox@D<>-qfEGe0d< z%$$3pAD^a3?8n);-5g9q1i6)ep*}5Ise{160K*1p2k$Jqy=T959sG)d;+`hf#N@a+ zzjSkI_uicS%M~93i$@sO0VlDhTJZ1o>c)&_V`CY&(xSJlw;A}uLoOxFyOrpu{-t&N zc>ET;aO=gxjIkDz;5>pI4DqAx+*{9Kn#u3O=FY39aiYYatP3T>qc1xE_hB%kG@vdi zZvp(*x5uxZb%5iTu?%>MyLG+4vvzz0n4uzi1Hp?wM8V?*I@aQABrqw~w;bckj&WP2 zstJv(O_)WUeVvVF?8KBeuX$tsJLHF{x<*qt7=()?dsGS8yeXsm3IyJogD802g(+ci z%YVwy2D24BlbZ%kJ!na5SHT|h#D@p+YR~*fKpDjwltlSu}#2g}= zVX8z4^c)DL&q@p+6-D`Z)gyP+BlYM%=REpMNmFjbzJq%oc!U!YFy}9HEEV+1-t_o0 z&!qZe&(3<{IDJpfr213Qnto)UzsZ?YCqmrFxMyclotpBre&uLR&)bWW`#r{UiX)Eg z*A3?sLLB3-ynP@}_4gXhDU!HGk{`_-hrB$JyL%w|)t`Jq)a#}8r+a=x)ax!fDwgd} zKO^eZ6SuQK`&&IE>LrW2URH9bguL{doD%iY{aC=H!~bi7Z*WZ1OY}oWY6z~tw{%X_ z%l5-hkbP?hMZH9EF)7geo17GN6(O%u^*<`=p`_dM*F7uh%PfcfpNB<#-H55>fu0ui zny{W>n{)s&Z%Gv`JB&xga4KMvpTZhksBT#MTZfBV0^79164Ouc4eQoE0bOue#V zKCC}w>LJ9m_Rx-*x`Kokqe}(3pXW?{3DhO|zuQ4mUm0T3a!vTaPnyDCV7}KUO?^X% z8S=gyHT4S0WynK0YwAlNhVlD#*wm{jrizDn+SC_DEUq5laZ^_o_gXk9%R@MC>XjF> z-UB&s>h%{B)x9}!>NE`B;fNY8bL7-_92xCe`I%EMO0E)Cb?DSLo}Ao%o;uC{EqUtH zSGKU6+dX#b#b$z}58>RYFM@D!{MN@32Twhw63<-W$x|;yY_%-CNuBIw$;Dp&{OL_Y z2=HesH+OE;=HB3Vlm#fCfm9EsR^f63t30>r>sn0Ef9}E6F7EgAVCyQ{K0Wce5=3%T zb|rW<_M_W^+Ty~c>3@jUL&*uY=P6nbBqophe2msBEvBBI=V)W)$Vu&b2to4N(uANb#eIzUc4l$l^az#a8|t!_$^oG-7P zk6=WewU_7y&DZRI=tbL(GTY#rI@V!y4QrKVE39J7OE`TlXS^pDcJy&D^2L14nLivJ zm{XEFxayF2QL=yxo<#-RruUfx_+?~{57-p+60lzJ>;$xC~s9!r>ac7jceMA&z~88*Qp zHh)hYRIh2~Jc;h1R_t%71GDXacMx#1{o43h3)956^L3opFE?L3e)96g`tI)Q&Glz5 zp6r_G{q?i;y=Qw*Uc55@+uhz=z0;8vtSbyxrK4~`z(qV5`76n=rx*KLcHsp+ZOXJZ zYZkbG4;{0#_%pn~bkc@9tVhrY^^!I2ek#D(a?|7Ap3V=h#*2}0c}~#|_6Dbm*32wb znv_A@=TxiI2^&m%W_~@u*)jI0q7H&H)Po1;Bl^?Co{d;SHnO@hSBic+9E^iQ@xiqJ z;wvQK&mNrix(ng8S6-_5*%^vLp^ut*v*@8>xO!p|t3)LT?+0I+@%;F*ZQ;=UxiyQ$ z*Ce5!EVPgU;hKoybhMPk*={eV?R*5o(Lc<1I$D^CdGS@IRw*Uff@U(SOTE_Qz?PG( z*0rn2Xz>Riv5Yy)R5cBaYSx1K1x4t1K|+Vx|7_dKlXed_0Pz%Vb;sk3efzv`f$Vwgs$3=5J3xu)HMpE$LxTeC3UF6sEHaZr$Z65QnjCd1UC4X#rVX^n3=yWX9gWF3pl;a*k#Pm!m?8kM8!Ut;kG` zSwZcrt#LCyxq#@&M`LyNo5@wCq;U4LruXe&czk{N#dL-9>%+32K461SP1HGPJMv>$1XBFdd``uP0ycf`3k;Aq1j(ZWMXVUP?{osGm(hjPMtGmcKqM=m%~i^VH0>W<}H3s;w+S zhQFWY$o$S|+_U}|U;pa*IKDCqr;h_zfmDa`QpV~Nhe9|!cD00P&$gW4Ekm+79rZg{ z8JYSEg<~LspNUVl{7RaIb?x}&kzc3aU5$S0F98t- znSSdpSZD7IzCjeHxt`ni;3~U?WbN5A4F9LO=~(kcdydC)dI+YB{lr3z8Gr^O;?e7= zl&y02Q(${=deQ8BIXh}j4MY7f#Q2sFit}NZ1MDk!eS}N?eoDad?|lm=VS1jtb&UIS zIDJMh>6FLLT9eI%sf3`dHlQFBzg^eLa~h^PuRX&WV17YA-E4C!5GH@IMhf=ibqLWT6i z#OLf$ip-r5Mn*MAbGYFA35y8MX$U&c%2jRY9EGeR87D@j+1Pr-)xA!?E(CK_aE zxa8i47NQ<`R-#Crh--qANRM*~QIRYs(IZQvs!@OPfN7yHawQZJu0z++f+&=wM^R~p zC}j7s0aCCWF)dk+hD*+!5{TkB1(CwDIJmw$5A~<#M4_4dC|W1r3b1exNM=bw4qoO0 zDOaX;*F7qua1i-Qt}3!>Pn`+nJX|c#=YqTT%%eC#NkoY}MGUrkZdW`Jqfw^9Gzu=V zdlx(k&CwF6IT9{5EHzL^W!F1O&5#nI846L<;wCpKrlg}Kl(}3`=SFsvl_Mnrb0ng8 zr9Ef0IZF(*#3eda3psdXk4q zJR^!@Ib2Bnt}Nh^F`z2HZ4huq$IRG(i{~V zhsDg^B$FXYxhzS+WrEk6*@}$P7*Pg8?n(*-Pr?xj8b^*lZHbdhDpm(+#B=U((cktDzuw4DewxbEA3!;CTV7LLn#rLC@LN{s^4q!5W@6o zwuc;Z`21~P?!Uw1p@h}o0MTcQ#v|#&Q;%I14p1~Q7*xe3gXdK&spsB-Lki#CBwFM*06dc%zB=Rio>kZ$%Bu;>djw%~O6(ho zZM{Vr*7gX(*m{JJgOm7^=^eizHJ2Cwzk{aCXNLJ*%)M7SWR|;iFNBo|!10=MgppJU$AiatNcz#O6G` zx0G-iwD^GLJm2+(;( zVN@8xQe$n7<%KY+Ow>zZ6}APlSSb>gESA(cFdqX;c*W>cihg+}Z(hMrSAV$Piz0^R zEm=EV@5zN_WkYSALs*rFdx0g3#K5l&T=}q==Mv^s8|QKWFNLx74N-X@VtUJ+@b*B~ z3h&~XMmO%73G7zlQLi?iZS3s6*jV4%ezCXy?Aeoz^;a)8pRB*$-raotbocqIr+cq% zAs!V=)%8GQm4fO6jXSfE8UK78;*b1Y1oEh~-icu_DRklN6#{(vI4{@OpIMt3&u%h5 zGYj;!AMcwpV|3O{GWPac{P#6@V22Z$a?(!YFN>W0`(fFCC*a}VrJ_((qYvonDkdZy zr3Ma~==kc3GlSH}D{@69_7hA9Po~%E6{MdAom#-hMzk2@i z+4{?88|L3HwqLw>wslKgn3k<;;;&M(F!A@8Q5?tG5dY&W!ZG4Uo`dc+Fk9DXV%FYm z5+pEtFM+a=DL2iKT%GZ=R-pgtHQCuzTcppWB9&n+0D|AuM2K>otwH8rxi5i^*-5ci zN9r~`ZB|^;?kJR4*IT;fERO=)8T1ZD?>#pZ+=`(Y4`y$3cgr;5=F=_HlAABqw_fkQ zT;JSyy8HOm*2e26+mBaoXue3Dujtokr;gRUG0Ow&=6E!iuMOb;#VB2i@!{$cVUlm^ zbTHsYd*GNtEzjFodu2SW#aCa0m{8`~Y38T1(G-5ymnLWi6}dL`zm~3@fJd}h0qpVU ze1f|(MV8R_xmCpJ1adevHs@!>Dl+$CkzR5M@zr$N&KAwkckx=^P%y6f?6gZkkie7V5wR8a z+Sv(MUZyqtHuvHSyg-VS)pd*1o-0op+S03X)P7$x|4WPX=Fws>J8u?yqh>r5rR`xc zM9PLHroTajp{Zm{I6|o=mqihVrC@j(4pO$V2&B?+FhTKIH#=BPdy*(ZaC7*?P9mQ* z8=$=dcPx&0kouP#%0aojOLn{CxSN&5R!FaL+<^%9th3uu$3PzBD0er?D}1$zUPk$a z&$e{OqNrleVin`M!xoO6?5k82@2tu8UCG$)r1(Q2MJdaU?M{ZfXmAG(B*Y&-Ek@(p z`H<%G-MyX1+pk}&oBw;c{_Oe7r|Vm<9&fEb+1T5D`F#8Fi`|zmZYRo&W$JPttJG7Y zf1%qZpEfQ#BzBOPpRY+qumRFJvM6wA1W&{)?9T>I-a>FI{$0csK+) z9$c>iDqD{?uMe=con|pG@I&9jQyC=#vc36!7*JhtjnZ3Jqwz2tAzqEn{Hh9sp!APe zdBN{Tb2E?jv;QxH$x!l{0-TM`d)A2b;F1v?ofA1#aAt2YpCv*j+Uz+vQg*P7tSJe( z&zxp(WPT7n;H9rqD9=)q`bC7{RETm1i>}}%K;mD~{Q=#wORiqNPmQrtPh7;pecM*q zIYsizEoIcadmm`YZ{v$aU%sz84zbkBT}IJr=TCD=Dp2}VWffrk1n#O#tXKbC9U503 zVvXH7Xcw2K03tnw04VLLs#$m@6zy~j!%EQL|cZOaqk~xw?Y)>fJ-yfY2 z9g*f;GoC(jQv?3}otm5NDM;v^tw5j8haNeYq4^IWF#o@^fBfXx4%Y(SJZjy|Sw)O}u-rb&b9^y{r-9N> zX*ft&%mvc;S>ed>Hw}Dpb@{P1g9+J8R;b)VAk7d3_=0Mb-u>u|mMXlN=&VAS^~4=< zMPSlb5D85xf_OkugO6dz@Wrgapn@JZ=a;5uyl*Dwi;K0n{pEHY!o3i82PV(HIXNFU z{kh>CELdS0kJdk0z>?HLG8*zJWR{aD@ff?oFUD1kda8m_(rCxFWE%L<;5&4pl2z`T zMfLe;G5S|>Odg5A=Ek zn2EMZ<3L!YF;M%Lf=vB~7M7Su)#S{WlHx z-RS&cZ2q@^zA`dCDA*R-j_pLrsR<%R@HtVOSrrO8ZZ#K!ZzE`(DtVNpk0?8l9xu>m zTYM!yHEPojpe(fyUDG3wklT~r=2J`KU!Q>qJNU5*x&p*xKS*Y=NG@Z92 z`rS>1+BRQtuD)o$+bN~kW}d93v4HO5tU1N!`S`e>!X~5++dE_V@>GH|;tF{5SmH~8 zvdKP2Cmk=_qTO6v(|Tb>dpWDp)h_`VQ^?t;4#^P|ZHU z!cL8Kk4`NkI=Ztfh_<>#^4jL%_X%8QKY`bX+KKT-|0WhR!zOUSne)Z0y%sc4Cl>_m zrZ{QW=HK9L7q(jS)e#xY7;98lQA3@b!>tfl4E^@|+7$k)odhz!U3bTyX6|=0v}n43 z`)M+45x3B~+v8>+&2+n+Uc1QJ-mJZJ%Zw0fvqj#S4Za&gbE(1-rdJ)MA|8U8N8c=}~{$dsjGD=u0f%;Frj3uvo|$Vw79 zyXHAY#+WM=&3TekUV#Fn>98?SJM7WSkz(Se^C4)IB z7|myxG>b!P!JG&jatUHc)1Z<7PKtwB38i zX-`+qIU$sel|nAFEp#r357^ajXw~bNg~lWrmCPNbyETknpGAm-3|S@W^&oArCh3pXX_^i zXLA{vO%z~CWPyPB6awXv5D4Q5^9#ExdaL{8+wEjAGvzF8n0p%7*oQ*GhWWw3o-9>1 z%1xGMK@w$){Er>auk4Ng-q@{mWpf<)Fx`^Cl+X9cpFSfS<%uG`_&54<8|Fq2d`KOh z*?;u^K)c(3#MiY2zBK-xSsp?FU<5A&#snH{u!dCsXB-j7 z`!_gvVvnhy6$K?f!D-n)O~ncY587|deXd0~>$YRM_OuyxsA=O8+Sxb_*SaKI?T@|D zWH9c49^h0d!TTazMwL$WXq~*i*ya{ za00Q!EwgCbx;i_U8jiGH%I(7m_4#JgXc;QzQZKm3?^DlY@WeGD)*rxR$dQ%ssUcIpTpNy zI_(Zz6yx#GAiW#!#I3~sI-kwjOZ;L%MAx)EXa@5ukYR<`CW7!H0F=88K~8wvA{UnbQV0oQiGe1IQ?SDZOnwBEOHHF5d$ywZ;xuTiu7ouSS;?U}3)~ zBrI9KHyTClhiMR^LvMVu*#}VE3()arf6bwOHPtmOu`qEZy@%HyI`p-MfFH(qj@gZ=xPq0)umTg7+gQh&iru3ih>S)lYv;PFv-6~yF_=dRQ%PF0;fQ1U=%NpR- z>8a`P<>?n$O;K0Yb)4##W&yaI+Tb@>{>||iNji!EKKc0!cGKM_=5T+!Q~JqZ{uMq| z6$ICoP{=cDJ&f)26$pSg`P1v~rl=pTF5PGT$N~9Ppjwx-Shes4F8htCrA(){l6G!9 zhp&aHm*3##*o}wqk=^pdfLz&<`C@dVqZZyZYz6K%if-I$P=0ctz|1)Ckv|_tzA^mV zjIfUbj@rl21+l%qqZ0ngOF49???ElBx)S=-0T!Rkh4D*dcQZ!tKQodMZB~qoPGcN* z^IZeB?3y3$I7{bn3H8mL$dHzCB)z=k`k0HpEBD6^Cn0=pcN4--)I3srnv(oa{_Sm_ z3xQ*j4?iOXiP~Bkk`SrV7_22s(-c~Welk)>ij?@S#=;$a0r4MNvpBfMy$ezX7oBuP zaKB=HI=)*fo=UU>Yan4nryxs>^hqet5+_NKl7`AGAx(*NB$i~!NJ6CIF&smb!uev@op+NK%&BzS8A-F(mF;%3 zV|A!87cMiqyzbk~Z<{t+HoRm>e+y_hJCIPgqtRxlxdKNf$x|;u81Kx@R`~8Z{!637 zu^iqgh5u>>IF4~-PZ9vHRZL=ZjPtr3UW#*l`8 z7ZtFFv!MdQn3z*~uRXn*9~l}mWTH3eCd!bcF^Th}aD0mlYOKk%8{59kJ*V2-xwcO6 zT^<8=sVXk^SnEIAdk^B_Uw90{dB0lu8~BR$^kQ_H(@=_YC(zV;7V2F9Qo>GvH}-Q2 zW@HSD@T?+m!#$@&3=m}1$g%ryd{86?;zCj%I79!$?`8#7$0Y;R!Bma z;mx)3F?`uQhve2d*<#heM2m4Nq`Xq2$x4)}fT>q%=h{^D=oAr0&SQ>b-V_^k_TQRxjD?dU~3l#M#KT{I%!bO;y zDpm&SuNdA0U5RELNc~j6h@qu?KRG9K7BlllxdvocUzlsq$!X(?tx8k?)e7j; zEGc3^C)W_ZqH5Zre^uS6u0VsHmBmZZtz25pf?jVM(^==E)18rhm3s|#*nWEwWx?;? z+3(*%@X+PQU}DI~$g#I$-8RCs9bb=)=iy^Eo!oE_n(&_EWRiM01`=pmjd`j%!^ZNLf&Ff%`#^@B>sO~c%7Xo!!`VNsnwimmRmgq1 zB!tON+PG_-AwXp-`<&&#fhFU8VO|Hq{$%ZAGdndph2c@9JG@%t2t&(SjXutrZ`sDT zBp;d|6i1MGK zaf@H!H=e0$)4Vw2s{iN248XoJ+<##_py}nXI4%N@PcNGM_Gor@!IT#_Es(DZ$S;cs z9X(`_FXj=t>wa4S2C3ur%GmvyPwF(Z*#1Y2aad*xarh~VC5jB}ADZu5z-+tvGVeMj z2)jQjI}GcQ5Dx_1;lCNZbq-+%Mja0ZF0&o?!HyvHs5xsOTGhZomBNS$v>44$Ys7ic z5SEJ&))iPjTOI}B!O8lqR{Y%wXr-^OEWmMsfThe98 zF5n09bfPz>WVWxQKuXcH!ZS1st^t_XdMa$*)X<1k+UT?@UY8 z3NF-ar%tgJsV7BFfiT@fZTWXkTxFsAx7EUV5#p!QgG7RJV+}sWIrYu=;Y)lE=*=U$ zMDZn^rsH}i^wTx_%#!DKuPphW_&$>V;a^h>x&sJvvPb@cQ9GSZLvv%br>NnTnssuAo#Vudib9-5)+5)E!DH z8H9gR9{ZO%E&?~-BMkiHRr)-FH=#-M-F{jkZVwhT8+>d0#XeVSF{nrfKC@Uhr?F|i;ITB}N)%~S3hbQA__#(hemSWS+`eh!jKwxIbxrNADO?BG_` zKh($Vs|sGwNZKFj#A1WW?iC%Hk> z$RZG@>7xC9VlqxfQ&+9h-8e7~*=XLF>|ylnr2lo)%;8iLAKciB3V(wgYBTf9+Tj&_ z{+hZUyc*v9`e6sQryL~9-5X7YFy`WfwiaI2j#K!LC@K0ziJPqaOggAL9CotJz1UCYv9Rp1cSc zF5{!&;p~|YWjKgeH4wiT;id(RB46O{TC};KNYo@|YDn7syueCs?{U85zFuU&pPUw^ z2=(e-!(c7lm#_`CR+Q#!Lqffw&nk?AM8nCyy+l=1)pGOp*1vv3V z>?E1Px_2XDIwY6?$mwqBcXrAhXS9{I}RG{;yd0&>)0MlsSKcG4cx{RV}xK zw|cP|5kC6kMq{Ry<07w$(_~eUalNxb;*gb!Nk2p4lT>(Lr8yaT^?EK95;hp9+!=BT%y@Z8Shg-cy(-vGe99}tr`f7_aUn2Uxw>f!ey)Td z=x7AkD9-6%7sA;#0M>jHKyF71^p~Bm=IcKz+eW)`GTj9yCe$S|VK$Wu!Fdj@;AKSw ziYO%}MHwNDOTb7)79DdVvi%uR@i#{dck{BSVa^J`fk&-n*9z%Xy&QUZ3{Nq*G{5Ja z)!Y+AaG%1V{Jp&_lqZN#?5baYqSySgaAHEFTpTfp)qW1Y#Em@w<~E%05?e^pGXh~& zgnufnri}fONs3V>#zX8LTziDwi&z|mn|IJOH!mJG zM3)yIxK;5XH!mJn&CAP=?5YAWJFfw>7SvNtz8nN3uPWSUmPJDyEh`#$v!WrhEE;QP zS=q>(6^^-Oqr*T=PPz@F=PV9cvlfTB9To>$<^5#`*1WMnZeBK+1HGcwUj>e!YQl-i z4dE^W<#b7IqUBn|XXo0)<(F%wQxQUxtDBM{B)`Kv;3`XAjX;vM5zNfm2ws%QD&RC+ zeoUkQsuGl-Qx9@SET>IrsE{Znl?WME49Q6RKC4V_u-rI`9tqCWb8>poh8qhZ`O(SX%ke_SUmk6aN9UqWz&$!QzVBR`4`zjLq|uCz z*s2ikf2T|hk3P23tLZ^Axe_^97NhgwY$$zPf4D-V-o}`uFt&P}wi160z?&Rvy;XjS)y9`zUnp%!GpM8M;_ z;q6<})2$e?N8mD2F-dBb75cb`?gxDQ#&|fUN3-5>V-iwG`(q*JFXktkS|8%uOj~z1Rr2<%bNyh#h zE*;}bpJ|_b5}SPmosvI=DjS|`1m3XaKh2xtW^g%f=JSsOISM>^9xdR8lCXRJdeJoF z<7oqRm|EKNl?=^h*!(mZ!Ttwtq35y6ZrVg<=5|-ZM|dQFRoTl}k{ebTNaDM>To^I% zC4{ky_*QK38Q35$efu>EWa+v{#fQUiWABVcs7ZZHDIOM))i;!6U7gV97CQJ=;E<3=N@ z7c=;wi&@dYjbd_x#m3{6O+wJCT#*z*SlOa{b22i%f$2<#*gCp}udGm5p!Ub{;u>Z> zF6SwU`P@v7S493(}q#|r(tAS5Dwm>XM>jaTg zZ8x!V7>5keH?t^K?3|ooy z6sDwLkR;*YTvqNwPyv#r1yGVGVR>K(kkhmP&XNOunqClL!(533NRk3DRpM)b;qq6i z0(43gvD0*=5#7xJ*M{y_Y(k$9ThOIQC?1IcK%N?aS#p3+)0Mi04WrJ_XT=)l8L`q? zjuhoS>tt7?R!))>gruoKLXs@u>BqS&I!y`SNn*gJsS+AbkHb|IUq2)v0MoR9OA;k) zICPzSe2S+A0U{$v;W@dw$2NlV;k5QcBCG$H&RQU3NHJZXAqyhX)F2>9&NOilPZ~L- zrOh0Z(}oV|Qbg&KX91k11!VbcGy;nf`G?S~05vO!(sP4QH9Ob*-5*+GCO~tT5y-Ez z5pi+B6fIjDWCdN6BC@0uf5)OMgHc5ZEJJBCoJP974HsLAXT(NgIT`ba7bu8f#KhDj zNP21vF+++$-iG@Cr^q@5&|$y3%Ddv!eTn8BPZ+v9d^zNT9QkaCx zW^vIDA1zv_6#Iu*rX&`f}}I>>q*w z<92IR1M2@kRs9`cquvZ8nZ*{2ltz^=%_Fna6<}7e@d$TyzMJk0ZoMHNTrFBNA2f*^ z``zX_RSdHIA7ag$**D|XVbMnOM~mxeGah}J4QAK>;puAr5X-m4jsBn^;c_unsr$~f zwO9OSyf$sy5H?K>r88-j#5S|L9eyx4HFeh5E9P@Ni~w(<1PpJNt1XbhI()wi7w)05 z@w5L<*I{G+J40_4$sCEjfC5D_z3}oosE66_n(-7r#c!G&|Nf5FWNjWP+^uSiS-ES~ zSUR8iACP1Ie`o*r4)aUgJQ<8P0)2NPSlNaTxpqd(j5 zuCU1$#%-M_9~ieEd8GyrnjW_H#QpL}nf=BqJSuGEb$`V5of!mS-Gs3Ahen1U)?C|e z$5)r}+9|xV^gaB7uS3LFY`9LalUo7u#=W#k9#hfO*`FK@Nc2=AIT-vHU0xX?p;Ss{ z9Eu7us7Np)YpVX2M(OWX(&I%Moqly+qx5H5tG<=Mc;E8t&HkT`IBlSm+Ko2u>06(w zwg)>-rGmq!!zf}TS0T5DW8>{Xe7>uUN2Vs-+V`+Tf5n8jC+A5%2?u!$YsCsK$$&hVMkA>8&G53c=} zEdU)yLej91|8L?kVDJ*c9!FR`AYvF^Ve4#u{&ifZ;LRps4i?sy`j| zHkKV$I&>DJP8?S{`+GX>-BS&X_>Jt;(+OawzWx9q)S8J&*m$ZEv*7%SHyC(bJc6^} zaQ(UHOTdNT;Pga1Qf?n`x)C6-PoI*|Dm0T2;T#&h=%_=vZ-`$p#6WD9x%JTf&zRLX3 z?JHNk)tgw!{C%UXEP`}@H?*vhNR-*uauwLUxkaEJ%odj`T;Gi@(zK~#nsF@&{Yo~y z?DbeP&BL7NoJo!c18byPbGsmxSdEffV&jrlfdX9(C`L70w1R{@Rp3bLkVzC!10Tju z_iA{<-yDov5vUOHi@++x@7)l;jmO(~Eux4NsJa1vuL2BI-GF*@QAHJzNedpiQ~@81 zO~X_5Wo)GC1N(D}v0OjV7weq%Z7y`HI@evMa{^J*Sv)txVtJmC&@#n%j^XC`dyrQdC-;BxG{L)Ks4ema!!8JjWQG2)mo5*)FK4aS%Q=rD%3$(o-gqeb!8Jx` zuO9|NSAW`ORblgTf9?T#@rRke+lIsR-?cipC%$~vhKV23!(F>;PX_mnpfq>jzgSt- zUJH`{^i?u{-dC}eTIHc2sk7gu{gMcBAH5OO4s#VB#8y?=^N0WsViUj?sgIu#+b^Ar zm617;uEeKcAH`HC*k>{|l9dOSS04UeK}dcD8v}M5B0XbtO3pl)uAE$-NF{V}`)fk( zD5a*r{=DLn5dA&`h70It@-@W-gR6WXUy3fqziH^*c6KEZfAzZifW6-_%Ot}$wODy)4w!!|A<2f7+i z)5G4uBje{YWt2#9DQOM#yTLpL9|d+o`f*@ZMT-XNb~c?g3v@5K+R#2E0AJZDj-rvw zDP0&YKeTXiDjaIlNYK2oT>eO%dJb4sh4VUv^n=8jaQD!YKh9hzbwU~LxfP0z_h#Pi zY`)(%9%q;Fro;ihXbyBBXCInSWhnGPP+`gy^TkH**=!@oDNktdsNQ^VIUPeqkFU3ra0X4Z4&w|06#!NAr|EKnQ@-9}?RV_L=lfIC;wI=@*^*9+Jw`>c_y2V~ikj%3}CAFeLpyE@-S z4eXQV$Jq3!FOHh!o5Q~jX82lUX^yc75aY6o>GI^VKL<)&_?BVqbM<84cDw8(#j!Cf z<$P(6VGwF{q6-0pM-YgCl0bDO394wx=bDZ&t3sK)Qq}CwkIui;G)k@47Ml>J>Esx> zT2O`Fm9#Js0y(yOO`E2ir43b8!GwYt0L@Yr4X>b;Di{jB^euGNEi?1!;;WjYL3CYY z=jxi#sVN7LyL)o_ zpq@BtlGR?z>&tr7nEnGEb#pzpA7LpLj+56EZ2x@H&TJv`19?RSiEwRF_XvxH?(wtj$J|`p)~vI4HsAAf(_ggsNJley26z$t?~gtn56+s+*=%rK zG5`!g^S-B8sVDa2!WyIyQ-PnvP?mfE$&NL2g)Vu zOABDzn>9wj*m!({F>DEif7x-4h*QR!sJ?Mp0z?>dtPdK;8?DfBvjHAUY0Zqr<}y)C z`wkL}K5h`=1UNI2aU);og4JGi$(3WCS zgotSzfbTg)9-E^JgaMqd+_*GP!x7XysmM&SIVWT&akj{t5JC$rrHD6};Nha}Ong>5Lq{u)h+aB9W+SJy=famIu(2`f;&H zy_&4=kk(G-kuS`$!O0$2`XggqalQzWP;wZYx;?qqEn=ta+$9JZq9V|X<#9by zZkk_Wjw=hD`FGA-5&eruf|#R;gAS25WRXeO*1$!?GEgCV#HR6hyW$GBn4}Zo=()|Sh9>5n<*;3=3pXe z2u4oZf@N_@73UD6oRpYINi(<%cIYtTx!)1TCUE}T;lT)$QV_s2g9H1eSYeV9Bm`XK z%_fjESyZBaQi@b(LO|;^$>6y9A*l$PP`Gn5L8u?KN9DycI;msXp|=A!b4l%g0; zLqzZ_4xc}u6yZ4yf#+EWf7h=J;AfW4Mn5>+AoJ&69Eg=$_3A(% zcZR+6%L6IUeSCc&XowWb3k0$1%C8WlKo8(0f>^LVZxN&|O7?d3_Xtw*RlP)vsPW)c zhH7urjA1{iKqdB&G@?)jyZ>{1G4(&P)NAHHY_gR01Iw1CeixPtlVLL;reuKw?F z<=iy#8vehmZcNs=;A?9bTh}<>*gh}d#9Pt{q-#Mo->Z~v$9$Pr1mgC0vE{W5HI0t0 z|2o&Y^ZDKRbH!QjWHnY#RSY|C!rJ*qx= zUeBg+*{EAmt;&*<`ipI60n9HK|2~|; z517ahF-_I=&=JznTme(nVNq9Apv_A0ZJG+{oQb8&r}8gXx^3eHowqYQuV|UT0f?!p z{Fto>P5E`97lRpkCiWk?49rULZJKU0Aliw&t{P04$#n61)Aewg5^jRrk1Jb7fM?f7 zPQoGQC1QS7{)tY&yU82PSc_u@)5o6u60Nk zUxQ7>WR2-<)0&0)?0R={Zq{lTzD`n9)lw3t8t2q?^dk&LGDuuem6K9eKB^IzHmB3Z zEcGU^=rHvmlglzA9eL$K$yJpw3XhHX*$pgUOcGSV2?Y_Eq?b!fH}?MiXzO~>QAA1~ zBm$ck!}u2MboWPddIh|$Cw(-PaQOtrFq)~VS=?Jt1tt_upjWfze*4f&@}skn>VBt^ zC~2sP@@z{7zKz_hUml^lG2o;Sl={>W2`9NzwWqm39h1qVL$&~NDympsMNgzbt7^ic zb$>Fwg32BZ-A0V%jVb$+vo^p}M^L^LL}6>HJHV zw**krm&&+5HST8tf*VsuQ%uHktdJ+Oce7qvJ2@@=Jxmv2YIxQXZ6$|U=fc{5v} zUQ|clT=wD}{O`*@9fSVC;e7$`!n4BkD z7J*X8EEOF8dMgEDteMiu!Sq-+tGJ*tRxAFK&)G{!v=(e7t`4>To&?^~$3b7W6w!jw zKCo?EbuDKE79nQ?y^;TMH9Gx@Vg8JB1zBk#_$J7qV);P0f(DGf<7U-RIjtpy4GD@E zFVk~Oq}`t&oDLf9&c1nMmQ-#fkgqEW2s6f7hTr2e_O0f8G~pORTAYD*CqqunA;U}w zcU5c=cj%m<&uby8&!lNZDe?ZSpaPhD3c@JS<0*)v=FE)N7tWYE=}^VgFyn4RK@54( zrAL?APd1xyp`0g%7fN7dHFp6RJ7G1$!^!yi@a*Jbq;&6jdLW={e5a5U3^pr;1r&x5 zB9hk=O4zy%1g_G!qDPHAagI?wTSq?0K^FdU#mG$E-GH?XOI?3ZVRM|z`Cwdmk+nZD ze#62N#Da#pGk*5G9UD8-XCJlD#m0Esn5Bj3s&3y$g^h2VAl1iqZswMDf}?|l%l*9{ z%+AeX6OcBfo zWGsesu40|;j6lN%bfZ#_ukc6{748imt~8GaNuaKz8AT1ORjO@|N7I!nwY)mV*O!;K zUR&_Dyo#SDe4t&4X3HzI`(rvbD-_H(^Ao|T1lT-3pEc(&J(nP0#1~^hmtrj$x=N%F z$I-_cB@$E=irq6QLftI5M7@z0X3R`a%1OA1<7Bx>h=jZ^1Ml1@0AAVr!!tpdqsAbE z8Ahk5u$AMcJ;wsq0&tN93rVJI{w?UgJfsBIwxAW61@Qi@OACayg+#W4*a9WYCB(>HEv+#ovh?pbxw%UgTi%G<+7G5x8bTJ=$O>% z4OLuHN9Q#_2fb{-%NF)mv@=sg4C&1mzZe(Jta!8qA3nk)Jr=M_1m;cERa9V9R^1kn z%PExo-C%B9Pgs4}_Q_N3TwP9SPk^deK{OPGL^xJVK8L>o_&EGxC>0Oi4c)1TcqS+) z!KOxBCocxD3{;05b&jksPxogFVVY=hI0Yx%ot;8V5F1mAc4t}{*91{pRjXVPI<;Mq znlK)Inht&C>M<54>tgx=pQc2bVvlt*>PBu(hH^U^xAlz&#C$ej^C>%^AGBtn^}{}{ zLAr99P|yzUUKpjw@?OwJ`*c;~chE#haTj9Ohf&P*tDYV<%@ksPv=Xi+UmzR~JZa%G zs*^d>RBgs`>}2ZJ(y`%7?FGTj!k!#iBAaqVLXH!MTG)g23(`IVt_AG+%MQzsaYn@9 zZz8iEzI%)g7uHHQH^P-QPQ*dv#f*5{E#xUoXq6czo5z_#yv>JkBTpLF4IH5~BG43B z6B-rZGyZ?tV(`QhCNm(RGu=ChEkQJ=1f2UukNVx@DLzyEpYi`?sWCaC;7=jiZ)#{D z>ZS&~kQ7`hqN4}O)GOO;64i?Ng4f-|xcO^`%DoI)Gr2blwUIXEgIviKE>(QCgEppc zUnbW^mXm{qO^uw9^HK!{jwDayJ1yCXe5hj4T#}i?YbW(1Kgs2cST3KLDWy~>;UbrG zlXO*-KM+@2p$QY0W%f)VlMKDJI zA|oNN9TRo-Ze+w}Bm|q~aBTfrWCW)91eGQ$Rl%-9CUt;$Y2h)6!%(gDTZ|DlPfG;l ziG*nMMk+4_5-oH#s)A0z<=dU!<=2|RnlFNz~+QASJ@!09bM zf@6OZ3{2qsU6MYR-}q7mhF6w-J;lQx)7 z6G+-k4ua*gDHaPzCs@j6eTo(c7-C2lsAy~1!iHRm7ZMTdPkDh03UF7iZ}oh6>*uRm znZM-KtsXCKIg`EFYg-6%A79$K{Eqrze(s&Enm4w5?tOn>%aynP>srnX=#~`UdPzuE z@~W0R)2>l{FjUT=%@d(!P~GW)UalREu%6W2xT8nFHE2|Et>P{~DkjV3w}q{Ai=YcO zrCx*olVX#KU~+Y?nrAYS4IM5eq4Zl4%RDEQMkz>yLoH59?ZzTk6rZXV<`&-l3Tyw| zO%5P}m#k+kehZBnM?&+ynViEJD7U|=P?**B2v6;li0sxzK7W6Xao6a3XhgsLt{W*F zIwD)b@U!Ng2r3WOH{Tw&r(b^^%^Tf@O91{c@q7*LPKJkP8B-S>L@2j8$3Y;&n;Q^) zeI7M~dAcH2iJ=Iic7{bL6(x*E71yZ6M}m;(Azirj9V?R7T(-3(d9r4z2dX9=wDY!P zujygUyMF$m`JOfi8n!;T=TPlcJd4_o)9C|do9%O|O?Ie~?FTu&aEj=pwH92mW?T7i zlFjD3stg#(`l}!mYixf4Cz?OD<1q4uwkWXL!CFyZ(a22TuGNXUb=lf}R+xH2WlRlxSFozL|;EmzxrqviKw z+x?%bL3oHQ%VgHZ271;GuR>%gAV8JkO|iZj+xrO9zHBG$)#*j=>VZ>>qvTzH3MRbU zZI+Inl;@iU{?`0>cQp>jyg7w?92~pR{BSmeFAVpbbVL2Z(KAJVJ357{LsdtRliN=` z)7|`7>km7<%DXL@YpFRXd&}db-5N~>vuo7l%e5J4`W&?0H?!(&0pp`XsYQr$ARbUu zj`IsQbaQC$#rC{@>x=p8f1Z>^`dAV}=#8N7Fu&bSugS4zd)YNHr4q9}2Wbu2BLL3^ zVb<*ltl~g7ih~ME0QP_C?EkD_KZmUZogJFBMgxGzXaEp3TG;ss1|fVmZLZB!a9By) zC!FIa7>-T*(&a+u!Ozpd^muU%;myTYD|>q|ee(!r2$uf8O%i;+c`<9=kIa8aVUp&I zeWLEXvS7pG8qHdZpYNgHX~zWek@W$TnB#<+Jf4n6i>+&LRL1ZIp*6*+`x%t39~6mi z3}^SbJRAWw)~+Ta09t(g1phcZJ1}bv!;>|7Xh8chE9a29E(0f%F(Ep-iYc_S%h0u* zwjjweFiCDh!=o6_-ip$%yeJQp*^qcHsuaTFoPYz!pizvdXO9Pp7*gc%S)2udJ}bQu z4y<5i#IQeO5FdXFKqKX|oRzinFF-}%%ukM{$7&)(lFyla_~zzkP(?_Du;@n~czh%> z_#9ExBw9j>i0PbKL{1_@$l^RSkP^uul~an4N+fq#oa49OH6yYEM=rji9$)(HcTrR@ zrWj|@jY|SCHjbJGUm}}L=hPt(Q)$|PUMq}?%VeO^ae@YNI94`L6S)%-!4D@kr-bo}f6Dvj-=WB_TJxXlmQDOm)5_>b0^q0lg{-~8mWla+} zJs_Ns>H;aLK9G{?WVz}zv3Qi$;&tffmfJ+l#IO;Bnz95jm7Rj502*_!(UW$k`Eqq` z2k26q4m-&{Ug#f9a-l%)LP{y<|FMWdECIw_jPyANs$s#C8dT5shpD9Vx)vrNvUB%DyO8j5h)>6Qfiox$|?IT-;z-^5@Rx_ zO$XRWY|}Y)GT269Oh($f_VI0f+>M8CWmWt4NdD8i&-{7s-d1XrZ;zzTBA52;Bgp+c z+KBpLzT(&0$|`&H5#T`_ZL~$|=Q0xq;Sc{6K1(9}000Pc zt_pD74G^}ARDgeW1N=M<7|2z~u%)Mh9Viw2Kvo;r6?~B+Y1KI`x8YAaURp0}ljb|w zl{3G{mYn$&cR3@wcPR8u8+?l{PxGE^nP@&N34uyyR?^dusfY-N8jSS+B=rB}^w}O5 z`BReH3i=Yx(6=Jb0pU16`nz@@?Q<7*<3L(j)ea<*|8yWTf8K$#m0IOM(zi^Ob|52& zw@%~7VB+D#K9B~dB8);|h+Nw|#`g)#Bw(GrH}0~4_GnM-yIkzg0-nJwxc8$uJp8*F zL?}zRKfNMMJV=5Eh-DZTYJF zb87#lVvv)jxt{0!c+7Wc)CW^sf=IfoA5RItwO?(e!a=I({*KYr{v({#9$Xr0KXIpi z@XVid+NjEK-sGtLPR?HGGzFY1&|9tvSH~w`jBWxf9&6G7^~caO%DY)n z=r7M{lv&Tm5vQJOO8qCVJw}sk8+JC>!2mwYu`F{lD2ldjo5p!;oSxxeHr#2xjc^?8 zjS%T?`VqnXIgB#NSx1EmXxv-h?(ymjk)NH{V7_t%3h!H&Z4lXKt?lni@}IQJa@!hp zm65bZ1SnJxG5|9&>HPK|`I>`aj%pqap-XkeBg#l|ZpkuYU_6|MZ;ooCV^Tp6WQlJE z>tu!PNPB+waQNj+_e*VdkLR*&^~A3pW{?XA$#)G`sMrd>YKXQ@$E+|-qccH!j~}}F zD-7a}nkjtSz{)GY%5T;!CGK`UO=s)ObU1rKq^slcM(OG0{FOdy7uy7CuTRY__suWk z1<#xK!jl8g-;T1Tj$WNjsO;YVxN2tJLn~owP?yYbIR{k~lY&1%P1(D@%12Qzo)Rf%ogjV_>w0 z-YBBKAeJb|5$N}VtnL+`1v;5s*EQ@(tJMx>fpeW^S|Q>OyGHvxb@(wAs><}GB&Wkh zp5A*K$>5>_HZB;yE?Ouo`F_fcy)NRjhR>VCEW0z13;BeNg05X49)F2D3@%4uz#%Hb zV)Hl?rrzQs_F`zi%O~vb$wu1ppBV7rlS~6?73o<7lnbWxfpRPY%7<1mSYk)a({msZ zX{iJhd>lB!+|IksGAt8$eIDn5)MR9iEFnwd@k7;TF%f3WkTR)&K8n*1(Q|2#F0j)J z(D86MTlKCE6MKk=qRta06%n!!M~AfkV1R)~Zx$F%X^Eq~=37M{g5_L9HOaT6n=Sh( z;g~oc4Adch^jRCWWwj?f955TSj{GUfZEe>l+wTOXYj4NmCR;!bJxN0ucd)CE#sk{l z!LGiQRlTc^T@hKwjf!^=-bJWbS1|^MG%C8!2k={pt7@N8CruYuyPB9=*co4+U!F`e+@Z_X^o=m-$<2uMidKzwA5 zFqlIi@Hc1Aj*$^3B_V)m21j20+^`t^BCpFL{4RxKhygERU=~5Z-<)3`wIWE&CrB}o z!^tr!Lis!blq?(X`h+xIDE-hZzPGclP=dSqh=3Pay|SWQKNnb;Kfl0As<>*MMLC>3 zFTLCnSod+&MU_M%W$BevV|fK8;2yw2EGb@})tG4D)Janu48gIIwHczqhMJcE|JDe% zuVyn-=}6;gyXexWpGF-Y);qjfjGNrk()rVoAFeKUMrN*Ge42KgF19t7d?-t!+r0cT zvY&=VE!KoC1>T>_v_P&xeuVE%@i*Z#TtcWVwjapq1Fgu}-ExbNt*cQuN`h#jr`lvz zrN+CR490j*kmpzd?C+!Ds4hb$Nher~M8Na)H8FP`_%jOm_IpQ;`F#^I)6Sg0kh#Vd=+1gYVuk zcLhhjYmFRKr0T|HKr8{{(`Ks3MsrJ?Y5nW`NF$2RrnJm!s(c%ovvF8;qKoV_Td*oq zAK{F-oRQ6ipG6@A7~|l8_ay9*ok1gONa%W*El3;!eZd+@SF%#I4_{Mf*iY`o1!8#qx;H1hgx#Cz=Mu2I1T;&sPxHaK87<(W z8*5jSnOPqU%)og#8G|tAQ_326AZtD}`sEgTZoLK{UpOaUqnUcU^PW0f(LmbpYE9l% zhn0)F807%p&fw+~u4o<|j)!=ZGQBwR0gtHjR12*BS>PTE2#}5=h5d%ZhZcIjqF--d zn1jAG+bw*pVqjk?PrhXYo-_W#u6*7jnX>vV6gK?zRt~;v*-`N6002!+syV3*)&Fs8cgMTGo@$hupM@1`tyh7mAw~=>{glqhw}FN7m9zB>cZ7&8$?R=f=kMzm{rTSG0f9 z_642NCRWr~qFg6%WH{tHi6#*)R=_8Fpb&qgAEsPJOvp&;(4nT~`ZTveGWaE9ToyO` z=PShpzFf^L6$OJougiz4%P)Wy^*F{aCb{Y1_|nvYoqyC;z1SKpE(g<-_T%Vu0q^{{ z1nTGPyF7ScL>OOVrgSquyc>%%=lr zEdR3;fAFtJJQ%|Xef&|H4_!gwn}+R`_f)6ze;v{H4M*i0{#Xro41PL znVpGa%KrT6P7gC2ei`q*7oUJD^qgFUoXiH3Ik*Nk229$$qeg&a*(!+$>cz3%g*beB z^nP&N82=)4Y*!FnJ?%5E73S7CYvK69bi;`hCz<)${$zT!fR(x_aJ>EI3v9-Cmrb=T z`e4TG1qX(gT8}&1FXh1q(zNbtTj&dQm)r6$2Bsw73Mc%)x5Efk=ys{4=^HHRRgZE;vM4Knixg~b!#v&TG<;+W+~Vn4CZD~iRBIWkkMB_ zU^YYJ9(;z6y~9V9$DxxCJ5}HxM{v^+n@aLqsve{G+nvq#`;#;O;lIi`sQ&74&|K3g zGAmmBI+*!O$hS2!b`&VDc%d?JPy3gd|7c@TuMYV+wc&3m-8P3q_;B*KQS;r$4Jxa) zw|?*!+21$cn(-=XH*A{UvSr|3NAY_Xzzhqw+tnf$4lmXEMk1;4hWX#^R(3~O^J-_R z8NaMO3m-LIvo08XdsTje^^J3|a=96m{U1E_;#P}xO;J({Bf0x-FK{jF{q36xY4H`8 zEASIsJ6J6a7N`D{cQSgO!S`mxqk5Xp&gp_ zW76REA);_=KPJ~=BD;HsfPuOv1xT~yO@4Y!lnX&&wER+kg*^i;zoRu>RM0!vN(-Kj zTtX5NELF+~5WU;9_zJwZ!)cS0psW)l2L?U7=r^R`a=zUcb=se{m$>UmIvx~1))fOf zG4&OfVkd2~GFyxPgi@rmpj)~Qp4-#V2>cm(_1rtD|e730+xGg7&eC*Je#P~WMl2M69fdf$FG z9t;{+x_{;=ZWyJD-rQQYP-7OYWcc75<3czh7RqVAfxmSfX5)goo+gg)6Xk>b z1?BNCS7;1(g%8$ORR;d8x<<^1G&XI2E3J1c+P1TWRVCgrRrT!_-BHy&HT!t{7Ccew z$-)S~7L(v0g&oEWg78=w(%WY7VRPrz(>Uc|SkQ$q%};p#eDU?eU`S~|wOBR@`Rm)` zSI;^ivA5Slrf6H&`#WpLM}QQHTFDO2oDpS?8|V^?uaUr{SpRB_52D3DexX5(giV;k zoQ<4~X6%fDH<5W`{yXHy7xa-1w&&69x5osK*c%}_Zb0DeFbIH0N||VjTmDl9AebxQ z>Ao~f=Rg%*T@`wy6TgtnD?4k<0NEH?O!c|ELc$r*+##!QPPFStwLL@S9uMz`DMN#g@QR4JG)92iIrVMJz&9SqmydpqKa$Cog@A_QvFQyl@ zGf?*q4i-CM)hCNB{m-MtnLmHD*i~!Q*6YFPUoQ0iNID|k(1_EA&K~Lio6!F^rw@HQ(o>gBcxl;A7Wq?>zl#6I z!s4L!9XNtqYPCnm7=OBknLqCu@`|qV5gC)S=%t-S4eow=jZ9OdRNO~isbxP>1APz< zB`;e)xm*!&!g#)e)Jh9CA}3#ERFr(LWM)E#=rxfmz$O^}03t3df^_Wh*-3qbq8^ zkd**m9TBOY=FP`hW4t7I26F9v>#qd*0=zS&V@Za74kxiApHh$1tVj(hi;JWhHWzCj zTQk;Rjrl!lUn{1R**XdGZt;UXN5*@$Uo;3CAeZ0A4Sa?}*$8v6rkh)zgaGIFSAGSb z96oYTF9FW?a0$h&5OE4X>Juxy z*OFi0&XAv?#-sH4+8pi6N?m-#L~C-8?!tc5(zl%H-Rv!p4Yh~Y}b2~->jwNze@NxN*s#GgW)`w=9_ zIb@NOQ;-EU&ni@TL4Za@glO4ZknZ?I5hR}=lT;3vbwna&O7fSBRahIo<4}ba+CNf( zd_MyfnLiPzu+`izPC*B;n};bP+C7g_prS}v3R2h#t&CAb$cGi8u!USILJ^xgb(u?^ zMdVpYd;&at#O+!c2g15_F?>?80@c%1fy&iLPEn+)2w3n1Pe#Q`I4p_k8>_&Sz=6{w zRYb{uR)wVQx0O=%y0Kz@hBZ97-qHiSqSFcM==wn4{39n1Ed+xjny-tVsKKA52s9$-wxWR2dZn zHB^V#2$!TrNSe%HOT%gePLm^Yk}ja{%aV!Kq8z?R_1R2Xb2f#eEd4=}yI#DVj3%J< z9jw?uQuQ*;5dU18W&Zry3@Ws0K?d(R6)0*}VIJZ>F1?Iyn5V3^po+>%EYJJ^)>Wjv ztCmu+*{KtyxCNeYRhzmea984dj8D_$y<Oa>rSNBR3y8Zcw9p8p)<{x5TIdQ)qh)ZpZyq6yxYJ_|@z+gZfCiUmGSNc3YfEDwh z`R-7`D|gQM8&iDu4fe3^esnw?j~4Lc>EG=??ZY{Ry_@5ck7mrgj0gwK{94%D_p*C@9cdjUp`~czINhq z54>jlPybVjkA{=)9v0-=;>VLr`UX$WR<&bz%KD#B28Pk*$J#H8ADT!~QuvuIt$@88 z{8+mgz-V$a0AI@=8nbZv0$ZI*bweW?Gs5I2ne>gC>JERD^QowJ){nuaXYD0kiJPz4 z|Ii!SsukHqf<6_8l|t9DT%Bp-I)i2_tYYp>IDIZ>yeFXmeYTE#F`sj4<4@%Cxtxp6 zh@XWGg7U73BNS!fa9I~3vZo}sweG#^)h1qV+?fr&8{OPXKA`&@tUfi#)vHm3`RD31 z^XFHmT7_4wRux8Pcj@Hb5qHeRZ5; zT*+$LOgQ7ZT@6C1?rbn%xNBbrOekxC@p0lQe0u5BOgHZBo*XtMb^_dU&>B1x6Qj{x zyQ6{7VV1W?L6IuhKv)Iq%mRYjaP-a|;3SEv2$JuFD4f~Kc?XYA9WSn-T^C>9?(BaY zU(I8pDlz2?LIrcS>W&wq>C{Tx8O#fk2yqY-I8=D_n6ZxmZTyvPMGz5@BuGfPvQ<}Y zww%}rDwr*l+kM@=qdOo~H=r#N9@Z@Y2C8mADAU$?ES3CHqO602-ias<4wk99|2k5K zT<&V_m3;Pe8>d zh@y#lO@mQ+Io86iFTb?;(gcPegK=d`h0Sjk=iR1aDeEi+gder=nj{IMWfk|74m*uS zNZ?~wt8BMdG@6vfj>Hb#adf~RfkHJM-_ttuj_zMoCzPR?wY%}r{MO4jz39*w< z9@#vH_6c_#oA?H$p~sU$uk2U~C3UI|sf z4UGexH4CeGxf^_%;|pd%{bK#3#A`uBsd9F%Cxgq;DOTrbj29n@G6a2{7vJdcCl#blfRl2jits|_hx3GbozCOprqB% zejs{3_|l9+N*+HMiBcw22u>qM&6#_>61Z4WRvx1ZQWbtH`hn~ME5RIJb&;`VR~Rtt zBJ^TsJ6_0yn}gPCgKaMVPdm&Yx!0kv4>dHUt{|FpC;)YY>vU+uuIG0 z!hV66m@sv7JiQonzR|utHVs!7NrT)YQ-8SoQBy;#T-9ZQzuT%W_`7MHK}BGnsWOv4 zxq(4hn6z%O!EULomMnQP=J{m@cr^AZZvr+mwhX}-=7lE^E_#d&Zdbo+bNmksoibAl z+N-~z9X1B*0^4D~kdt$`d$JF#`m2$RWRuNLk}8U&Ma@a6Vm84esT!UZbxa{C1;eFT zTH(2!re()mR&q?!^vpwrT&A1~#<guZL7DLf6a+H^ z!}I@63xz3Zi6BV>@)M*7q`y#s7y1T&9(FCDy9-tX0VZh1IL^^bP`b3kdZ(|#vH9$^YuV;S-s|J0rI?Q z3WmLWZbq zC0a~s*X7bWbx9n^yYi*6DkUMHEGLKU2L$+SL$4B?4F@zi2a7#i9TXA@1r^hCut{iE zVzL>JCg%{ro-68?kSPL4E|&wdcZg~3lV4E=O^nzim1DB_YeX^`1i}2`oVg%tgh(j} zTAIOu3&GWhEr<2naUI5y*N-l^~}C6gkb|$mM8i6rj-&DOxrcMMI>T z2%1lzX|f9G$A>f^%5d2L5z;s!j+>n!(+JKoi3pa1g6{gbEmp~0ov?Mnst?s#`k&`$ zGk^XZt*h3mqqCOQ+4Rz=T%mBpNnG|`-NLjk*-_=hM4h)iT5od$4xJvqIY zwUhL-XpSIa+G{QR1=UA*OdS~lW)z=)pTqI zvPH5xsEOd@bwZ3{Z-*n;GUzUWBdh~O&p-=l@@FqqNQtSm|tBx(p*;dI}z z+wLiKkk@7ZrUAi5>c(WrP}lg!7lUE@y-r3#TL=GcFmCI>31uBLDRH&+Qu-jJY-zU8 zRT2nkB{&qi3OW#00+YhJ9q=v_rPM)4$wX~w!}MOlPe^-%o5{WwJkI$gaH!1g`N~sO zK^8)|DtO2Z=v7ByF}Ih|bA}+V!+wAd-m$5d5~!CF(LF_^It~5fU^q0+U`MY{NPB~K^!kLf9=yl2&B?2T>`%V5 zKl&~zQYO;gDX%IJBgCUKSUsAgy-@?MZK+%e!y5iSi&JUB-0{k)NSmW&D~XEG8diLr z&p=5-wH2KPB*vJ>?vLrLF*O0Jv5r-d#?)_xbTFE@1A*Q1PD)#4b(>d<)=q#O6&4BW zs;fsOEn79mgKy-VW&EWIiP@x=#6(qq4<;L$(5Fb6Du?8!H&sZ6D(s~Bu{eTVKPaz# zt8MXBB&sq6Rgf%lRMC6mcCh$xb@`>4?ZH=s!4}F*COG=U|G{Sj10`>gsWLp7D^1Ca zKh2w82D8xsVxQPeinh$C9e&ZA-?!%&R5hio5WuKw1jOL&KU+9~(9zEcZAJCOz;gw7 zLaTv4keg1}>-t@8ibR{kA@V!BhJKWE3i_lUdCrd?2`t=I@iSSz|KA zB_1gnOT~n>2Ni7)T2rxf*ThsV>^9v}p=wH`SGB5CvM*MpW4^YFmeRl8yY($Vm`3mt zossi6Z*E_d)mlK&o3l5nEn5b)WLElDEHTxgjlz45L7ICg)#{3;WsQzoElAw`v4GPx zZyuer<7Nh@e@NjhpLIUszo~jSxR`ko4v^fU$eg{w8=hFtrUKyrq*?Ed?X+hGHGs<#MksRv}t`!www^;Eu{_WPus^A^8`3ol-uw7(s^cP!eQvjxrGo1P3$ z3NH;{}2g}A3>V0vY1{2x8c)WT`?EZFM?8zTFxoEx z3TFbKfC}qM>cqDZR5Fab91zl$1zdGC-%>?aRJB$!CBWXb<|jB;W0|PSBl}{07~g0R zBdgE*!R*{D&0zXHoQzX-{19k)<7iS7W1A)JKqhnhp&CERV6?V!l0x zo;{}-j-Ee|8`{1(m2V$ofqZ^M3Mug{y-yP0nHzKJZ8(3fP|<|*dr}3$sX|W~CVVlU zGh=c8VA9!wB~(kqv}_zKd;B#rrX-{`(+rNh{Fk$84z@-(krT0b78j(Sz>Lr|pTN>& z0SWOc+rw1Em`wp=D#w$DEhAXWBUmw!LuHOwMm$D9Kv|AJ)=yUwxf;QaB)2+e5-IL}h_76&I2on3CK zuS?`$&T=#)mqlP)3de9~BBaf_41(ZNbOhzDuFDVzzjK7bc4b71Nf9rkaYWc1uQ=`) z(HR4g!E(4H*k0hVsR-+H37${Vfb5=t=p{ajp+J&`!jCPcKsJ{_*+dO2J*t>OK^_Bw zBn?J6oS0$-0tOh;)%ucW5?QTz0$z1KT|>oHKRMTtLSin1!?Y|^=E;PRt$~Rr6CkJi z7)c7B!$ z9s~FJ9N4FqK(+pu~Y zqj*t*e+n_8x)im_3-cOn1izRbBpa}kiFMZlQI0ZA-5^a+v{acN=%CaD}50_WW);-UbV6~%}= zF06P4F3J#OM25%{GThoP9(*IfK92(WG!B$K?iTSF2|;B!96Ni`En+hgg3WR`cIJ>< zL{13^aGD`-_4926HzA<7Ne1HnDR0z-QTPs@stGdty;$Sfem-22`AZ(I36)&`evM~w zR(`W*Y!a}0`8{An*BdZu{PXpOrA7RFy+LU) zq#{y(zTTjM|2x0lfNIvwu#_|iDNeDw6NnCX`O1!}4icss7*%g_>H8sFJoe!gUm205 z=HrTY`yI4I;SeujAU$TF66_d{G4|Ae1E!7jjwYRVbo+ zy0TGAjwE`?F-tGGo3IqrI$c|9yX1Tl!`;sJXM4ikzn|NgoB5SGV;&EraZ4C zB-PdwY`V56sRTp{hAL<#Qjzk*U!7^=GA=5zy#l zE+%FNrd6Dc5+ki6ifAw*I;y&es(3+8L-a%evT!EGJyep9Hv%9K^*bdJU&hn$e$;3d z-_6q?VuZc`u|J0c`w&q}8z3R_G0-r9sq#Ek5bKClxyNRfXeRE#H1c#BkUpe%wl7>H zEx)5_U4mT43XVZnkXbYvaeQnR=g3reH>nR~&((D$)Is*nmSZRj2`8 z-tDX=N7tvSd=ap~Th}lKI(Gjgq8%0qj2S|HKi>av(h28)e41KwMKI{5nak9A`6a^x zK7+z5%M2mD2_s|8NtDgu&^3k9mf2nr*zFVHnJ%#uBFw(un$Bl#N%fFt!HJ2ucQdh} zxq7KBz{CR)SecrCJad^xpyLq^KTl){)_m=-YS8&`hr+&w{D5DNM#~^CHPhdJ{u9zg z?e6#;>Avqr-7ABp|nD!`0?apJH9?|CultW3s#y*RY3Vy zkg+cKP`Q#P>-!E;!=cy7+oL)y^8(p9U?VdL6rnV2YzU&xZ4PmXt~k>@c`O+GN9B25 zQ85t-I7qAoesa)Wj|2x%RBYr4NkWLz43)RO;Ah*wIbYBe%(`zxBMDNJ<0SYrt){x9 zaQy7TCGw{vr1H}Yj=cQ4!ioz|OM{t7ybV(XN-{L09x;KFR1{j~qL@EBs&`lKW=Oe9 zNA!NapOO2^#q%oP&=72{BdjczX8|8VBrp4(hOAn&7bLHV;ysvmHDp0=62TLT(YpAZ zWm`$~PWXWw3`S`nawc85N2^~sP{GL}w3i6?URr#84r?h*RRyLbOsIyUibrQYc*(9^ z*ewzwG?2R(5aUrrs0#@V+!NmIlOGQ>a@Fq!Rq%Fdx@GWsx>g5T%SM;U=Mq23CkY^> zEeVjzr9du;1MzVnf((4Z@s;6?Gjx-1Ot{I(Qh#g;nXvr!dKaQHC!Egj$t0_SSvP#IB zBd3JUp%#v1ez>~CD3Z`Kp*k6jP2Ch^0ztR1lZ(;m*NJgr%2=MN8!%K~$EyaBuA-jd zN<^^Kj(9x!SB%<~u_b+l5c00DH@#w~7W7U=v0EFar#tpKRTsFWs{u_f z@*JC@kCPXo2`(jd(4Jm}h8thF?L%&tslb8Ip$2Ldw&qK7su)h>q)Bd7ERKt7`2W!s z{0ycsSlhw>Pj@u}7v^cKf2ngy-RF5=p=YO0d_cQ6LNVH!L)IVT5bt1d7^ zma2C-IeA^fMy`rCI#c4l0;)!1Mjm8zjLMcvy;)fjLl}CM2Kf3EC(!pQPoJVJQHpR~ z8K(o1RuF^vL5O74#f8D9N3>gG>eoGU-_lgYG2&3fQU`VK5R`!(Q4he5ci0?J72t8^ znk51aLsq+a&v%DzFXFGlTckVRWx53P?4o9bO7LDv&mGru`V~A$7 zX-?YT4&I0AA2-HdO(YdGd*2R*d$abkFF@Q-$;Al6R!7%{l?0t>A4dZ zd0iIWGqWii<5s^o4kjYPwGlWbMaYoG!F=ddsau~#V0@B-l5L`pm*VKH7NUO&P{<=d zAx#6y-Yq7X3@dlTm;_ZL45Si%_$e597?p7QEDGV%vh|`p7!xzKni0<}$)IV33V8%6 zq;a4^s5Bxtk?=qU-oPBS=iCh!+=836%iIRaUa`4QxlfFh?k9Jvtg zi|B%g;EOyiVKqmdZAbvZI6Mj$!BQH6nP%jnlc<}93j``IWaM%4543U`6U8^~{ z=5z1+!8KRj{wLR*83Y3;99*;G(n`J`+FIYc{LRQf6}AT~vAXl%iOb)O3{*9cZXS*k zxC-g00-z^WA#-ojrI3!Q4)QPX>>OH`FI*&D^65jkPVkuPMCIXBMCI zf)hh3xXzV{49)3|fk6ONR*JUDYg~V+L!+y>$MH~nz1Xq(dVH}m5M;iF|9L_U)Q*1i10PaI;NJ)U zi?0WRDgKBEF|7dcbnRd?If4(-g|p-kjDHI*BTL)D-bj)LKNzExqW&3Ti8=U@Vixp# zwq~pR?`FnnjALV_KRZg~T4HlJ#D1BMA{A$m>~W#KCxt}nQDd5aP8#3(rsa`3II3Mv zzZ{68j~nth6B(C3C$;ilq&^}JA?HZxKwSfta&Wvj1j`qN6tGB69Ql~2qN9!y-RjJs zk(Q&}lLH^w0iD$Ka=UvyPi*`t@m;%teTP9_E3jXr7kPfJlrn!|r4*~TKITi$C@jBD zN|Em6GAXEtB)I^vt-g*$QVR7@?l9Y;^^OL|W=%a*ZQf1kSF%823kVJc<0q1Y$f%8UWJV@H6%L64T;8n#K-&>I+;kvv{U?NPAE>7u8d$oAHwn#J)AZA0m#dbVM4VMI zodzP|H)rN15ZSr=qk2BP!6Q555N`O1%y&Jj!*QvPgN3QP38;Ms(>j${J+Bj{pA&oL z&rj^Mf~#hB!r%;e>8YJV-N(6|=!i7R+*7ZVq5}-=*bb^--)DO!4A@<+b0dho}!y&ec@I=8>;L?J>NjCR~`of2N zMf=#hURonBgD&E6L5|V+U@-gI%+~CGkk1YdA6qj~A75X7X~()jGG!eOQ}+h2HnvE= zyb`)cRd_J~!Jc)^4L{>>Onqhker&sxN%EIPe40g1|6mM}Ed!~WL3JOPv<(6m(TEih9Fs`AcKFHBk|8j1s`tT`zoV6%up&lE zLg3O2jx0y$2w8i9P!E4X?Q;~1Pt-)Ip-q3-J< z#_5POnMI7R!tO;31$!Wi7+<))ix}FrWWvlZVkpB(7BOO8=U_0bB2i^z5wuL5HVrXQ z1yoC%g+yO3as0Blm>Y0Qj;IF*n*mDy?<_QA5@esG0+*aaReQ7;iJVluRDqi z)Ip$UDwPs%)>KrWCG1gsSBr7&JAINP$YH(t0WE0VSm>)LG87iHp&sw=vMKn#I;y|`z=!0zp zv{VGnCg@;vAm$M4Qf*Asq4@C2;e5V;^cgyA#lXuY(JU^E$H0-2CWe3FS$?s^&ewrPzU4^BEX*xf8dQ<>FE(S+^iVl?yT7o%w< zS1m^q7H9KIFGwZWeO!_zS|XLQC{3%fyeyS~4`5-M7O>CKRJL;JfhwMfWLe4bG#g!X z#HpK`Qs2Yvuv^(O+@G7uKc5Yz7s@-gjMB9c9M&!qzHd)abdl&d9uP8R_-}3og)M=| z54vw3-vDKTr>jlRT9|pl)KTfC#c^{vIvD&n%i5x%Mwe@Lpj>=q>5b_j zZ}6SKYTFd`lxfLHS}e7_-%(j;Fo)eA{?$g!7W_8w z7kJT;-ViQbIKWQ^8|+-xXOfxA7J zeKLcfQDgBH|8aPB&-nO&6cfpIJG}UK*WJT$s>1pF)w4*w7XJxquv}?02I0eC z`08mEf#r&F9GPVrlmi|wb!F-K5bCe6m^*2g2Z#;1Y1SV*W-tsd(e^Mn{N{cbeH_0@ zJBQV7k0x2P(}2QdM0gmhe}wrChi)_dbdKAmx!$&|S$H2bv(teYZStgec%hVSMlvzn zOL1sHd6<*gb*%K=sqyF9tHq*WewSqlexo`3$r8#I5X}`@3z;c z6%UoBfB~0|Wry_T5G}93&3Vp*os)13;ZR53kfria|C;eY7Uzk@LV*lgaP&${dd zGdIj!iGl|oxdo9d3U}nCuE|PZtY~%J-^>+l{XqJjB z{S07d{z3pdt>(H2cEaO~dHE2wM7x(U>_kl@(}LJ(b#_FtCFDa0W2Z&z6~~rMO?>D~ zAY1aRB$931nvd=H`n;WNntJk+s-sL6z>GAU)UX_C2-t7{=}G&snT>G%J_76NlA`g{ zh}#~Ire-F2dpbWbwKp=ev|0SYyYT~vI2EOqS>1;n3!=m4@b}Cz!9Gmu=VVo$pszc- zldzfDSqc3Wi?M9YoAPErTu7T1xtc6Y6`;oM`6YMuEmOiW zchJQJ7H!x01gc#1#VJ*ZJW9}__76MSBvQtaE^vJ zV|pvV%rsfmC<{XDLcz)_v_HAIJ_^PX>bz}Q6uhb7AFoOid}AQ{6No!4!zrV(Q{P6Iw`4O zoj_ISWOQ~0b8q;P!{RGTQdM9yL^jK*sD-0u?gCM096OuuW6A->9V%)evQR@)urjqU zZssQ!5T^NPY{Q)}%{RS5U(@>V2|#=FwLQN+oWPae3J)Q}6$BP78Z|YR3U0>XBnAc# zMsqXUo|Y}Vi@B!E`DZf*ZteML2E8Vcby_P?$;c3XHr0JMH($4OHOly_GmT zpIMi2cXHaor!s-nB>JDKXu(9p65gCZv=ZYe?3wOwAl+?M&^Py9QijPn>5fws2YZ6s z7i~Ll0K*t;sOO?-=h$kNc3}a9D$lWFV8s?CX1HnuZcf8uT8SC!<&!LaquN%fPgMoJ zYhi!-^ea@#;0Mmt6^)qVs%gdXxczP`=GW2UqP<$gKHudO7I~|x7XY*Ys#~lwGF1pX zXs_nRI|$#XEiEV#QU_jGN#J{}aeZIgbXm5Fw);5x(Twf6d)x6AUs;kWlF>Lpf>&>` z(0h*{{thG6yAiHK>?*UX={neJ+7KcszZjFV@uOn!#1C!;|J2MW#^Y^lMHQ9IaMkFB zEbp}MK5K#)b#384j<1Xp{c!-kYDd5$B~Qkoj*td$LIAc}j3@3RWXoi1PDeE-cq3^a z0p2V1E+cLm);PO@G4zreXBUDxureN{Q>5#M*}$ z(Z95FA7SQ+sxU$20=#H1bGHM8bmFr6n5gXwf1#)&wrxSb1=Vb1~xPA+=6|k?j&p~b zIZCOFHASr#?UdoGC0i_}W@4Ico*NTz3K-|x{?sAQB8F$>N?6)1m*t|FvPdMCi-W}#+0({>KTV3lct#Y&a=4Jfrg%hG zh=>FwH(L~6XGwxm3|3o7x>AI?J@BMJWtOyfWm>LJ#fEs)Buh**$kK4hz4yeU9(h)x zNS=smf}>N9t?;NwmXqj_rBT(W-vDP?D2!YQg@o(Swd);)vh*k_%@Bp`-sL6*%MsI( z*up2flS?PsVzJtqpy3@MS9p-@X!v2o3cS>WJhE|79%YB#Z?G71Ng zujHyCtG2C~P|m}}@_a71YpXhn6O=@h$Wz2%yXQ8j6EPZPDomr`BD*)KqtF~Jk(wjn zV#695byPO0qtpy35t^Y8MJ?`ClVVCbT0)u21$FLGM_D;iA}~iHidWifR-3cLKucVr zQ?-zTM^?Th<&q@@m#J@BM?q;m!A~;;Z0CkG5s{;%(sDFhaQC)#6wEWCIF`eO)NfRi z7VF@lP1ixn)$zj>Zux3E(NT*GDG{Eb;4(2=+l-E~7zvTVayT}G+4Ozr2%gdq>@-7z z)^?s#U{AqdeKH5tcbX$)%qM^`k;8c((R*v!zH$T?)I^5J6V*}JOD0t!sA$EAOihTs zlbnj6G)w@^;_y&7u_LV7zD7s{srjODa@)wHMN$&l9%+t>jYC^z2bsx`q+FJy;4%vv zy-}JVB636?myp}zjqoW2!A>(|b=f8=@9xq%<5{$}SRNNv+Ru$5Bo&b%GZi7$8!zwX zCi3zOspvc%*Mj*hUE8`*n<_@4RTVvIch?u%aXkk$atHU=t*q+n>q!3d)_Ug8-&(ho zT6I|+NnIaMX=?7MN09q?H669XT;)c(t*Y`x^a$_(?w{KN^|^K)TQ5D~!uRzP(v@5? z|7A2Ene|p2O&w8kguzqQoXIh!0b>@vkPf=~-zu)p3}>4thYAnQ7`%WouTz|p*OXwV zb@Tn&DY!8Hqyzdh@T21-ODF#uf4Z}zgmE~LVM!f2*lSg=R@5!a($!QhssJI`e8Fr4 zKw~zG@V@-1sucjfYAlLchJ(@M7}gml*w7vKT2oqAMV3JaAN;5XPiecs-{SEh?`w8l z_DHGS{Ns;RmT!9aqcsokab&DYFp!O`g~Tz=HO?b!hEVk-8^)=#s|x(0qtTA@sKpc< zuF$SamW%Am1Mg|k5m=j&0x_J-E7)cvtGQI?srlPv8twMgY-VP9*y>;!q;=Sg2iNXk z-pS~)X|Fmit0)XXb#J?xAkz!Gba6W~B@#P?#&{_l_A9+?2|O|PcrjR9xj2pS4|qm~ z`3F3Gd130(#l-CfE1)Qu4nwrE4iaW`g(7DGPUZdi@${mZ8RBu~kT33pz}?TZG!1?B^F&g`ycX$R>v+by)yP(E69X$cpGm^2ss3@ub)vnTCd zJBEdv)zeY;=@{J=>Dqem4L;VKUfXkda0V3x+Cwswpc1^7A^G7bo!xv>nek2DF|c{l z!F>MRG+aLw?Vm*$wwD7is*)|RnIWj!&PM-YGrEnt=AsQDz{&{(fM5B3*5@DfCDy=1 z0<$5FOYrO3J_0-s!S_iV9uvX$&*R%cHlha>jz!m+^>CDnC`^;NAivi7lONg+`fX%N z+qrHk)$Rrt=cjF@c$lToqinIpN%(A1j+d`aBr8yeijnITQoxwW`PjN5^0*8^pDr>8 zz0KhCT`P_Vz$umbNtPSX>^O4pjHJSnoIGT4IiLY53>;kq4mmu`@;I) ziApvlV)-NvmJe%2I8H-gc@~FPLU|E4WTpe8P2)(J*jGej1au5ba|E&;_#((D0Yy%8 zMCIn9UZidl5?ZrK21oAsEH>dRMtCBQAS0+EkIV4J7M-jJ9PNk#RQ zxr)YmH~~7Dl9`l8=S+*I)1VrE#ul%y@VngVjWT;}`3AP1Tfdnb1E|5C1$~?x9ZS>|hIYy0*V>i4KA&dekMPNw*`!-^!WjKd!5I8PN1(Ag-(2vz zLTDV;`|rWwZj5&qEUiHA%Y# zPU6$!Ae-h|(Bvd_`USQdO zM1)Mx%Na^HyB=e6b7EDMI9gKAnWtM2EY5GA{Xh65si?_VJCKc4#eWtGFW3aGn^0vv zxL!oC94UwJv)-Q^wf56nRf~FJ(xg6#1^vWd3~kBUWxz=p&Fjn_fEXkpkVvkVnuEDU@(Wth#cjBL#W@VUAd^ zJ|T{@MbjmP;+Cc4D+z79Zzkt()WDsrQ7G_JqumjZpqt+nO%fbO)Dgzzgn~SjpQNj+ zEqLFor1Sn94meD^o?!h5-pU*%slr+TG>wFHkFFkHwBNVP;v%_?ry>)|I_UlRr#ZaQ zFdmPl^LErxLhn)B?#eqmIjcoZse1(yZsj<%_^Po+4l7ZE|2g8qV26$f222!kJ8q5?w@#JF@Zlk;&C-)bX2 zbs;f7iiv4?5g%vGDLxv=VX{@6Zze|V(p?Fk)fpjKh`M&of6Y#^+L#jj*fjgLGzHABeO^+LCD zPU`T1K3fs~nJ+VFglSIJg8h({g|nntz~jX=G}+?o&R~9lKeDKp>re^33XQF7-?ql!ieByc7fNq+l%Z3_Q&;Q~K6J%XbY=C^a|@Tcie_NRu6{so4}D&j+b3_M9h?=91|qS%b$89PCm2+`58fIVgw_pTE+26FReG5%c@Q9!!|X) z9*Dq%k|2{*4h=mz=le(4Kt(`9nt+T>I)cWZ1dt>W$e5~vN(Y%C1_BNmGPLp+VQD@q zeHPT#cL|nJh_=c?S<~DTf8An!;vm}3TBg1FihiM*hCqpJVHt;f-N(-5Ex}tmpn>fBm|!2 zaO}J{9>F6G!HtOsdDmM#_#jw(rFwsI)CZ)J_=p=SUOhLyaijBx9)g7cG7r zSYXrgo#4i4*`Is^YPVpw2QyUIX4cfw?u~xHS1mfIj=#b;fE2n15)V^4M6bwL@M7vZ zTkvSQ!ZmtdiVjiC=bV?{_1+bEV?O82_O{5JkZ}H3*g^-4SZR75tk5YnFw$8AnCPgH z(PeRtj$Rx2^;@5M4~|?kUy9E3X)2VF2>F?=PBdT?96=5MkvHZE-IW1>s7-Q_^RAut zy-_nBLW><5b+I|`>cW~Px!P%0n14F$nLqEeYZYGQv@49x%2kdUr#%OGADwnZSEN;( zcCCubPJ0gg0XXeiVf#4kIU7hlD#ee;F|P8;8}Zy2K@hqIBRu{qIRK2e!=#ED6jC8` z9xJa%{V^rKVYAF(DAW4Yd60sVeQ2p5+OBQ7@H=Vl z-imrZ)o)#gbrU>N)ogH^Sb1o!V&vgy zH`+q>!`#hxvQa@Wlzf>qxWJaJem8m*V8z0S^LAm|k+HL#1DhWi^Aas0m)moz`0f`r z1cZ-N1D zj@^X+7gHJVLAmS3zZ$v(jG2WdhS0Ruxp%!YC@`aq8%nR?8M_0LP5;iX28O<1K+%vp z%N`nWtEBatM{`RT;==J~hlsmb_NB+fmb%$u7fP$V*P<`Il=|sv#S)*|Tm^b)@>Am( zkngo=pX!srgJoB&8!)srPw*~_+kns13x++&^~Kt z_H(ka0_rq_>X^4zv(pZL37{ga!wXB{vWpm2#$5p&;yirLYoi7U2&+W(E@6LA&nYp% z68qx;m&77Q(jSsAb7VS1l!4`t5=GEdE+P1o1^DjaOD$P|mi0wk%%a@9i`ivETcV`8 z*BP0Ue9r70(bZfr>8j3DDVmc*)2dIRc&Z$V;s{ERK*UkFf7rJtaDD|}c#TWQ5ExvJ z?oURHn6Gi>{L7S|QfVkTuQNrVR2(Jrgp4m5ku*wmg;tmZ*29gdY?_c0)wXo*xxNEXwz2(09O05MqAFsh=kntcSz z(BrU@WhIeV?|l4xJI3}my`0yLDPzZ3nH|&6bw|}Lq^&r|^R<15+sDEc`NGf|}^uyX+=CnMr;DuMEE z9Fsr;1%>Y>9AU-vi9{gB&mctRj|3rX)z-!zklLB+O+pV5=blC#P(dW<8E}Y<4_}7(w^zgrg2gAHRA`LHt*ZP zFnQgq$nU<7um)=dT&ubS`cd&LY^f=X5tu1^c3s~dZu@4wI~* z&{8@?+lr-pAwku&D^kShcdjRc%h9Q*5J#JKxRki&1<-@R589}FY)Ro6vBUR+mx&C z%*5^CyCML8Y?^<5i}ac@Y1tWrD>~s)%ey~^!Du!ytIM!VXQumb!nx?h_+m!tm2^G~bU!0JJc4#8{7|?l3*8k~q@F zDPjEIz8Fl-8#`gm&F}O%hc}pJO);4=-aNwBBw*Tw8X^N9o?3U5N6p-Lom^~JSQZ}AhPqhoMoi$+=+pxYGow-kIdsCOG zZyrsqE-{(bLWO`+c)Id3ompXA|=6cn+1Zxebtf{MD3$mUYoKU6%7BsRUj%cz*R(^YbV z98v85mE;H)b)^JqU&`Grs1k@`P_V7m5BcQoGP?GkYg9Hz-U0m--Zur46>^85v84Dr zs*1dr&gNuwU_X_2V4eC|87FI7vBULGEVt2Plk*fDLWkokhv2Y}`dHFjwij^y!&Fj_Q%QTX1<&v=y&CW&& zjhp$xW?VK(q8M8#G|tu=n>Fo$yT>gQcPo*`-FoBX?i;GGWQaGm1o7O-A2BjviP7I! zlC)R0Fkkmy39wRW{H-^X{i!D*;i&F63m9oS$t0u{hn|EK6#tlnEcu8@NNHNsB&0~q z^K|qiq`~L!aS~D}NE3uiLK=jBfJsQ(|ENhwD;vlR;GTpuQvZP_A&)XQ2*xm5UstO4 z877r+gM*>GPRGDgt2uCxG9pTkY~H|#ur6)1TIGQhCGM5F9}u^Ped^71s()tsj& zaoBLK9UaITes(*CJg({&Hq!T+w4iY5hv36Pb~EaC4z&nNJCBp2PiJB;vrCZX1s14y zin5GT{vd-k#ZspT3PPDj{Pi7e~;0hQjsPJiT^CpKR^Un%n7I%u#h2SR&YmwR{Dd) zfv@x3%_hD5Y7CR`go-0nn_5cDdJ?6q*k@oqamp~0$OQ`KW2d;Qr`-~JfwG>K%djpx z{)0q+$}U0ipKLI_c}zB+RRM}K3#rCed#yFX+EbgK>FuKb6>ICc;%>gM1(f6!#aB&Zlzc=eVHz0~O&BCRhern#MP`4GF@>Qe zO%)PW6si9Jk%cp3pn?lm{?J=YN8Mi}IY@|6Jqn}srLAp!kU7igRJT5ejEVzS7O7xf zguirAvSVj{50b`cK8Dfc--FV#$zeaqA0(zRGGS;~!xIhX>=-%cAdP!8sHmHB35qSRu+UQ5jFd+ad{knmK2Y|HT(pY8(nzZ-BqLr=Ae7-L-3&gW8GI}-$iHKV^Y1nx z%QpyGmXMO4Iu4#}((k0ne^2sfN-v#0O(L7tKsc$DasY=C5#RWzmp7~G} zOCnlugTafJ!Ams*ewDw62~APW=ykTZe;{#yhZ9Ru&8l#PzmpqJ#o2jBCg0P8hDluy zxfNP=@Th#Kb(c&D1{s&*pmmCzEtbohO}g5yNlm}HC4L&c?A&ItlX6Lr-pLv@;^`Uc zwAjI#EuIUmNiHw(olM1fvZRdRAEcjQ7h_=!MHM-MYBQD*Q&s3Ji@%Dop0&}(LbNJN zyGpN5a~2jw8iiZY(8n4b{cY2l+*B2H_s9wetN1I54IWNMMU<1wc; zLpDb`8N@o?IfFy6ooIc*`r@}M?eEugzp)3<$I29=Wq$h=QvHrg_R*W{1IYtSd;jv* z>)RAU6_3yE?zWlTxiM0_PPf#iH?R$-&~q`8TF1?K^w&>>J11@Zqd7)bxolV0=mHMz zrw`bkSSL)LHP4~2z?Xu&>SFtu7Nc|TU^F{1lI2BaQhROYAEZlRS|g}Kq1%k))Bk*e z1390v?fGN+Y~>7Ut#kw7q}=@FS$V7K&etSF&hIzrBRjBXoGx#lmb8tQ-DM(0rgAV+ z94;4dYphm5!pjQtS0_F2*mk|w#N?vDRZR#@! z6ZR%2)wz}hDykyViGzHH%CG8!RW~>b$Pdt&d4cgVD~F;vWFN9JfRcU6s&NWOe5CrL z+Dn_xGLWL-FAC{R+iB_93p>3#lu~5I`+|9RC}W2m? zHr|&J)1!NfkygpJ3!Td5=!?A+hjKU~?|yQ}VlY2jQkrG9w^`CM`YA9nbDkjJEbSBv z@Tu&sSop1%*3g*wmI^)f0GEt40PG3Iwv;^du$CnG$B0(RM~rAG9n& zQMSF6L4Pr;sdihvw8`wOr)b2R0)>?kH46U5rl48mlPi0p6d_>ry8yGzc#|e1WjSgLGR)4SaZ(K*3 zCUo*mr~QM>yjj@+J?&=Z3cUq(G#oa;LBbez=9%D5f4GueKYih%|F}VcX1}drwyp`+_yXVTezmF09j%U!;CJb!+Z-KpuWv-$7p`wN`8d9~7? z+~jNZi*YXfJTvl-8gu#GGqg(-RA+s1Yp4ghJv>ZcWGJ@+Xf0*r}1g!=6}^ z?Y_T^$Pl0^ymAx)6+Re6LXwmf2SsP4pbUOU?7{GyF!W#o!y*q#^N+xz-rKsSIow``MRC@8QNMn~Zorb;hL4}f63fJWlH*jF%6T`;8V$JFt5YrQoVj9i- zN1fKDnKoUe5Lcf%eid>f!dOoFk7%~!Q;cSXu>*rzPR29;0b*O7;ooS-a6RF4kv{?6%jz>JJyP zaTgsSauYdDG?7&S9HTOQtJ+uXt()+Z%h_U)5ldoob2DO&|KxMLpDklRnV&iWnDKo4 z89<$&O=xm#79_B}3(k?VbNHZ=dMS{Qg*1M1c zP_4F=5%i|bQC}OW53|C@sw`b;hRa0?TN}u~h1S_m`S$6N66-hhxs$yk8HrSJ*~Xvp z)h2&hL&sEDflR~oUIyu+2CubX*T`j$m1m=2sC{`WHGyIQsqkrnIrofl@E?CST7)w zsHAWxDlLIcYm}BxB^kWLY6fj7V@-H0e~@#JS^q}RD4*-5PF#4XeO=n2Z<5Y z#hHY2N_Wl5iqo53T?Ys%mIr_QZp~~i+Ax0*SV(>@UKgS)Uwr-fhHsame`$h0NN}Z` z9Jj`cG?Vgnb5gCsh5Gm5Ba@+5BwxWhuOZ z(ME8EGmXjrW*+$EY?p5CvmL#bypTOYcsE_l(T31MFHf13VMtYQ>noBfma$Wnaw!y4 z2amFgIsN5VF>MUdcy9deXG0I8UVJ88kY|Gx+>H#&|+Onjj>?GYJ0x@ty5|RCH%$1DOHb zv7M3nu#sKmMVqV{iM!4-?2=Bl8(bw9A&$Y4m4gbNkSK)dD1TbPo!p}w8k)kj`Wj~~ zr6E8NIoVIwa67$eW0NhU;AdtD+qxLhOaPbE`{A=>K?X>-*@umh&dHgl3t@dR_d~y! zBY=}=j5HdR>ak=&+HI$g>z%fx!IkJTU32#qa)*)bRhH{}1ul%=E`qCddb9mNA-?2a5n0S1bg1YbyYIQ>ADt6(*4+NNG;)IC=yk(yN01P+G2Pas$|tHU&B^T z4=?h*n#rs5@iFzXp(&~veb{DW(o{p`ROkR`+(a_YP^5LToaB(S`u;qb4#QL(CcC3M zd#et3w$pPN{JLExs&nr?qvz1`4u$| zOXjU{{vbmOBE}HbP^ta%HiD&lyBFycFX_2N1v|<_1dvF^?MS*a5G!kjbY&javGYVr zvYUtQQ^(w1EaId6FHtVEMT&&KvMF2*lOj@YZ8~p5r5L!{FUceDN@R`F4&f9jywPak zr%mh()f5NqwZ=$$YV$K#no0Q3U=8YblG#ULpj!sGq zX^PNI28!|zvbn&>1gHT@J1@vw;2xnglmCH+C|@n}FX?ieE|*`@+pmO9eC3Ii?octC zsf})*By@Hsk1!HC$#&^tnau_I0{=fq$5UpVpq{5Pg*=?}w{)}S2K+))z24lq&oNO+ zCfl7m36oLwxuVO~D+R1N)|HBP(KCYJ}^(74wA%K208NRWf6Mea0xMwRgpMD`BX_1ZqxLe$# z?4Wu+o;FQJ>VJ@dBwx#*sO?lXm(rF|u`rWp9T@Y4%{g%B$k_!_jl}!xp5y=;8T`-x zvB|di(}r|8C}$v;@0Kj$c$eP8C7yq}OxM3HRSkxQu~~b-wdy>*(KAA?4Qrlt<6Um2%!Telt(JbSSeLCZnd)@y_I8c zbd9aZk>CTZL6xz3OoAEpgE;XV-jftyii^o#$k#vpSEE%Q^@h_?Qg3zYNxRjXC8K(~ zowWO{!EibrG-u7`e}m6~5<-* zD=5PsR$o{7cNm?JVitES=qL6fNY_9t7&*LWK|b*-2ZZR{jk0xttR}?`6~FfFa9iv zt8*tE`xD8}H`$K%12vImVJMXZdN67fyw%g=yPV{IWAQZxnj}PtA?hsV#DjDCLKFm~ zD3cf^PXsoIVF8Q=f}M)b{vD-8={N>Ps2wp@iz^M=kP-`_n-J;AvnCA>C`9%(21cX? z6>>qffE-*LUco?R0VV>U8krHGlq^3gh-ky0Txa(XX1>W*_q&JlE&IjSK(nKb^rP)D zFb$5MbdIvCyV>VZt*vJ zofSrqPK=TUZVxOiK!V~u%2KG1AOL{usQpArGAR(bLL<=1f%ep&Gqi+(*@7;oc%821 zbW=xQiz-P`qUdjP4+>I}qC^RTo8I|6w!R_{BT16t+$NK|*7B9ROOk;OK#7K>CfUW^ z_W{6kVmv;bio+DEXZ;9u!XTh_I3lDH-?6|{atth+c`W*YMXGlcXmSk>9+{r9WTfFhH<(-QsFzI-cCq|eW6z96?(tC3rhIM!e3Hva7c0a6YF+j4Sar z`_3!G3;H))2gy*d(sj^kw##%)S4+};t~tFg)L1S_S0=*X%*BNGJB4-8XP@eS{&TDQ z@34h!^4rz>iCR1Pf7RKiQIlVr>T64VZL6;x^|f0w+4R(_zWO>)Ux(`JNPQh!Y$oc} zRDNyL)mNo%L#f+nnQR(L(MDH&RXR45jt!+_V`#BaiZ;gTtJ1Nd={S>Ln{|^-Q|a7P zIyaSFn@ZiLQn%T&*z_S^5I<}Fr;F?4ucmWlEM4N-Y0ui@=B$@YCv8|9JL)BaNq3e^ z+nqtTGnw^fgN|#7DyyMtOTb*Xac&No+p{)>^)UXLeSQ%ieXNNL$VoHVpAQh2W@8^$RJ%q$rmI9R;@a zhvaVd6)8bWUe5kvPVBe1TTm402U3JVP%cD^7s}U#d&HO&<#H~wbo&I64*-@xX}^&o zzawSn=@I5)5i#vGiOI+S*Vt^lGH3bi)Al`)LBdbk0pVRV`3Nc0KDQ@Xo_ zArOox%;H**MXMgyqFPb+2)Py2PGL=Lb-fc?=@e@m2PU4#0>hvBvG7DV5L%y+^&bo8 z9K+rw-eJYz(^!5oSh^Rj${dsB_nUP6u(;&_f(={XP>o#7Vrn|?(G}NOGU$w@4&34E zN=<%Y7k@OBLjD|3st0JzSXG+_mU6q40ked5N(IAEqm=3J3*X)=&4OHH?$jg1C?YGD zSw`p=U>3o$%r+&Oz=pxY`Ug0MI;d2Oy*yOVB*aBxANFC5Be({7i3FIu9A4k1<@HS1 z^sj?)sNXPpsal7Ro>n`~r&Wj#FBhvLnayMzY&L{mF=q2<6=Jr@3(2C3Tgq#(gwt?c z3P!eT1?Hi~!)X`Q*7`nS5TW-rtb-`YT*oskv+Q_4Z-F|bO5GHb{f;0{7$--Q{6e zZRe=J!%5arhVv`7hvD361sjg8 z^*EB{6z?e0Rj9Uy?Mf62HXamp$iQW$3k+t8jHB%4)he`#tI#RRWRP`_VlrSHZL(6W z_A^;Qrzn%r9D5X-QO?muE7xm3s};2hHX9h8?fG`82cs(?8_pekqm1U)N*N8aL%m9; zV3Sd+U&As)mvZqYlYFC0=GQ9LWNw{;O$IfhaTM0ur_c2P9 zi#4LEWDg$*7Deo1&niuoRYOC=3O$jgr6iMVd%IcCty87uj9T@eF%B>yN~hS-Gp}AD zM!WvHSYNHK({HeY)TLo~CM@s`HCm-kq1nx^5z<`ZJlB&P4{Mp`eKsduC@)5tq=dzr z{Pyc_i`6{;ehyz@FDZ>^`1c9}7Kwqtt8MdqL;pgX1CrR&swPVS(Wxs%wMs?(a<<8q zc{=B7*KygU$h4-j@u&lf_HXici|1^44&Q&5t8?JSssH$>ett_gXKP5OC6Ui$I=`L; zX*DLL#yRu9AAJf#0>Xoko!jb|sxbAanBpU>!UbtUMW(p`pet+^M0kCZPqO<>mTeIx zp0kv1R`*&u(5?KVlchU_EVv$Y=qeqg>7{-UY30Z{A8tJ-E{E1muT|rxTE-(U)z!d? z_BqQn!jPD3>NJlZ_5uCw(pP2lGIL;D4=e(GZ<`BY1=FJYxZl>-^1o@Cas#}|NQ1Lo z+)ftkg2;1Hi~Yy%4Fw8*f3$x8F4rFN_i8Poe1XGLBA)0?#j?M@H~H^oH4c8P1q=Pw z`SNACSV1&F!{S)Z}fU9}c)Hjk#mJ>BiFmkN|4=T$C$IG@w-i_2y!P(JIcSI+p% ztJYwv*bk?Y6vElp1W#SBLNM`|e`DPecPOmOE=Vk)#>s=*&+?}o+=^Zrh-0Of^QzQk zxLnfY#uAJYS$bNxqc4RjuA2;W6l|*d=r?<$R7vjrb&i?D|)y?Ot zH`C#Vo2&D8&{Z5iq?>>K@2h3@Yr0vas~zU@I(n02wj#aEl;C@Tjt+>>pB=L1bYiI) zDmW|Ea?8MO_b=&|p0fdW1d&9n%X~l!QDLxi=4$hAPuYf8>0qo6YuZv{)Cw3dZ5J%W zzR8W9+)|^09*)Fbwp5{rMyZ6l5(W)Iobvc-K|%5h-1xCT6>40p&fjI5TVfv>H&zN$ zG!@LRo_68fH6oq8S>PDvcbn{6Xzo;$70lme&#;X?f;mu@8-^ag#j@mU5^Cog<0`HK zOJ{PQ-fV|?Hh1Ub;MSs?X_a?~pk?^csv2!6|Lbg5*#FDpY)9q8Iit~^}s70nx{EK-85qE&Yg=5R#aD82o9zk##!-Vlb+p)J!<*UX_0ikrvvK>jxSK2pc{ z9p-RF7vs`%72TRlpUVox-ny8qJ?^5dF)Z{0qr%@H_mog0<@p;FJEhyI1htS4C(G_UJ_ongo*7_y8<$2| zaVu?P=Sl36niOJ_^YLsCGrgv;amdAn5)bRv>-T`K>UR>BHF9gF6v9_x;^VWnrX_7pkY;CsSK+P z^7=j;szWVy%(*L*Hb4baiGe<^xTjp#?~t1xl(VFmwC<2jKM z>oH9Z(TYT6q)kvBf=^XG`sM8EX$OQP-7!br!Hri0HRt-WWa ztYP$p57J53*$y-l+tK+LTZyNNGag>Z)w~fCM!6@p7?Vi+uj}3!KI)yv>H6g*Vr{&JZSv zRIVtoMg@_epito5I=9Z3*`1tgB8?K(c^M*$9Mz6`IzB20<8`#|3GjB<-Z~UAX1ymoq8cD5sSMke%{Tx}_yUYk3G9jBy5hV?iAq_{7OOdg zNwg<%ev>b=4eVx7{k-Sv+fA0q(S={mUhD@Tzx)F=;qwf-(TW0|y%^8JGi8b5HKA}# zC`z7CQRD&r>+ug<>f?0}Paw!|;pVe5Y0z>0YO|R0d$!FvW}m9Zkf6~(<$5ynHQqp=~8hhI0%gpc2;Ua&x()OMs{ z<`!w#z}wLo+RVhc+l$g>-B!K zF7JYaOTYL%a)0`-Mt?FJb=$*aFzq#y_INZ+hOJsG#%N z|Nei=uu3VyHzpKS#c@HzCU#kN6pIoY(~JBhz~PoeBD-^zkZD*u`;*Q6Y_UCi`{B)- zKNH%=b-p4w3?8lW9W>6sESsP0a-MPieD*PaI(vK~CHR)a`Dg#c1^&}nzL7s}@_!;G zxXX$Cb`OMCz9uyup!^f~Lod`+H_aTh{B53YcZ8etEiL%x!>jKrxSi}qs%bcPv3ek3 z3+QU3*Q?NZR^Uy7wcRE+)@dt7>ZQ+HpI>L`oL-v-PuLHgpRc_WiM{;k^-t&HeEIaK z@2`5Fe^*VvF_DB5PT789Y+=;=d&&6?ToX9m0-?z-e4Vy7E~4v$&;pb#y&+sP%f;$_ z`WW06Q>rS~m+AB3@rf`GHY%sA6tGyu3Sg8~0-!!;r%Avg@e3(KOYRlo9ALnS5TsQi z-lW@I@w^hG5QDf%k~q)gB*&vTHF#xTwkN(KMVj=QG;A-kP_Q8^ZPvG(HP)jVCY;s%M3 z8bH!dl3!(mq4IpJK*hl)3${%2iq$=*P!eqrdzc|w$@mK}RpjEA7#qBWIYPZn3U(~j zUua&F+SZtUH7UQwWa(Xof-P9*;%)ZbYY_I%)iLl5L6w`4ZsVt+vbkamX<+&}ww0A- zl&KkL)8q<^!vP-s%@4v;%X|xN2}A)@KDIF7D{}wV; zgySu4y69q)0Xv9p@^Q9YmMqlIpXioDvx^B2jSjD_TR|gT23-@T^)LO}0S!O)tD>6= z8fgIFrv%~Gt{{Wz#g?ym-8S5A7xybt!qhG-o)gsrBkB!yrAvbP>Q#<3NCd^XX(Sju zCwT%w#>iDNifxT@^6K#J=_ooVwg?@F!n0+b?)Y(&bVs78&~!C7AJ8-;D`<~EBj1Pc zFbNJ~X_w+Pu5V4MNuSWa7>E2ZjZvcbUdDj^&#P|`VbW@Hdy~J-=cHjgzg({BpWUy*A>qZ>iekOMh)}jSnpH-t?ECfR)-@3wrm$qI7<$!!Fb_gmJtF7p z(1K+bc~y!YZfVDX8=FUNKC|8B=lJHjlJZ#y+kCMrBJRNphol$$xbFa#owwwJ%d(ud{ z&F&y+H%5(Q&>AY<(iLEug#Gztz4mFs#;j5!(JOE*<-a1 z7j~*OJ6v4(${lH@DnI;;>vx3bY1MI*RXoDo`>o|sUWA#>FLa(%t?bpgdfEs@iO8QY zd!`8JS%gxaSrp2}fEE=K*9Bmt0gD6%ltI9NARHJ_1p=c(8GM8!cu|c;jYX#@I6Q3x z-H%XFhC!UGOAv6V=D#Ds%zx(?cx2?&fBt)*+Uh&hC}kL+lPv1fWhk<;R(P?Q>qh1)lkyvdS3|xc8%%aAtihQakbpS8Z zV4SaC;DBFCuuM>8YfcSxkW`2(jL1x{-&3xa=_(~vj~W)TUbqd-Qrlxg7AYHSDe?={ z2{Tj_pfqBa|D7VAvS7rtMCz)#(4o!J~rH<(R`M$B&BM^$a4FsBDZQ zS!v8-8#9<>3qAgLk}c6aq*SzAm4AM&aiv0L(1(f+HMCT4e(dOy!>7lNfL$U*)Oz9| z*rm!T;$U0u$wOgVfpNO}u+79%{qzPLXp0^tbCNByouc80UCUO(XTxmXf~#Jh$~C*# ziYEtEN@MHNrx5fGY3%Te60l%J(4u5v0<2195Mh-^Kdr1herLKJZr*J& zYIU1a5<1O#BminQyUB3YAm4hUZg14=O$P(DryXi~89Ma_Pd zg`nh|VzfZdLnj?2(19L&u1sM%-ZYs~A3EIj@s2nMin3A&{l<3I%CAT%dV0T*cZ=H{ zF(DDbzrl$FNGY7c?~>2p6Q0t{V46U`XL!OO@7Uuj0qz0PN*Pz11>u(3w?yHj7{q8% zaUB7Zx>DG1xy--6UM!c}hZHK>z^2S3_vZ}A7-ssQ=F22SXAUCuCV#b|^-mZ!Nm&g` zCJjO)snB3Z6aE^m)4tzCgmgM_H6%TCXqX`h(ZF7(TN;nhiTz+?26d&Zcj+?Q?J`Qf z-elt1mf*U>$){2}yAgoh&KA`DP=wXaQ)#*DFkK8qgm&B895#{$pPIy|D!J2d)Uj-z zSIMq2q*R+*wH0j&ZcF#pHm_-IPG|%3OL)X4y&y9iwAE;ho2z~od7-%KA5-sBSio!yj1;&t`~2~#GnfXDA)GkR3)nI8^I z1ENt4&T-E3Q~cRf|Eo>@1UIII*ZBr{wbjh@L2;}}iZ-C=f5lEv6zHo#7DzZwOg&$q z4F(!JrBtBD1C5ztD$oW4orF$)C_+56Nyub~A_@l+I_;zg1Hgn#Ln$IOn72=laPiQ$ zMFyMx!ulW@X{8+VL{<9y@JFgDalfUTbw;B7z`Buh^FUH+(bviL%G?Fmw9fs-b?tevq*%!b<1qoU!ld4ZCs@<4~kK-PPbE(4cB zel;E-O;F@iZG$2WFa4GZe)L5yX!r(Ia9%4zTb8Te-+zh7&xERyH!EO!jB1+|ArvcTyNt5))zL%~g``N{@~F$o7im)1pN*e%05uw4nhBGgMP!Ni0^+}=ty-8}c!mrZD$23r7N>i;gO%|XwO^;Tb zwqA?B(b{IUT|i|W1foD+4X8j8R4gpoV4(DG_^`A=j>kygyR&F{Xh%UXt1-K^nO@H z3FPtJ-ZDnj(90-;EKtS-ZHVD={g47_RE{>Ot1+ADL-MpqiH1jVh>FICTgoLSUl*8E zV|7u5=I#OmG;pBd7XrF_c0r@p8n=*s9VKJe9v(^w#w|pN_Zex9VJ0ej+1`>aVX*sc z2Gy>&DT3T?6Qf;zalgtpEZn(?S_ft`s0M0N1Oc^)(LiM_2Q$ntO2B&PdfkijtH!2M zDBVHw+hX^?3bJ=!OlVMS@($i3gV9P}zKRQ;%QQm!h^>aZy1UzEyWf=-IC~hxL83nH zBkE(NC{`cSEW78hXMvMfHoc~djXBZ>Fg9J7e$uY-qKW8a8TuYD#(n?$r>LrilKLfH z{8lgTRT2!ccA1t3@^7&3lxVo5ms}xWI&E|)>{Mq9yQv}iMmc5#wlfzlP9y(YYv<3% zBWsO&xW+{RHO03=w}W4zCiv1j!_w6^zARap*f)tcLDsHlhb_4b*E2#zjGFt4m zlkxe(WW1kfi&;gvJf!dL*#*4pFtm_&sqvl zs`A6AOg8Tp&)IT&vHEq9=^0=Liyr0TRLt;ODU6y>pM4=}i!bbnt^xW=L|wm1=N2Zp z;6Yojb)(#@v84zNEqe>smo4t>s5prWd~~lWM@>2KbQm1Q1SS3AIiQvL05ns+WRyrLLaz zC09j!se;Q=8J6Q5G%%di0o)qu*K+kFz;f?88<7vI#eY7rUe@-UG@^_P?9sX$nNDSC z%qx_uK?3D$lMxxK+XbA&ZCsWs42Y|#D%2IXaFHH_5?JAH((b;^;lwK1oj<4lD%cRW zZm2%0R`ol`#jnPB_H%i%7 zIB1e>C8Z2N*btfuKD;i`IWXD^k;I2;lMY~J(>)X{$w~J-)4hmbKDldJbMJsA(L%DBqg3Zp`tEO3?8SU{tc) zM=m?)Cg%u zJ|oQ(cFZHnOiAXEU&lG5Oi6@EVUvPKIc)m(@W+&yU=MsynThLIN0pfnXl-*&|1Fj{ z`WT6drv0QCVM^RMTP|7W+M&QNq`q<01HqRXN-3IlHH~>d-4M6ZL?_0`;%5+^_((%j z37EJ&${}_|F_HV$1Svv_8e)r(qlh(0rKMII&5J3#iX3zaDZ`@|=!S8j^ohNGAgV+& zwyfm9H%#7HJw3k5N#wmPYsrK1ljIiIoPXG6*J~2crc16sV5zm}G0wM0Lf1d)v;ppa zoo@F6YSCkWS|mY0E!qH}^fVb>YIt zCySgvQJ$D861ue6k`5k(*2)?w#tHCCq%Ua|0&yEGOPYrA>{+FcSU`#^A*H&6+@xmr%Ar|>q1;>p%*0NpI^?-oCT^C}gvp-yk+C!Z zKsX1}5PNys$q|FuNw}w{oje1~Gfqi4%r|tJnMsFN>M7DD20^7ERB8u$Q@$U)N*4n8 zA>Gj7JoW{PP$aHKM^l=}*s}^SG)({y`iq<3?^8!q_Chc1^0SgY%s=l(HU6|+Y@#%3NZ03-R{_inZUS0 z5MscJv_avtAPN9;xeyH|TSWrQ@P)^u#^5q3I65xW56+|vfXGhhVe<^TukxLGj09^C zR0(~R<&W8J^DvmK)JblvGO*W z32-(k)dqCO2L`||rKckB)gi%VDYC%WqevB$BZ}mqdE;XHdNC*A#sTw&U>TJ+eELMp z0=aYvG0`erucM+xNr^%(5(hb7Qib{)e!-ATbF%j$(&hvql&)5xw#TiC;oionV>1t1 z8$*Awvv>|#KMIy5WuR1@e6yqa$3*FZ7M0^f;;6x3Nga~&2+eSNOOnOZt_C$0pd<(@ zRyt(>Kp6d5&0#1c7@Z=^~2&;^@FQq7G%2FU>r#YK;kMzNs4lzOdZ&L zR)nAhDhSZdIFb+Ts_Ag&zfft09Pa@zN=>#$15V7T)K$KMYTBsh!}V2SEu{@1Rm#Hw zMME*+>Cya9R_5|7m2q}H@bN;5GlXe$yJs+WNr{kfv4UMp^qFpN(e-89uj$u)TRU4C z{a0VkU1e%uFd+qYmuUL`C&5#gYZSg?3@lP^i&O(!sTSNV)l zvie_rH+ARx1L?&Gbg;H;{k%#6_^w~JyX^7LJl*!s>aDdktXKwgI08sbsZTs5Rjp}K zk7p)OxZ>lsq<&_=XX~(o!0Zub6)v*UB)fF8gN!G)9i7WZ_C|%n)p1oqkrf`DN-)@v zm}L1fen?mM#_p>#k+J{@;aK`P9CV+`#D%(|NHaisR-5U;F=_aCP|g?Z)0{}ZniUn+ z2!}F(t*%fM4*FADYtYD9jmcO!(H&B6x3Bp>I$?%Y5+0nF=p=LwSBY^&s4@b^Hf69ioLn@?&JO!@HFuCm zaRnjn^geL16AC9o)5jMRy>kPJPSg$7H85lc_J|on$2Js$sWC1Wsk9-(;9jL;@r+7h z!^56Y$r)B_az{e(2VUhxNYu%3vgiY|j#XQ8VnCO2tpcx|NPU1tmomdNtry1TKsx6g zEX~2ALMj{!4CGtBR*3b+via3&`Eqr4^RRG)B3t7)8*C)5bJlr^gR;#Dl6}K_O+TFJ zstr*iz(seJJx8AMtz|7rJbIB&cs{c&`aXl{XBcYUedQh%kMO;}GJ}`&?dkXi=5w&3 zQ7{JBSKzcQ%{6uyx@1%vh=)rf;iQ7(3-h$%1*Ii}C53d5^x1?MhheB+r@U3Km-P4zC{lKxA+qVWdk zSNVC9Ztk<~?j7l(6(I+OiKXh+xRy0rSd{_BOOjC{EKlhwc(a2tM=!)nI~Zp>7hhDw zyt>ZrA6fe@?d{GU=sM>zBL-laYwbo%?kd&4ru4R}2wi%W?I#Q1p8;o`$@LRG-%p1w zYG^n#a+w+n{SbE1nM)4)6+55e&_;1Frgiwk>MXffAIl&IH$|DU`x@c;*9jfVI4o9rI?p+21; z>@GC7F^c-c>0{#vL*`nH6K67=Lsc0kY26`*W93X#88ijd6yGXS&}PgqB(59g_H>Ny zZVih4pDHBUaoMCBEL~$Lr;Q*X4eMsA>*9>K^%Jz=P;rMk!m|4u&TX*9PENefh{{kO zsi7Zzy^*zPi1*+)Nj4wnPjIFS&%rScSMm+X(Cad#pn+Vh-Yp4d93IdP@u`9>-53a3 z=(;EN>jm66a`*CPu_6^=>9U1G6wne;VWo4nc>b`aKey*_!GT!$rL+mRsm_z}tI`5y zq=xf3eZX@I{VwzX^YE$}r-H$dvB0T7D{HPoadaC-c|QMzwPfI*0rF$|1F1$Gd zo-m-xC}P1eRoO5&RSYi5;M&xfh$_%<6&Vb*WXw|FE*>x14dNjNqtuuaoz>cJTDU@W zeGEyH8ETLw&kB+`eJrx&fyU^LYL})m41Ex37~b86#_chK5z<1{7FC6naz!|bF8|x^ ze$6(!?AbXBNbh4Pj(H&c0@WcEXqN?e;h5tNVr**_K$Ps)9@8F_>*(QHHow|n9 zDz%-_FI~<`4``h8^E0fYqzW?2D16qjdV_TGc9+7`n=|xr_CoQMC;u=blU%*K5(oLi zkS1jf($&+LdI|-}Tm@#TQkA1ffu!T;inG%wWfsI5>$q0(fiR=eQ1d{<^I<&~4&alx zmT@?^hxJ=}VJA%!UdqZv5v3{bDrIHgv{}~U1xNBUe2X_d=uNx^rK3B<*l)|yrGLAYskwxq3MU#fJ0OLqt!ZALp-Zjps1(^*mS4501sl5z^%i)p=? zgKmP}wE6<8tAVANox%(zmDJROA}dv@>5{5EsC5TP z<}9hfSl<&gBK<2>^MvbODoxHFSC(H`$~lbRU1rf&`*@?}J54J6t%(kna>&rxG>t!izJvcs0$1?tzJ!b~1``?DtsP6_y!cGJL<}nn zec72$8SF)8ZvC`e{`j5gcDU=!roCym-yI~~S+AY6r-Ml{nALkpYcd`UC&N*vfgSZqv3FvjN0SzbWk7G$L+?CyxvThN?ne1^2^QWOQu@2g2iji z4ERx3nh6odztBub@?2+zu=LM$m6>!ftpg5xk(qRD>@{YZ$J7lQs+rOFc`ANMSSjKy zNeSovhDs20l>+ED7`BZ*6N0A~VjSg2p7H@n`KEk*MYb-jTn1=Rx+hk39PW&!59TMfgFP2v~fQd@$(Uf`d+WwuGWV8<(+# zA~lFBMTxtdPJA_#uEMJmT=1rQ)=baiI__0Dl<4)V$pP)w17Gf@V>;H=ZbnuSyA}d> zdHJ?0=={ed)h4IcTZhzaf~=DNn{0ItQ-r*igyYVLDtW&n%`Kg731lznDkZR6U4obc zNhRNlZS0na@@)`0|KC5ln-G|x)4H(mbC2zBzkk$P7q;oGy5gZV^Okg5Z@>Pw*ks{aFOBt-n;uWrn&2e2a?RZrB$E$9 z^<#TofS{(hR;ZP)cIiUiXJ)7tQKAGlM(>xr$+uf~7LF;(j2S{M@!o$xX*-Ny$qgZS z`kzm!ygYADxtte5Dy4x9%LkII@k2;wTV&P;k}bI*B;Vvuw-1NPUxFDzF05`@7>8HJ zi{-o!Qt7E_sk&kSDL{~Ud6QE8Eqi|bw3O?%&x zj^SIny2i0l1jwZ1f;>j$+X^E159jQdqQe~Oq`0BI|J%RbM09&JYNSU=N>S|`sJCPC z#&&ha`T7NDxH9aJAo@zWHdqtMQ{z^l1zU~7s&b(UylHA$gjRwYN5;#q15_H9?po<` zzp6;*T06U}R^zX3HU7Gv8amh7*?@BOx@KHTT!7?~KOrABttHyZvv*Y!8x!8?fU_@yN7pby} zbIpHBw;wK)wFL@M&S=(QKyjXWxjD*DTo*iOFws1JS}g$0?&}Bma&>o^rCTB^G_&j6 z{Klp<1TgUy3o3Xs1*?7O12y>Ws1@?fqip24%|TU0fK#=gfD&DkB1svQqWpOHE@we_ zlXF1st&X9idPVLgUtPDtf>u5W&j)a;=I~i6djTycVM|ntv-%Y>G0SKXN+A}~R_Lh} zBB9~I7Sq;Sv%#n}8719TZ@h{bplUpSTy(4m;gJv)LIW^;Tz^ zwEKjpKj{yWPJJ+$bSIPgtlR#Pi)p1Zd{fnx$MQ|}4O(u# zFX8$E34(91zCcpR_iy3)0ttd|u)aW2$@ei_Um!v74b~S(D)}CIJ(A9wpVkqiG^MHJ z{5o6QKd2rIjx{5ygz%3mo+-)q#k4SdMP;N%rOGo(;)H zj0+p|UP-jtx}YZuELLTs-+{e#i)ZN=xI$}m`Op|eYL6>nw1tGYPF!Bs2|`QxLideg zRUJl8E5Op&-9<{kI$?qqB@5G0tW*ZkP4wuenfsBg&pYIP%Wi8pX%3QcXG*$={ca~2 zHQKFYS|5%{*Kg9DjmGXSVy```_xhwy*l6|ZNxLor|cpMAA0v&8VVX6MEb@oIC1+enTS*Dw`7vs-9urGDog)t`z^VH_0Hbm_FHn- z#&!-hk9}6vw#LTOB$S-5Ay~p5pl7}v5z_`dgAmWIAEl^lRFI15&`T732~f0Zdy-OA zPFf)q{cE+Ne+^LduV_V&zPnF}65H`kzPnGUaGKqH%4a9u-KT&ae0QJ1biCbtN_{!~ zj8y!xTJ6h#;&X{oRIJ^izmSUBYqv_2g@bvt`A70gn|vg{)SS2%hh#;MDE>(QHD+eM2(vx<8LnWu9W2Zq^ro{>zdlP^-Bv$o zk0#?}&}jCPac9`7HwNu-v(s~j+3i-hGwcr=NpsrnChcakm5iE%yxZw@+s$rs((jL) zVfKFw+S74=GHWN@Zlj&FNt~aIy3J-X>vjf>)@U~9Po|Rc=)pL5whZr%7>siv)EL`y zNCmpXn?jf_@_;u?H&i#mbo$0Df|X&qtshOImq~~0==fc!V@spv5ZYBo_e>9WbT5op z<+`6Oy65>qkJb+t-E+r>Mfc7s>|6ddquz&gK5M8PZrB&OF)n@Fl81cJh+HKqCEljn z3~~}7Im_?h$=O-b_{-V!d9nND?CgL2ud~U;^}CD7=MQiH_3hPfZ&?bGfaC+><;DFf zo1f3FR_q`>SjF_uTArXE<1L)(c30Ehnjfa{r~1F2{TFL4Q~>hdl~j!=s%99KsLsy8 zrcf!ux^>{w`uBhS^RKj(C$3i&kYLV!{Wr^o;8XHK+5W#PN+uj>^FIF`bD|B9RTX?- zPY*zh5x@v5MbKoflTo4h7pE^`MAEdM6r-}9ff8MD`!%spK_j)$3aOQpp=nl=tgCh8 zhcnU#!Gpy*aiyfA_X;&oyc>7&UZGN9JYU|=7E3z67%Wf`SIRj}?~}><0liNJ^x(Zu zh3R;`Po@6lVpUod#FTr%FQ`JgOyO$R11iD!g(;DxUQ>j1(gm|16|Q$F>~Nb;vTq9- zrX50+0@EOsRNB!CbS`;@q>ovrRm+u9N2F>tbEX-5t5)n{3-Ob&1RW<-5LQZnWc*4V zejN%8Vo<-;_|C?CiWN4zuY=PJRaP)k$XGSbCtgsttNDk*Y z%B&jsyL7Y7rqAn5wuL!3E?+$`+e|2?bi|82*so=`MXRqhU5H=*e|yR{VyMQawY(I@ z7|{?z>E`F4D4BvfHm*tl$eV1t(+uTD`##$}ZC30o$=z34x4;j?F7bonwsh7Fpfn7y z0VxW%Pq1mV3VyM!hK1%K{)Z3H9LyF0&|0)I_aYPw**&7d`>2G@H1v7%evF^L;^e$ryH=?SGR$O(# zlYtI?Yirm39(~k@%JPr-I7+Iz2iIF1jbwsdVPPX}Rn;O&`qQmFOJgshqy%hzh@eHu z!Yrb!R0gq#(xabYTBh6K_9`{Uy~eaYNLmxvt2FJ7lToKVOeURfqc!MvN3)q)&9Nm+-jv48 z(<}g)KjXpb5=h1C&#>hsKnQX@>q`^_-gN_Ne2>jOaG(SMO~$u6Z~=bJDFIq_t)CjE zz9g)MAd`l`kVI%GJG&E(147BFLC|CzfE3|}KuOT*AAO0Q5=B#9{(vQVN(FNvnie1; zWt#NW?laRHRf395z1}oApxt`#rE?0?@s`dh^?xO0FlKcsr>h3R6Y`QJr1$}F8Z?OE za*>*yFdPU z1|^rRa4@KREQnA*#O_4;3#q@oJF(E)q$h#A&351O%~#dI)t|a0v7~lCSEpm$NsCj6 z9+=KAR#8MB7_GaO0Sv7V)-4`&JDpCuGfNti!8mD8`i*4RYmJj;y+iuA9M<>=v6|mc6Z0_Khv4db-Fi zWs7&H^8{u&kLfNO;*Q^EHpF=@Rad5}^2X2Ae>T0ZcZv_yi8dV`+mp8a$m%f|b*kbD^h4h#Eg_HpB?@xsZmGq?3jVv!YE;%<3Ck5lx`4WSS~pR|KsfPCOydI8rWMN5V)sHUnJ=F}(@G&s zYsXZm5QcLQGl2wL(*VPQYy(J5>0cvyd)H=CHp0$qEhT-#M45Jpn7?&0L}>D!)Sx5+ z`dc>XpMThj$Lv5*O$%<_*I7D;;OyenW-(_!D*eJfurPQ_n>OL+a(@AHByOMjHLfn{ zd~)G<2f+cGAJ*p|*84ifWQ3GFAzia5NkE7bK{{C~pX`ax;Dv-JqOwSVjJR5qw$W%S zyOXRUE6sm_3Q-Z;JAB?c%vPDg=+1}TVyRsYLVvn>vo!X&5+z`RGJ+N*3p0dNsSIN5 z$fKXud_I0>x*cwys6XiUd%amQ84spOdp4RSqrsq;jJh52q&Mm{r-PF96W#h~I&QU+ zUa#It+TB5m5RHe)pgx-po6Yg8F;d4@{gCw&+>LTX;gn-U!iV1V6NZAuxDb6~z>i!% z!9<*5{RETb9tINDsIv6Wwtj*;SRcwc-1-Ub+SpMa&10Y6WUKq#gB}@+#w2uDf^qsp zY0GACmE3nk&qos3Z4Mz?GQ&zA5<4G4Fz~_3Jo*g15+(ZXC!e8LDx6{zK*&4!0Dunk z;4}0J)A45LmHMPc`mjy!Nt^=L$(}#0Hl)LqZnOE-Y6-x2EEkh)OxB-F*8UvCd!lgh z;JtQX_ga)w5#++=C7MTB5EW)}-?**y>fV!+xYY$2SCX6<=*&-!bjxon0;G zbW@kHl?nC>~_MpIfP;k3mj7KqCAQK zp)Ew<-$(=w7gwem>Q=Gbg61U{0jFPB@97Oq<`};5`$&Ec1=^`LQ@Ca;iL%3Zxmb%_ zo|BTqzh8+6NBHadiS|_ZYgOVfc~q03HL08fveq!vtXb-iK9hQ1ol7sX%{}Dx1&sOV z1&*mpU%U4oT&&)wu(?Gz%?qDoMc@K!`u;+GEaWdw83-8+vY^yV#cNF2nyv;aM^Lvg zzTEXRdzs~dj(uFwwIe)YVUKRU=h`E0<|wy8NXF2#WqJZ`rW^l8R6^HZH~GaQX`5uN zwJ20u*S8ND)nG9q73USOMTk_|&dG=3yh1fcq0!r?$1lK8X>(04Z|9Nc^&>Ga3zkE2 zxNRD4l$yg3v@I%5QdA=_J|-Lz3MdeMCq9f8yT^2WlfPTs?nt-loIlWe!591;oTiL4 zKpESLYAIVmgq6KsESCh%Toi~e+ua82=#D=yrc!(;UpJ$_5`R;>kxX!#LLL@BF(T5x zsr2a*cJ9(25ixwh3O4>)5lQXruf*%1b&Y5eoPUV=%c?FMSBo?^yZlKEMy({6!7u(h(tVWrCS)!>4^Xenc~K#_sE7x~7le2<B40oBCP^>EY40+Pc`|$mJ>(yNI_OND8^zx)MQO%v%T#FB-guix7h9$x7%Xv4DT&_ z+2tQ;G5WdAmUN=koG6SO&!kv-2yH+pe`%2V5#uTjrkk}8w3qEMY+Oakbr$h%p$PGm>0xF zloP$C5oBDD0D1RSiiFV&m_$f-w{Rd6O36~r6;)!E&$I2~R-#*`yM`JtUas!-U+J!C zypz8|S2;Sx)~Go0FA+n(mmaapbcX=e7>sq7rB(L*UABQhnP-I2%Pt}tXwp>Xw|H0B z+UO^eP+N>{Fzp?^Xy-Iub*7ge#^s(6%Rz<<{!NIWoz>ux4fwpx=jkpr3Ku(YU0%bc z9tW_c9Qb{97GHkBoR;ZATgfsHzzekpN;4SW(-z-D*Q^AKY`A5}R}PVUU)UqZGAu5u*ks18u4#(pH4D;5SK7!$RftAXtdEBChxs-iu4ev7x7=tg1UOQ8 z9jC36KjZ9I?1s2k4ZGju#wh%``U<8u(}F?GVSk*eScw(IN1VgYt8f^egKX-YT`4(v z3Q-3z`kc<5xC9RJ}NV! zIDc5L-Lzu$bvR2*_H*Z>@Z3_cy~+{N()wg%O*d9}o2*$&txqRki`fZLMPF=h7I$}0 z(|dAExJfj&f}vjz5lU+tkhT!A{C2ZD-0UZNfpI3-26HQu6<$h#?XOePa)TDozc_X9m#z!vdiN!kw~NB-_>j{bgGu|gB&Ft9 z1>j_sH*p-c5D?z^X2)2m^ERDUszzJwsvTqoDG~Pl>WpXQe&fSmZGbT#Pft8 zz7f+*5oU_q(5yA&1KdU$Px)Cq7+9 zy3u>QjH#k=z6^V1m>}|i87|}$C(LkB?jvTTNviDqvz;*`yiBWugC8;@+#7$&jPly& zMPOyWsK|71JjQ~b8p#-&Il90Pq<9X*&{X}8Kvn+(q3VAGsQMpxRY`Rdq-yCoDw?Wa z15~X#B}G&9=%?RkvcypG$&bI$bU4lVH=5s0d;pFH_24JqXs8Z*1ddC}TM_zt`RS=V z=9uK7&+w~iY6A-?@c0$bdE|^Y`F2Z!;W??TT>>3#qDP{^%@AFPV_~RUo8MIdwDrO* znWeTPX^WJFt3`f+I$?tB0HqPpb|4NTGujvq7Kl&B(^042ZX~mQdz!Q-GYG^7-K5oQ zHoD{PVBBx?-GO*x+-{9J-AU4{cRNXY&}k)uMysE+8pGMN-|p3Cv(AqV#0!p>(cLK{ z@}h^mp?QhYMvQKyF{`?`VBHpbim2U|=?>qE_N(&J&lblQvVA1fQh#HJ01mu*te%@bp} zfWKMXKkV32F3Bbkyo*JM0bKL}MsShuXNck77LQMGg=(xBID!scqUU+? zj;u?W)AVRvE6HeOwpLBX)Kj;QfNK?ngel-1p*FzYR4Vf^3&Lm(_{06+*r z>~pa};LB}cEp#}3U1tlv&`nzjtXsmHnTG52@`XMifZ+6{bN$C(NPk`Z@@FbPr!a+H zZPGdP)h>x+m*>VWI6hSSiO|Wz44YvTw(a?rK4R9{ebrLIBavO$6Nr%1dwh1e=Q^^3 zO2+9fyC;T(1?t+$l)(Jsh5!fr!FR|+Zkf7?$_IaGZRr?~rqA6Pvc#ps(X9S8$M^)d zFnxl?qAL{+8H&bWa2E!q{{e3sYL4pDQ9Y@5M%|=6n>CZ+u+dFM<4LPEn@qc%Zs|C5 zcRHSRCP}?L8z$}6xSb4oqejwfPCB#MsMDE^CVwa6(A?*2c<@IJLksufMxhOr-Gk6H ziCN3-IR?#yo^%MBiL4lb7N)E6&rdr5&2xi3o_vJyXYT$33_nY+euf?deH1}Ts>ttWM3x$3EHN?qBc7a40fR#QI6Y4 z8V>w)W8X@q7_0tqL*JU?PdoChx%~$Xd@Jb38~0Wyk9Wiyu}Ij0MN$0>MqB*z83usDqaR-q?-vskI_Jlq@N#KBV7eRz_bb$S^c zLI$RbUZDh{UtXe@W@*sqV4d!6k93rWvu-kM_9vv%Jsc(dVP}@qXZ>EcHR<=et&&c6 zr!$%Ko9$`RYBi@xyD=Unqjr6qjQf*uzcHOQ>x1!+>~vGd$v)UA``OHMp3b$Vn$e#I z-y3BkrV|a!kKbRsGJb&07nV|&5eN3iVb1~z!!FX_!~L9v-m zTP1`P-5n{@F){?HSHzKnOd&=Df+vnEh4}G&3DYKoJSGB>#9kSv2vX**3yOGh*0PEN$@Mr-dF2Pgu3J>XlwxG(^C5% zLqz3p3Es1RKq*!azsj!D=jrp}(OFr0xF5=B$_@a%rl8jpWb&0^fuj#K3;`#! z*cdDQbDe$@K{t14+4T4RHlVUJDb<;0nQy~8Qk1G3Fg=;%98PEuR(j2j4-lDw6j_m# z)XH8sz67pvSpMt6CK4i`5C!=-ckOQS!WLKQGTjoT6n_ zSUR)dK{idSDt1jhJ}>GS!)yF~c~4AP~bkk+`&y;6ik;VW3XGUvCe4v!prhb&_^tI7h-~o90qb`1Ud9@%3&e5 zr#-_&9@ULuBS$*3l8PBdatS~Fu#!uvdzi^>%__hBT*FSz3_@$90}n$vGehjKREdwF z^Sg|ln$T$R*%^BD8ez~Zg+>PomGg3^|b!v{B-%?$PTPKYI4>^TSi-j-Ck)&aWB^if`T$>}wqJ10*Q<8=|HUg$3 zi-O4?!7>S0SC!*LS2Nqaf2h zB7F%$)vtiHU5Y3SwW5=tP5FN0Ds2>S$S!*{WHxyibeozR0Mn4!q*34@*Zj7a!yeG! z=9|)m!IfkII3-OKK$bb^2Du=Bk}eFOBntp2X`%o^HW=Nji~zSlgvZ$ihcL(mat<9I za~srq7$GuL(THP^M}#XHVHDhVi`yO1Eb#UtP8Eic6B#q4Oln1@W^_^TV*5~0{im3| z(?0zs@IAC?(8`JLNPJrI0DyvuBUDnW^C+Z>1}Rn_0}~Ld{|*3bkp%+Rsigt*ht)>V zQ%4zt*6%>A0-Kk|FL{XPC5tc%NHPiC5?@h<1$lHHpjBKmu1aRK;Vx%%;T1BYi}&#R z94;-?Ruu%eR?tScSCDeRm>D{QE*|jpVxDcs`IA149e`PpN1#^395+`00bG&p3H?3T zFD|SU)Un7ZF-IN{VhYMA;7~>)^SDkL23e;J$l*F!G+0sbi>upI!@-^efG-dRn!u#z zhOqUiHi?-&$}l{xyS`1A+3%rMolYBO1cNlBs?+KA2K;dkz#roQe~bkDF%B@)72}6= zlit$xs@IR{a*4l+#3T;{ZP1GPjmt;WaFR3%_$*%)Z+^sq7NlWt1(ngc!Y)4*#8FU> zyz074tXMXE;#JsX>WBsE(fv)6KFs+RG0*JC{-;SBl?4P3i0`2-f#2CP?_-3Z=Ohu( zfl{_*N0YqeSSWDDmw25v4ze~R%0=VwMh}Y$ z1`zh_TfQ|Oap*M$QRQ5tk1_@fp}$Lage{5OFSK7sLzol+2G9u25k&2U-vnC1DCjq- zaalGJFrf+qN(eZ>O}1kmMz-UG5>#MhLC`*I=>=%qI>EWyBoBjY(wC{?2`pl108Br{qKyT= zSnUJeqz(jc5{H2|X(Pc8my7!q@9&LXM)_`+KL(cq7n3kUxHts0axMm-Yj9mZ+mQYc zH*ByWbmA}r=#)Xgb;5YS5C}s6{U-gAE#;FC)I5DCWFX^sZRrTykSq!`?diYI?)X*D zAl!NsfZw7Fvw}q|ZQ)SIZxD+h*evjqK0kk$jMcHkaOf)=oQADD;wuYNXmYXS8h=3O z+1Z@P5^~31IW_F|EA-Lm)8TUckpAUt^s(LtT3iW%!h`(MPB4tPGq;zJQ;*S&%pcTOZZ9aD^y+c2dWe#DB%dr z)`vA8^nQ+6!fc}*qsl(9bA-u`RY*b{TpbyRc{UigVTX|$7TJ(859<+86B|x;HO3=M zE6$qcbG8KJd`tg8%u;+=sa7dJd}%o1^##ttcjOBU3OiP5RIF{JWxw43St5JyETdrC zN+mT;9%fT)wL*w}uwETCmvHS4w!w8g9d<{p?jV^pr{knOX!erPq(4q(^;vh=u6MiB zamfbPVXrluwR+Q}HS7+PcBj=$M(zGAnGHLwR(&uVHX6MjxxrQVQSNIz<(^jQLeDl< zQ$b_rDtl!XqnORAT*UGBr*c8=EveENRhIs_cA*OY>KjQ9weeIqHg>P6^4GEFu{B9z zuKC1M*O~_AiCM=v-;0Zb!3{IHIeQ}yX;PcB{UL5yR(p2I-(gY%T@rFvb1xmz= zAupbJ4Nd%(uoS@Nf~YmI_DWbM=eJLf@6yd~>o9PTFu})n_opeAn}Xg26f8>-S4pB@ zKNlPb${J{CI-~-OCxcp}tSSLtzpQQ_Hu;K#`SalZs!ps4a_3n+ao`N1P6~?P$|#+2 zV!y+YDcWjaDs3n(MTv(sO1Fz!N*Oo_s0b?|siZ-(eTobZ=LEC58nDw%-1gpsXp+2m=xB+>59 z7#hccv>8;wvYY!|wdhEr97;OQg?Ol!w!LLr3ijp0;C2p=OL(Csfc2y_Y3BRxEUFJ+NWkZ|<$ zen2v%gk+2KgOkbd@L=}rY6DY9eD@xaNFLD?+H)jSi(4gNE4>cep@bj2#S3qOqiycd zfLi-`1WxQYlfI(|4=QFozo0`QqD%J$7A~h6h*-Ff2Xe7XNxK$YpDR)n8kSVz!PV-D zFbvWtUxp7K2tpJbNEiVI$ikp}Sk1G|l9awEJdzp(N~VrLCTYXqLHYceT|Gsdo}*Kv z;K|ex@FZ;*yuum;JT^*-!bMX`Oj1@gC`uRsDCS@ZNsEWnjK)MylfZ)#>pb8TKhZp< z8~tejN{g%-t4<&hyOgK~ucr<(fqtM_Osl5TqfqMv5;d1w4OFKN14@c8)Kam%m?8@l zT9YKA{xKQgAzweF^Za`(T7$Y0sF6Alqd|*@_c~qXvEVe?N@!ZzKwugr9+u{DTA#($ zw>pPPgf@YM8Bq7?^mwq$^^rI=;!22G+E8>FDIOTOJ`$EBtpp`ghC-5rctDzu>A+u1 zL!r}Gg0l%EMlKhfB`Gx?D04R-kO@U;5LZGpQitI)NaMhL+y~spAaH6VDHvS9fD+{D zn4Y(iw~S#R>FNELWJ(EYk9}nU@bvZ~ypAlez~R&>Bwl2l zSzr(d816sY2d$*XL6ym)a7yY}kTKmvlR+TN@D8I%9tc$LZSB`>w7KDM>lAv)EvSJo zf}T9k47@zhqtZcs=%MWeCOGsug@zt^YI}i29O$?($Yu}(I3^IX$pgW@OXu^&>OMFU zGKg^?Md}EEf;0|Xa3o|92Z0NWgbdO^aC;5w*bHzW_ZZl*$?;$>R$uaGIYB4m7kzRN z1KDI#iPuc7RYIn4KWdW+9x~mLv$%s53FOsmk-?M)w=)v1gGD7~2hBPC*IF6t#q3}L z3MxKT;Q7X~$o0*fx)Li-XH6@HEM(>!@Lr{5Aa+DcC$0piCze?kH>RbN;-OIjy0UHh zyxwFa1Hg=U@T{VXfNPA`1fK0k~){M!J*XcKYe-$)b>K788LEwj{l4>obdgzCy(&3?r zeKdqnHp<#FBtnzI4^c~N9?+w`@Z;1Hf;O04FE`oq?mbD7K?Y%$oA16B9wO1Y==_)q z6cTyijURd;Io1HPWuETdK0SWPHnV*5m_p4HT1*Q(DsdMmqV~8IxS&DvwLaQ4+(@K? zuo|IA$vw*DQ~(l0SRfy^*{|tlk-{o}b|67mt6|YsqO#I+Y`E6LqQyddli$+~48+4x z5H0#jh*tU_h!!mtqS~tQ*Bnm61BO9yjYeIG&rBYYJ55S7IJwm(3YQ zrQ%+8W?pmRHTKb>;QO213lRx_8d8s(1gTZxXb&NA8Q@{4uIc$uX}TU+2MQdIEZLfLNk3T{T)Qrlc- zaB?WmLG*GT;-66t_L)BKvej<;%h^r7%r@zY9%>^T%jlpt`xouIX-t0d(DZS=dm;Hb zC2_~ql7*jUZ%(BEgI~XFciH2gdAjYN)m!TrngVVPMuS1hyHLKS=~>f6>fgQD=&+{p z)sMt*XH+Q3TkPaLWw$?$iFE{jFeCp$-$ET+=>bfQ5p6V01FzLyWh*$VNmNRt%)4eZ zNV{sxTEKc2809EFt&AD@XZ7?*iM69W!mZ;~o;1w`?P{7_f5kgoua_^#O0$@@iZ86V zxW0YJ9oc{bddLjPasS8Y&paxCIh^p&3H|*d1AUGiM1I_{=4Fi zxe`SUsH75MyuvWIejH{M$zJbRQ8tPrj=5klT?NfhmYBh9Q569zMbSr~+6wCKDO6RL zTI}>;y>~F?VuzML$-l1-s)1tY)!~R|mvRZmKCZL~DgBn+rFyxjc`EJ_?o*lvpE;%)WJ66qOX zaJQE%Svb4Qb`Lo*tYbFZtKpk;bDwSLfZ)|?Y1$IZ1OXY&lu}WpVvVZ>{Wn95j=0!L z&+^S}_CC8!m$y$#!qHf1Ayp|T;3X@U_F+9IiD62NI@Bwom{#z09~>?`Y@Jsw9=k2e z(mIbVmpMiqE3NSg(glX=P-mHAlx57Sk2J^WZ~I7Uez0@S2hHJRGH5rFL3`Xx+QUvS z8P+@fWI7<9S+g`Elo(U#m_%x795kelAiNriniTT?#zWQRq^h=R|bPUR6H%2@ghBSwKJU{GjKf zE2r;uOuFvN&+j&ioX`cYz!!9wJPJz(MEbCmo`MQgs9IQOz_KT%kf?wRiwM&4#z$aM z^8B!XG#FAz+=K&$iX;qpiXsxEVh{`!mcpdVr>tzw!vj>1VquE(d@+kQ8Q=vc$Uq1G zG943G`Wy|6lcIs~^r65wSs*aJxF@*x!s)P}c=Eu7)tm|x2+D?RG4|olVKgA|vMURDQ(@Df!JUa8D4`(u9vmC+4t3ojw#8|)v zQ5af-bT6n!JG-(J>amZoG@wE;h#8d-bXb5QeHb=D6%30V@^tKTEe(W{Kti-7R}@f@ zEDo&RFooB<1r|Z5bwY_ASq~Q&#KD)xD@J0M^g+NSRTOGTy(i?Oo`C5AeTsuHi?H=> zK|R_znx#;WeVk?y>R!WLHiIC@dklEl81VPB* zJ(37?KrRY8_D(n{=-3pQ!Q8j4ArV#&|QV& z|D5&dq7FI6!gS)-y;h`CcO7vJ>1W#Z#YHOtfeM3BIP?mKLXcI$5D6s?%mPb6gonZR zGlsU^KvoF>5=E}015!K)b!Zt*d;M^Cx9ZP9W`D-3s*X*=sp{*TF;!JB45KQl)5TQ1 z*uwGKuni%spmMq@_9CrC~%uX&)}fZy-U1x6}3QCd*d*bR+GYBODxqS`$?W z5w9Q8b#}K{iv8k?Y^$PE$4j?-Mq$UQ4ssS2y7@-vh>2+fK_DXBNL*Teav?fcBurx2 zQGHTxCWB_Tle8P7deU!?M#*4WAIzHF=4{q)x+CG~xHD*vM~!4Q>=4TCV4RG)-Dc7l zG-thGyW1W&TR$=qc4h<_Yn?JIc6-_rBzsghB4$TAvu25jpIyR_A56QXx+811HLLvg zbH&-t45A0ohYGr#nISd;FY)o`H|cga-E8vBn9iB;Hd5#BX}k>LAhDF{a(jPXlnsYt zgvO(S-6zTJ--Fb7wamYy%Q4A1U(#Esl*Cu0e3M=iT~W3nPBCeD6UoQz#8b0o@k<8< zONZ~u3_u%#V6zjdFsy{Y0Eq1m5V|N>7rX4SctTjA8Z*k12QRSuMA_-t3xV6Ahd8Z< zd%B>K-yoVMQHB}kPcVZbbiu)=L_uQYa~&a4nw~xYSV}Lvipb2IGR(1@C@NEP+BpBQ zpD#2Ej9wt<GGGe>yOtLZ*S1%C`kCE^A4+E4Q^ah@ywa~_tEx~_!X!l z#OCImaKR;{$RaR56&Zxg;W)^Hv)6Dw=MHjYq3Eg;xB@@WAEyU9Exe@GJfv#6Am4H1 zE+wH8`YkIqF@a+yIvZVhMUDwSn7pbK@T0M4&ao{I0#F|_7s9$lm?tkj{pGL+5buBN zu*)X&99DJ8h0)(B=JI0VI5Fq^6|2yYrQgdV6f#|h$Bvox9Kegt6Y|6Be#PiC2P$K5 z`c7942U>+RiYJAk9apUXKFATxI>S9o={vOfk6_9uj-tHnaagqR5&VvFas-bO=?cQaV79h5`omaeED*puV{54?w)p4yYZo#DS>kf)>9lY zOzmU$2tsPyBV?Y z4mFj^R`(a;4~?&hNgy;A^pbvT?gu!)o193nFX$Ve1bBt4pO8`1Ls#t)WGzcK4IoxT*h1hufkZyL` z%1HLxjfo|)BXmZ=!dOX-lZOews}({--Ci9vH*oC^w_>r;>yG=q28pNZqomy*&ys#; z)P)6%!``6XpVnt;2M)CQGN_&m`lHdH-%R?GHVMajqjA!2jE6~mIvX}Rlg6k$Q@ehC zKu|6GC?l&=M$*!Sp77aJ(1@AYE3*v61j<~*@uOod$Q=?(V^mrC=Zb@cfAwJYP{FTo zY;44<{B`JsVw^KH4#!#>rYV1vy+;}ZvG<4r;6nWBYdeoH5Qg9K#eAGEmxPQ)rh!l_ z`btPv`XFc)EfymEDuYb%1Bp*h??)z6s;E*t@xzkIuz*JCChF)BL01VyB;-iA6h8_< z69D3Mwzz)?UNtBQF)&!lKpcz+3*_A*d!No1PuhGB4u~YI1R_(00Fgu?K;m{GYLqA} zVlN^?gV|@MQDNb{eR`ym9Kn8(gjEu57E6+QgDeFkl_r8j0k(nUSfkuLEN;K9vMn)6 znBIb}T6vK&1c9Kz!jO48`0NWsS&2j?jVgBjb1yV7a7YHtaG_WvVI>rqG6abv!UB1l zZysSfpBB?7L`4pj(267>7>m?cuphQ;uz_T5=I`LpslcHUYk`78#f47=>Hw&%2^<&~ z1Cdc;ps|#pkQfyfih0o0HSztDbV8A6st>u+02v2cF-$_7ACrBg6$Ta@1xOb^gdfi+ zNh=Y_lpGH7Bt}Vw1@kNEcP~i)Sls0cp|t%B3C=<0$7mC9s6_?*nC;Y9==AG3{a00B zVhjU`nWp_j|8?(Ips$!bR$tP8&4m+EsHlW7l4;scid&`lBX1VeB#8}uC*B{ZX>f`y zfm|G9O)e5KZc8 zh-UgQh$bx_;^bwOJ}z!4@nT7@kPVC}3LGkd7APcCT$E9u$HToK1utr>MiOEq#0{h< z$|@P-<7|S|T*T8wPR?^`yj$q>-xf|NWYcNExJ(9>@XX|qC`~3YV4+7BnoCUT0HlyS z?5rGl-&o|q zK=(O=x5xsEHvS;qB7-Q%`#D!~2*JCLdnJ7+*!^4^=GA>18tF@VioTre(w+su6ciYc zG_8bK6pR5&69zy9+tA2wuceDFHr1dVM6m&cgB9Kga^iLLbaw}934n1(AI~7K#BHUQ z4(C$+NG)PKNPdk|C^$}535ur+1H*|zK?L7hz{!vx0xv1xM0gO_={J(0*{JjGtNMim zV-Wc9sH9r0q8|EjsdP?gMTx`toQ{z3Em-z`CA(SlOLsBj`*MM>)WB>96DPG*!08p- zpcQ4-G*K9>*{K$k#!@<5n*uLga?xw_+zXl-W@*YDVx}ua0(*R!?5m=w-)7(UMOWls zlWe^vmS#coBA&Tm?U`5^wT!KHKDvhgL)9>r%wMRlwSr;FiVGI5#F}YyPpa(7O_R%3wDo zxb@TW;v=g@54R^_*r*SN&0!Rx zAel^tbT`8=8IC%WWIUYo>z!$D(C?0a8)i5UE_nrNZoq7 zKA83z$!Ij{C+$IFoDAFjQ8Jtid$U%*H6C@RCHpp;tyX)~8YlH$ZveNo&60kPFlx^F zo!+cI>DC*H@<;63)Ez8a-jl{jhDUunIE$*95tDjvmiVZ>oSLu`Z0OXamBdemm8$&k zlWpzP9j`}52ixDNJ3BU-vU~{paYjV=*O>h{j1VQ}eY%?GkM!v|o$Qm5Ncd#4#_JR1 zRkF&{QUUH*e} z*bcj?y<8Cexjm8VnqDfQTWy-e5ihf+j6Luw+}#i-Ic zzg(=|!%gCH?+_f3`U<)**0T|<_0=O#s_Ju@KHJRG=OXj;*<_9cE|jOIx>Bz68}OpX zyRuhYApHifLd?_VXRrR{?A<1tXLqFc!dfl%7^$b=f{;9%&uMjRHnI`Z=o%OQRJ10X z%^??ClfeGG&ISQFe2TP$(ff?Vty`njbLb}02xji70XiY4^~&Wlw+&cA=Y#~C+EXLO zf(u?gsz;7e5Yr*Y=&U|=}y;YNxL@~CZqPCnGE{<#-QD7_v?*` zyEi@@j2pw*bd>bR<8IQ1yU_d7b|aZ~+pTeA2^_7{NE38v8e!uIZW>5dStRQsXTV}HtW^<&5>Gv05zM813K;Ls5hB3lJRuh zOxlfZC+SZ{!=%w_GziDuU@~j`$T+}ouxvt383>pj^+W;=RgF+Udv6xOm{>p;cKl#K zm*$QJOe6#XP zziYw+oz4&02)og?^o$LgyLm>^=w)XN5qU&ZpO2)A0&^ONBnbYT4>vH*jFmD+Q~=Ui($Co$Qv@89dBM#%+9~J{IHa+&cA3k zWtU6w3D5!C`9~;;?EEA2wp=DOK3M0!-Wm@2<3T;?)n~J$4LcTwlR+!#j%NK)yD@5z z=Ovy0?y%Et4Q9!#)2S!zR(qO^y5mk#@6`LlZoAuC8exyYoVggAd4IpG=AWQ1FTtLs~iOTGZG|1PKA|j(R!Z?6W zyJh?-=|vtvcr`kS8W{`~IRwD}$GD8JPhr^LRhGZoGCCQ8Q_^I_;$07|fD>b5u`;<9fT-pG-#e zdfAG`>7>(Y^ry*S+L|QoX0Mx!ruA0RYfLAz>114=HGb%dM$6T*3w+Aq4BM}s0S%|R z#*l`Q!mP?-1~p89#~;=(<+%qoYo%$6{H z2xmJ6ZiFq+BjsLakBiInKcJ@&Bu~X!M9P7YrF8Rw zbn=PacVFq3tGmlA-I7oVDN^HskUD){=Nr5t$A z;A%U;*9ZA6TQ2_<28dXl%~xtcnH=XthsBC?xvyWgyX?{5At_~ralklVzku@G9^3qB zbDP2Y{Uch*S}{eN=6>66t4HVRE11W6TWy_EZdiTZrt^Nw$pQ4S-d5^U&JE+S_Zd53 z7)}@FUOUXu#Rg;7*~MiV{RV?NH~GO8()otyql)D4X_rq(XeG}OKV*5=nA^p^Otb4< zO6n^S9dMn;%|a=+S4Br82^lrY7o(|O zb01k%OH{b7B4(R1MU-kd`8v5KtvDG=N8U*u+!5YeZD!bb?iR`t7p8^{Nl{4J*vPdY_xyVf^H>{QsCBsP*5 z=82mnHbtIbn%ERrGEZz9t;#b$*+j9G5A>PegUu9Mj*p%yF8C9!Lw}bqU+(kOkZ2M( zWndDcGA&&mW{}CHVLZ0gWmiZ9rF`>>PPjmLlfNV8qJzlq!RO()U0gy8;Gz$;go{VG zNyf{?nq>V~x7$l1V6k2MBu07q27NrPnU9S z#@n1uNRdbMClbEJB1$ss%rIp09U;N;IbFC0m)rY@o`}sNMD+U%MvPdGXipVftgx!E zTMDlq^PEHs?EX{mgz*5Wii4G=g})>?Xn9evbn%x62OCf|q)0FpG{%7|ZC3aH_LRa+ z%b-c|X^?50CPrn}G^S&BJ*+?eorcXxQ3a{!C-HzIe3N}?NydPX1mSHbVX#bCeV0-v{HcxXB(4Dvxxb^ZwxbS zM7~MCWl&bN(#z(GgDdk=PWa4H#v!mWFXa<%p3BAR>RYz?w#dGlo1bwuvB}YB!pKAM6KR?P8?;#pl$uF2J^aQfFo`k*t-CJM=NXBQh`Mwf zDRi%X37Zgexaj#z71yQG7%mo|ZphpeEc_imHab% zp=OcO#ni@I+UU_@6KItZK4_zq&K;RBxMXjDv~lD!TDpk%)hfN_S<6jkU#BI>=Qnq z?&XHhGCnS06^oBkl&Ol5VVseQe8S9Aqz^Ytkw>UWF7u~tc9So&O}c{h#bFbe1~D4G zNybs5CM^xZV5o5Uv|5c6UwxD^!dsw>Lr4Wu$|Tek-m0MJk** zEIMw4f);*rScyZ8pdy&}Bz*?q?&}4e>14|$!YhdihG^?lF$$|TDwu_u4c7R{T`5s3 z1UWTUpoqVT#t{ zK^wqH9oDM5IE0#FoZdcUlP`Dgvs)rGyiK?0(eN$0AmA2l6lB_qk)bIx8gbBze8Nmn zqz^Ymkw>UWU{32zelLzOh-d*V4uOI%wpZ(H6>&`mf>ed7C4~Y zUZ4z~t+nVuzpz=7-yXM<#r7*?o|r*zlN=4)Bn!&sCMhTtR^VCPNP2)@@~zm%WIsfL zchTYS7bv+29J*8$dMkOTL13coA%z(wx@A6Q$7hiR+73n1ux7779s!@SBcbE&<6BnE z4YwdUOQS4N&Mm|!q(4}?Vx)~t8K6FLefe{-DKNcp*v}HWFtTk0Q}K3F~d*%ppTpFjgG zx4p{wb#8t*FNa*bvL>Xu;)sjVihoo-T)5PW*&-;*KRsF*05geCR?B-^xsSMYlOfX- z^2xWYoKj&q3hamRgr~2q2IrGQ#CL6~YtyZ)w(`r;HT)H{r!+(woSC=DUM4(tZsDie z9h$!r_Z6J*>M^zkhUF1|dn#nG&9b9?{^Br>h3!&;{nqihuqd7A4pF5KO`Yqt4J~fF zx_I~X+rGF{=@7|VYTug&$Y|0fwQ*T8_@SN%#`Kf6()U3tAzLe-3P9(|&kZSWQHSEt z(rs?6@U&HAv7%&RPW?2}c&Shr7|Kk?%xA87POe}EOSeZdi=_dngk-(z7YE>?Ot!}x z^rf4@-ZJW8#UzuFX?!HlRNNjVIxW>!4x!B85FxdL-b!+OIQ&A9a28#jpF8rs)<^i` z^_0RnopX0tI%FAT7+bGBNgZi8`>N_7Rzg%f^Ef!cxx;ODN(Jny zzvA-n3j~LJ!;$ESFWNpm@Q2GldB$atzoUmZ4Pk&by-`!|W*w8W)r8|@)ix~3W=q@f zDhkZ4nrOBKwXr8He|+AhY9_X<$gH6WoyGsfa5p1rNpYe8k>ZX%%&?8;9e|E!aKJ-o zJ=cy6x$y}^rVB6o9CEXD#q7c0zcaxAHu?GOz)GpB8sRHSxeA$D_JrG9*p;~&PNz104Hui(I-YSuc|rx2!THSETSFVk^=0OSZDLcL?YynC zcz8(HTrQp4D8j*(N901^gobKqWvbK9$5@K%mFV+s>XI3Ase zn7Q*@5A?YkaTtypJgYV-;E_T)kMJdIJbs*UJrrV&sI9xVjZJ)qj}%pvh2>)zq2(+? zoaa+o87%5#I(R6;jEyb2A#hHz6K5mwjX*w`x(pxcbvMZYzoS?`*;#>O)gN z)-!po*vHo+2YA%&U{R(y8I&fg1-^Ezn7R|#4tqnEB)=h+c1k+lrVC{CjCh|4*gP8i zMrHWyQ-MOZx7pI+BX0`@?g#Im+#+7X?7)Pw;pP*K-jS!G0NO7wIQz8pcXx%A1B?_+AuVQMo6()(MQ?J;Qirz~)LX7X6mVbDB@g z!wc?>9wJ+$BDo3W6w<%v4vjuLa8EdB7`Z3!cp2TlHG;x$*#Zw$W&|HIWPJc0fP)tB zD0Sqe)V$`|*6JxEn}|>a&1mAPtB__w)yp|<_bE&6*M2tmAigyoPuI&xAjC^;^RSZb zF$+DFd?sGK7c#@;f`Pk$_&}zmZKXM;8KXrEu(UsN>Un|%)aL>%dnanOQUF+X*l?Du z(({LIPdO>!M$z@?CTx?Ws%3)9TEB{(nv73Xh1dEB=`#9QyKtyZWPE)bd^e< z3%@W+0^H4+U3eN6)YKd;GGl+;jF~(AHahDzMBIQzN0cA-sh9;H$8ux^Y;>ri1UuiC9@uTs{G zI337z@ge7k;LnxXjZ^9>iLXoc@g=eAt-B;=)?7zB5`_y25~p6wR_MzUriBHMWhF)Q9NY;d+dRJB2J%cC?^uoiW%PRG&{W|S-6}G=! zP_3-a=EFSQEyRp(*w{uQNItkjaLcL#6+K7JE4|F z!QvswgeQC(V{F8onz0m2{2~`6vtl)}J8FBHvEid5GF1#p?+ZatPezcTsF)P7+^*u+ zwnjrWbY-gtD8+2PIh>tN{e41<2woWD_<7_Uiwakersq{dwj8fvf(gK*Kt;s$3lU9a zWDznmMg(IW!PAe3l2xC5Cg>Q=8&wso1E5A(M=-QOm*=Vj)DT6x3nWIlXAz$Xo_LMWY|_z}3$2vX4;0GiYH5_##y zN+v9XFhu0lrz~`$&#hW!*VYF;+4@}>ek6unZC>#=1!Ur$id1`LMYTwii1h%ehCycn zMCl}BvXKE`0+lvdQI>rBay3}Kxt-c+^S~_J?%dXxkt-)m6sCOc0Afs)uxaB|!{Zr7 z%7z8PH)3Oz9H3IS5b<>P0Hi~tt4grimm1uHQ;Uc51XxClIb7+to1RLs7)O)5S)f4dvz~?nywqmy7nZKYP0;r- z_t`Xb6h95JO5wagkxJDu*Viv0EvArwhJnsR4SJ!ae^2#|gfjE&E`HzUeynsa@NI~M zMJ;0PGj7(=CT;oX(&UAedQ0mvfvq9*ih4Ox0cke>Cxbl}$6K4`C9}!>F;GXL9?<^Q zy}0u7xv<1_N{Cg%ej=%K$7!#0$+&4z;QPjUrK;Sqnf(517m7Gi-XMCH>>_nxtFlK& zA^Y~z`1-LN{l_)DPy#0}Wf=OHXx^NycCEEtYlHR6nJSpVT8jhXpSEW!6Wk(_xO9UhXb)p(A-l%Mpd_I8tgP3Lfy-1Tr^U~m+Kb;i;#K&TiU`$(|M9c-P4ilaC;jk$k4Ef&nSUEWN6ssH)Lp79S{dH?;va- z`9}SG|Nf1h%9;(#>U`zZ%4Czyw+!KHS3tN9_vScC-FpNXpXUemssU|vqE#P;ZL*9% zs{whEqmUJ1wvFOv4w}ZJke|z-ahM&Hd32?A}UuPLU6CsGpOwDeb?<5UL!pS-E`2; zVv%KwzQyI4aI&<`8=X{v(9ihd3MFf9Om$S0IW9uSuWLHSYufdGTE?nlhM0M6n;?|< z?BjQBt&_cX1(Y{@1pOkS#heK1b4R8LJfBngM@CoMf={ z*N=8w$NKKAg4L4}{lK2&>y8|ff)hwvcPXz799X+&?%jf9e`5Rb4t&Vdj~Fu1Zq=|S zdqwX)-}obm)^n*A|JHLXzh}n{>N(=Gjw-EverdYD<}DwJ(K#L0ACg%%=^&wr+T!RG5y@3 zrma`k8$0hdmmt@qPj^@G&m-PcB(VM4ep#2oO+IRd3=N;ZiD>D0 zh%(eVbE^k8l}C*P?MEea=cl5KL0z>ZUP3E+Bvag8lBvu1MPHGA2*+?`vDM`@N8Mit zeNwDnSwH0Cc?=mlVbd=zTAO~mSLNY2S30Z1RTeINfEmdRrY#Epl0P$ z`??2OK5Tky0M2B`tVnlElMxRMnPzj8u5DGa+q*7Tm3QJzOmq2cGq~Xr_ZqJRer@j4jQOVFVfT}*e_DlRh7TX zbjwH41$BFrT{_o)f7J6=c5(9&oW3BprSj3~PuyD4Q5O#wFmFJD$oV3}ev+#;!lc5BdO7{jkwaD4N9QOs;+tb{I04?piJa;FP=DS{ z$k&P1kO9y2E+pH{|1fg9!N=tS@Qs?R(JG7ie1yG^m7e0vL&8Y=nBoz^2I)M((BD6SRU``f8XPn_8DacAVk_^pdG2 zm;BU>4ouI_zWD6Rbs>JBSh$Zbb1)Vl;N>s24w4z?aN#y zDq*rY|DmE}f04dJQ_@x=rwm~Zux8zU_Ni<7J3j#{@!jLvnWfB(`>^youFmVyVBk!; zD_^oi%SW4*V?k%OK4;Fa-U^?HflqVnX`40gq2+?>N2Q z+WDTU+X%T*nq&t6A5OOf>6yNKR(`HsP(QW6-Fz9@jBP^ak)D?=l8I3oG%t{5iWf?I zn70f<))S9nz?gE`++AGIM?F_U9)gqY+WnQDdee(S``bA`E_bA>o_Svb73ux~tNSzu zQ&ua?lHIFdU_3G@qhKsBc9>d5JJ1}WZS>_0lHTsAe`c&?t3eVuFjUzH;wY~#L7mdd z%2?C!0OV*RcUtAqFEzv+8;rvj^9#iVBpG~d+44$t9xfXa(SRGxYJtd{PVaEX)U|sA z-@mFu+@yg%_QGZ&u1#V7v4>%fJBRnwSD8XK>$t{jVO6zS7#fP?9U@p$YbAGX5{MziBa}(ja27G$EThg(3H&7kR+_TV9t~1fA>o+S5l%^E zU0DOz5DNituLny;jCa-2H~#gHSvOg(_~)lBgcC(;#IZ@Qjv9(#5O?l0pf0ZKHOH3|g*2FEg7zK-;mU%TKPh8Y_; z-zFYhO9SxzXU#WT{on0rF#8H9igSq8qa#S$UFu$ov?#6Tpy4xJ=$dqgU*t+!!^?Ro z?MTXX%LXTjM!;=O=b9I7=!9d6e6k^Y&xBhp2MFM4u2-RsC;Ufl`wwqq@htA8 zKZ|-Rk|QOz@3XGh8Qd~}#A)V&9=4ZGLEVeJYgPnLV@I5P-5xo9g`DcGW{m539P0?l zwR+|6DM*cWk73l&c#at5Awp7P48D4+xNPJq`O?*q?`@9dgYwyzbD97_g|y3vz;^6&C&*dDQBTkd6nwSj4b4sZlD+_c`IPZQEj zjLjEhY;Z~gb3tJnGlOg|_2Wfetd!SiObF9Ix46YIO;n>{DQLB^KT%pGy|fKe3|r(z ze+UW9Qg08*#ecVpZcn8r$G~#l1|tTI&%d_TJEeI+LMDBTcPXHoR14iqSR3(Skqff= z>Er@!oO+0iqOo*$+(#H}^a0czL-~`g$LXQ0*gFi~&K#mDu4PVFVVx}&8)%4sO*({r zcqCx*QupD(j`&hGPdEcBQQ&uE`eHHdJ5f^H`Vw5P>0}I^_i!+X@|v3E5E0{fMu?YW zwN96?YK|Key!+U6wR<8(R7*#K2vE|xH^8+z#t>E|eKVw8nECwGQ$4Mu^?*(Z9AqR) zHKLMw6TAsfe+_hxWmQmk)>wCICmh8eHtrw#f^NN>T3U-S zTgrY$D_#<5D#oYi-3gBT7|Vu~Z0dakGnlgj=j}wwjH0GXvKO+fqUo3z>C7D6wQ{Q= z5!XB#CF62Y39zc5pe&wEMjo1KE>0xitFO`L{Be}(*i85;rZNt4cthr?L`}jsM>o&w zuB{XE6%EM8Dw{`L+|j2BRpFS5tI*nP-uyB7KpQy@G_AJu8y5UQjAI~!>s&jH%2;q! zc)8-c(_0Xi>|^W}nN|E_RnbOye6pLvOu$OFPHYBWAL-uHu2=fJ<0^5SH)JZnzA@>x z))3O{w$6B{kOe-h7y4uok~`Pvx0c8yzoVFy#gc1i$H-9KT!+K zhxN#e0|H2W^vK4wl4^B^o)}fas4CNdtDQtNgT9CLqG&$6zin~_*K5aw?+`m}4ZH|k zBj99-WEv;Fid-XT#cf^`8A(UYG6#u$*Aq(Lhsnu%a;#pnA#2CE&>&%XMLvGpqoC>1 zTA@ehBr&0yeTd91BK+w*klm`*NgQFCc+2+eq2NNrS~yKgdBltcP0b1FPLrkhy8SU! z>A_fm@cqnWlFi4heA8*8>RD>bZRg&fPHF^GZHX}OB1W8Wk`A0)r=O8J4PJ2k6V zhdAvMB&JPP0cV}`{RVr_M9`ew4&el{7oNl+4Pv}uw$OAa$s5*ms9vX>KANSg*LwFv?q?cl5q4@XD$13!v()jh%7$Bd=8D&{495 zw1YA{CrWJ%Qj}^soSG|sJ{<$#*x+FdPKq3e9DOpFH|VipE*vKho3leOyMw(wVJ7Rf0Xv0#iw0+ zbetjj0XOlO|3v9cEIv5~xJe;K4-e+|jb|&4JqyqI&bZ9VpAfXT<1T_kvG#%y{!r0* z?cypP#Vc~IPgKFJG7hLC#`4H?_!Cal-&e+yk2P&c}6B2 zDyJfOlwQhpjX}Ml2d3<-r+>Ws(IJ|5{2abq(F&Su>Kcm0^3jp5reW~q&EXsz5GV#^ zgf9#rl)ymS|05Zg4nK+K*bb1&4l?PRz;(=YglN-KQ@(GaCQ%s)#~7q=B8-8aA_NgN zh$0L61WUJKnn&+mnI~5_A7i&BJepkB_nT{H@c=sHN4J6<1r4%Th@5}QMOs7+M6wu% z71>%BL1Ub(>^ALldPY_|QRxF1r27+D1O2p;hM=mZV1qFOVqPO@#3|NOhJ;D=E3G-3j}F9T_OPj+d{FkT%AKM~=h0;hbrY zWkOELijS~Rg(nd=l2ztk1rKQpm0L0zhfm=!IFq$~IWkbflV6KoMN9o{{l_++Q`TyO zZ1{6nTKXjL#^sE0=hM;Bsju$Wm}T=jeyOwQq+0k@SAWhyzmA(N;4^66G3n43_xJP5 z>KDf-a`K?)MnTHvl&P#88??T>zs9GFP%Q{8nq(Eh$I*yrooBTsnIIdIDH2B7ty?!e zSwu(BC5}(jX{8Tk+MSC-sh86skovfup-w7-snp7W?}87%j5D1Ru&~WNgRSG7(z;P| z=;vY-aK}g8Cv%Ta8Hfd>j!Ans)g-&;SBv?Al6J$YGcQ?LiB2_dtWEAg8c8-7)lL&D zYgr|2RSR8xcGj$Y5CBKn7v+(YL>83N^N#0%#>eW5LM)DzejUu}1;Lj`H|lsXuR1I% zYEtC4jlG_Ot%}n1pvku%IcDtqpfoRL;B6JTRDvD*quusD?HeMQ3*F>K@y0bgnO=ym z1chPjuX{?n;lS7cwSWj493q20GbIc*DdZaRD!kA8Z&#f!Q|u;5!4~iDRA3=e9**CG zOZ!|IlU3i$dw~wXDK5TUi)U9)@{iwtuo9P!t&~!q&W=F|eCd`8U8oHb)Q}hVZ_`rl ztp7sk`($xE0uk?@2A?j(@{UpH`o(_b2jXn*5N0C;u&=mmCl- z77$*mh^ZwHU123;E#B3KCRxiltn*43RC#Le)WOdTKZ%}(V_&>g;uWs(HY$|(wjo?2 zU4c}-|yLB|N@uQL; zWxw(hQSRaMC~kvR1nl}xs@d6kkocPp;LVq3;*`&a!&Zvn8OEMjsc$~9j`=VeHc-dA zeOX!mG?PE?s!mXei=as)fFi)yLjkz1RK}P8ET2TUSYx@U#pf+&h*ekMm;r8f%#aCF~B*dVbQx21p zrv`@DU(aB~8GYoqxxD^ml9RBeO_x+la8{^u@8=?`N56ZX{u*Iyap|0L3Ic0r1SYL$ z0+4DElTHPiR#Ym#YV`pxs*T4H)AZx$QS#6zKZ4O{saM(vI3J)ou&%rrfJ|5q`7r-*6Iis0Y-TPoZpcqsow`poEWB8{xy@L#@fXbN@ zTExNTNW#*mHob&1m*cU)i#Fr-D7k3O!9Cf}WL^>OMY)ilMB$O@6TNl_i!C=T*q)sr zwu6e$np=uPj3VEZB^M38%BplDlYW%65dmsl1%6E9a`rt&D;x)+DpsjA@D$45A)U%= zD-gpiQypGJ=OO8hSuum)v(GVV(auf!ZbCF_QG-b#(OCF16T%kXqo~D^6}#!SHTi;~ z;r(Qp+YChwHX?l2RmFyHHe=oGvvpGl<>`Hd$o(cX&KHG597fmu)Hx*Y)y(`~5Yxk& z`t0f#s*JnK=LdPW(mkrly`Hb<%#P=qb29$U$u)D#Q_#OW&3y!{Res(%zU70Ojo9Wa zXL*pou9EKkc`CU!P@JZW_u(o#p9Fs&d5Es+Qp50TQxKQLo+$$9kCrRic-vgaSbU;9GR5K|Zt}_>NQryY86r?ODnQN1?2y~AI$d8b68WKE1va9) zchcTUkm>kGk8C-(DrFlMD|fhwq{XV0Q+Jv|ZQ`MtFzJr<6PnS=cI*#u_Sa3oxck=FNIvDop%Bk6T)=z=^yd)acaWQ~U}6sQ zow)V)rpd3#Hs(JD@!Fc>N-z~o2r-2ro1658!COiZ!*0UvwS9*}f|JOioLLBl1pX0!`T)~S{(DKudn{A2dsT~G z3B33u@S@|6-%;<@lB9AR3zO!=+i&_MUsFJ*dQMdSyBcA|%;>bdb;JeqxxMY7gXsvn z!6Nb;Bo>Qg2}Ea9k@m!H^zup4J!=Zfg_uM_3+1%2(k?7HXnYd}OK>Gt9UH_q7F3p1 z{}}@+qkU1R$+=#Zzv}vU=C&euorxU&WCr+U(x`GKb>%Sty#S%aD8-K_Hjr@$-Gf!!-ps@D>ravHma>4&IQ@J!tWf~ z@(?F#xGxeWmbfpF(oTAo_U zWqw?)s8Elsg;}SSvprAFfvkVbXMGdp%*c#4$&%@Jg(p>KX@h7yVyA(V{gJDHwQ{2; z$;Ny3NFO{P{{b1F)6~Ty-~M7+!^pxo!k3Q1CqJ2^@z?1;2=$O7B@2ygR2Pv#YhPoW zzaZ;VC*%}K6GLx1^7-I*nrDJClqWZozDjw>`AKqGafh^E?`GRC^-Ss=MnO=~+)wPF z(!*a~$#w-38ctbWduan$%ZXWEjC&J$VVOzac5Pvc4LH!{G`VR(ehsX8E^LRhrNmhN zH}4!5Xdk%nn=+-{XOEkQ3N^a;?a~Gu!3O@z#HdNq7F=@6U9VJ!EhR5S(>9=?HDQOv ztmmnWk83S#Xgp>Z7Omj7LpV5`+dMa3zoiu3x;`r@yxoi2MR}v{xw#*;2g*C%S}N${ zU7N1E%sv!!1@2ROrq4`N7uW?&P)MD0_;dtd7bq(QLP;>J2LEn^3<(%hP16hw7>d*2 zAHr6+BsO9Ys>M)agBWUGO>5mGVbi?0p97#C@#r;+ZrEsnV;UUY1fG=^tO&tmhSp#ubdk_Aogw8Z|lBJz=RL~R%$m1j6C=*irIdoMSLDk=T zbtd>yJ%KT|HPvY31VekO)<|^+vS5c8#~MX0vLmD4lrLfJ36b96BStyi8DX&kW$hHL zoi--{I|OCJa)2%@_OsrxP9q?QMQUbjdzJJ|P7H#X37puC_Ka;DZS12Z4@sln!MBpD zGL#Yp0xX-jYnXxNBnciy148o%q_E=jo$x-Dl#dwm<0@u1dGAp)a_57WMPYkKd+W$+ z&st12v>d)0D_@N`9B_m3U6pFfW^{j1JMbJTu4PUt7^)bLJD+Z%smP*VvIAG7cw z$jOB2=}?3s;8{oWG+g>zQbax2eAg32pmGpUuwrqcq-5Ldlg z1;Qm=_EYluLwYbsYIt5G_(BHuff>=56xSArg>3kggTVyFD<}O!7y)Aa^q7twqjaCL zanTQqNixfs0t|7&qCKU;+S7M%Xncc*L3mpLiHNBj>KHabO4Qm{x5w6Xs}*pqfDvd8 znhDHVlN4klCa&{gPd)8;rJ5;bL&}p&KJ@!nSFa8L7*=oPn-zv z=ftVe0EH13jt2c!WWqcMu+RW$oP1vCSj`9Z$NO|R26-zCYcL2Z3ViJ`CurN?~;Ae0l#1{4SD=+Mw9Q4v|xo<8KVI0_E zp<#Ja#>vOR%XaDyyvwDe#Q0by^2_RzE$>;&lT7X}L#b80=0(N?LtoET0qkzO|a3x*!FWT$m>^9Y#KH;bJ!WVJ6$Y$8s*TbqB!- zH^_Lnma!I}e5)0S?4yFN{QX+1%h+OlDUrshl*?pcw3oG|d_v6Pd%Q5c!Y{Q=@CkB46ic?Qca z=NP;vxPj=QwqJJbjrucI9jt?Y&TS2*c{W9yh_BWwiDC;xJ)N?*@MR7L+-m zAgA#_LkrAeSo!UfmDSpDvlJ<6Z@sM$m-BQjzTtt187E=!aC&L5upewg{WpZ$hO!mdzo2oBpdS9|O;^JWs~^Gdz0(fIpm@{F!vXg2Ze8FCG;g-w zx-^j=Q#R_wKG3j#uA~&8ieeUMZJ5SSWnLJl%b=v_?n68LU^*$#x=}vCmn=4IS$XEXdY5S-|^qvVfsH z*34k(HLO1Kd#(R*fP4(Xg?fygvyNKiOV27voRlbff=02&eczk9!Ns)Fk;Q%Z8O6gT z?wYnIXkWbZwX$F3?iWuk^ho-we}LMN6zMl)QN>3!vapV^jpC2n6jRs`>xaAe0pp}t zR-o)m?L}5d=SOIGwKj5{h#sn4ZWUzP%{#L+`@DRvgvzoRsww?(D~l^**U!lyHJsMT zU72gPK*FfN>zj!=e&XlFJ;f~DZ$f_HtxqG5{noh+*}g8Uv`5TmxG5KWx@;2JNg_XUkO9}y#-c-WgZGdpoj60_6`SfIQGq)5=~_ zT9wJv(FW;%4nqO(0RZRq>0eQEP~Z@lZ1m{=jsF)u$1vTI7#RRyGX((9{{`O!A^jWP z*}?j6g3||$nLh+`Gyf2jeElc>P2dSRfBS%#qdCagMnK?j{zdQ`<^LmKvUM;4+Wt)g z$U_JJq0wFe{3nn9#=mKrO|=z^d!w{h5dnZwj{jRGc(i}fxcsY3Z7f<%uMl`4dZ_=v z(?I_d|Avp((^gD)y`)iqWT6jvVgD-&G)S%gw@g;1X7(Txpoyi~-$@`(A<^AJSR9o8 zLH}?3o23Sl#21-1L_$btD41&hp_q;MCo0Lp!a)iGK!iM<-T(l*jgaaC{vSvj58D6$ literal 0 HcmV?d00001 diff --git a/src/InnoSetup/MapWinGIS_TLB.pas b/src/InnoSetup/MapWinGIS_TLB.pas index 804564784856b8443ef59cfd4fc69c03ed9a2700..8510093fbeaaaddfeb4ff4e3b7a63ed93dc2e391 100644 GIT binary patch literal 1218056 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

dV~oJaf_1e4?w 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

S%%$@kVnrR)89RjUo7M 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 From 58cc11f44b045036dda868b4172fa063a58c3c57 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Sat, 2 Nov 2019 20:07:51 -0700 Subject: [PATCH 06/15] MWGIS-198; revert many of the Shapefile locking code, to be re-evaluated and reintroduced as necessary; --- src/COM classes/Charts.cpp | 881 ++- src/COM classes/FieldStatOperations.cpp | 2 - src/COM classes/OgrDatasource.cpp | 2 - src/COM classes/OgrLayer.cpp | 279 +- src/COM classes/OgrLayer.h | 2 - src/COM classes/ShapeEditor.cpp | 12 +- src/COM classes/Shapefile.cpp | 7083 +++++++++---------- src/COM classes/Shapefile.h | 1 - src/COM classes/Shapefile_Edit.cpp | 2347 +++--- src/COM classes/Shapefile_Geoprocessing.cpp | 122 +- src/COM classes/Shapefile_LabelsCharts.cpp | 30 +- src/COM classes/Shapefile_Optimizations.cpp | 32 +- src/COM classes/Shapefile_ReadWrite.cpp | 28 +- src/COM classes/Shapefile_Selection.cpp | 24 +- src/COM classes/Shapefile_SpatialIndex.cpp | 858 +-- src/COM classes/Shapefile_Validation.cpp | 21 +- src/COM classes/Utils.cpp | 12 +- src/COM classes/Utils_Shapefile.cpp | 14 - src/ComHelpers/CallbackHelper.h | 3 - src/ComHelpers/ChartsHelper.cpp | 3 - src/ComHelpers/FieldHelper.cpp | 2 - src/ComHelpers/LabelsHelper.cpp | 4 - src/Control/Map_Drawing.cpp | 39 +- src/Control/Map_Shapefile.cpp | 2 - src/Control/Map_Snapshot.cpp | 2 +- src/Drawing/ChartDrawing.cpp | 9 - src/Drawing/ShapefileDrawing.cpp | 1 - src/Editor/GroupOperation.cpp | 5 - src/MapWinGIS.idl | 1 - src/Ogr/Ogr2RawData.cpp | 276 +- src/Ogr/Ogr2RawData.h | 9 +- src/Ogr/Ogr2Shape.cpp | 125 - src/Ogr/Ogr2Shape.h | 1 - src/Ogr/OgrLoader.cpp | 23 +- src/Ogr/OgrLoader.h | 5 +- src/Ogr/Shape2Ogr.cpp | 3 - src/Processing/ClipperConverter.cpp | 1 - src/Shapefile/GeoProcessing.cpp | 7 - src/Structures/Layer.cpp | 106 +- src/Structures/Layer.h | 13 +- src/Structures/Structures.h | 9 +- 41 files changed, 6067 insertions(+), 6332 deletions(-) diff --git a/src/COM classes/Charts.cpp b/src/COM classes/Charts.cpp index 400dcab7..a06bd2b8 100644 --- a/src/COM classes/Charts.cpp +++ b/src/COM classes/Charts.cpp @@ -1,13 +1,13 @@ /************************************************************************************** * File name: Charts.cpp * - * Project: MapWindow Open Source (MapWinGis ActiveX control) + * Project: MapWindow Open Source (MapWinGis ActiveX control) * Description: Implementation of CCharts * ************************************************************************************** * The contents of this file are subject to the Mozilla Public License Version 1.1 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at http://www.mozilla.org/mpl/ + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at http://www.mozilla.org/mpl/ * See the License for the specific language governing rights and limitations * under the License. * @@ -18,8 +18,8 @@ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. - ************************************************************************************** - * Contributor(s): + ************************************************************************************** + * Contributor(s): * (Open source contributors should list themselves and their modifications here). */ // Sergei Leschinski (lsu) 19 june 2010 - created the file. // Paul Meems sept. 2019 - MWGIS-183: Merge .NET and VB drawing functions @@ -39,14 +39,14 @@ STDMETHODIMP CCharts::get_Key(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; + USES_CONVERSION; *pVal = OLE2BSTR(_key); return S_OK; } STDMETHODIMP CCharts::put_Key(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - ::SysFreeString(_key); + ::SysFreeString(_key); USES_CONVERSION; _key = OLE2BSTR(newVal); return S_OK; @@ -58,14 +58,14 @@ STDMETHODIMP CCharts::put_Key(BSTR newVal) STDMETHODIMP CCharts::get_VisibilityExpression(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; + USES_CONVERSION; *pVal = OLE2BSTR(_expression); return S_OK; } STDMETHODIMP CCharts::put_VisibilityExpression(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - ::SysFreeString(_expression); + ::SysFreeString(_expression); USES_CONVERSION; _expression = OLE2BSTR(newVal); return S_OK; @@ -77,14 +77,14 @@ STDMETHODIMP CCharts::put_VisibilityExpression(BSTR newVal) STDMETHODIMP CCharts::get_Caption(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; + USES_CONVERSION; *pVal = OLE2BSTR(_caption); return S_OK; } STDMETHODIMP CCharts::put_Caption(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - ::SysFreeString(_caption); + ::SysFreeString(_caption); USES_CONVERSION; _caption = OLE2BSTR(newVal); return S_OK; @@ -93,48 +93,48 @@ STDMETHODIMP CCharts::put_Caption(BSTR newVal) // ********************************************************** // get/put_Visible() // ********************************************************** -STDMETHODIMP CCharts::get_Visible( VARIANT_BOOL *retVal ) +STDMETHODIMP CCharts::get_Visible(VARIANT_BOOL *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.visible; + *retVal = _options.visible; return S_OK; } -STDMETHODIMP CCharts::put_Visible( VARIANT_BOOL newVal ) +STDMETHODIMP CCharts::put_Visible(VARIANT_BOOL newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.visible = newVal; + _options.visible = newVal; return S_OK; } // ********************************************************** // get/put_AvoidCollisions() // ********************************************************** -STDMETHODIMP CCharts::get_AvoidCollisions( VARIANT_BOOL *retVal ) +STDMETHODIMP CCharts::get_AvoidCollisions(VARIANT_BOOL *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.avoidCollisions; + *retVal = _options.avoidCollisions; return S_OK; } -STDMETHODIMP CCharts::put_AvoidCollisions( VARIANT_BOOL newVal ) +STDMETHODIMP CCharts::put_AvoidCollisions(VARIANT_BOOL newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.avoidCollisions = newVal; + _options.avoidCollisions = newVal; return S_OK; } // ********************************************************** // get/put_ChartType() // ********************************************************** -STDMETHODIMP CCharts::get_ChartType( tkChartType* retVal ) +STDMETHODIMP CCharts::get_ChartType(tkChartType* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.chartType; + *retVal = _options.chartType; return S_OK; } -STDMETHODIMP CCharts::put_ChartType( tkChartType newVal ) -{ +STDMETHODIMP CCharts::put_ChartType(tkChartType newVal) +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.chartType = newVal; + _options.chartType = newVal; return S_OK; } @@ -144,13 +144,13 @@ STDMETHODIMP CCharts::put_ChartType( tkChartType newVal ) STDMETHODIMP CCharts::get_BarWidth(long* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.barWidth; + *retVal = _options.barWidth; return S_OK; } STDMETHODIMP CCharts::put_BarWidth(long newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.barWidth = newVal; + _options.barWidth = newVal; return S_OK; } @@ -160,55 +160,55 @@ STDMETHODIMP CCharts::put_BarWidth(long newVal) STDMETHODIMP CCharts::get_BarHeight(long* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.barHeight; + *retVal = _options.barHeight; return S_OK; } STDMETHODIMP CCharts::put_BarHeight(long newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.barHeight = newVal; + _options.barHeight = newVal; return S_OK; } // ********************************************************** // get/put_PieChartRadius() // ********************************************************** -STDMETHODIMP CCharts::get_PieRadius (long* retVal) +STDMETHODIMP CCharts::get_PieRadius(long* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.radius; + *retVal = _options.radius; return S_OK; } -STDMETHODIMP CCharts::put_PieRadius (long newVal) +STDMETHODIMP CCharts::put_PieRadius(long newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.radius = newVal; + _options.radius = newVal; return S_OK; } // ********************************************************** // get/put_PieChartRotation() // ********************************************************** -STDMETHODIMP CCharts::get_PieRotation (double* retVal) +STDMETHODIMP CCharts::get_PieRotation(double* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.rotation; + *retVal = _options.rotation; return S_OK; } -STDMETHODIMP CCharts::put_PieRotation (double newVal) +STDMETHODIMP CCharts::put_PieRotation(double newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.rotation = newVal; + _options.rotation = newVal; return S_OK; } // ********************************************************** // get_NumBars // ********************************************************** -STDMETHODIMP CCharts::get_NumFields (long* retVal) +STDMETHODIMP CCharts::get_NumFields(long* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _bars.size(); + *retVal = _bars.size(); return S_OK; } @@ -218,7 +218,7 @@ STDMETHODIMP CCharts::get_NumFields (long* retVal) STDMETHODIMP CCharts::AddField2(long FieldIndex, OLE_COLOR Color) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - VARIANT_BOOL vbretval; + VARIANT_BOOL vbretval; this->InsertField2(_bars.size(), FieldIndex, Color, &vbretval); return S_OK; } @@ -226,16 +226,16 @@ STDMETHODIMP CCharts::AddField2(long FieldIndex, OLE_COLOR Color) STDMETHODIMP CCharts::AddField(IChartField* Field, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if (!Field) - { - ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); - *retVal = VARIANT_FALSE; - } - else - { - _bars.push_back(Field); - Field->AddRef(); - } + if (!Field) + { + ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + *retVal = VARIANT_FALSE; + } + else + { + _bars.push_back(Field); + Field->AddRef(); + } *retVal = VARIANT_TRUE; return S_OK; } @@ -243,28 +243,28 @@ STDMETHODIMP CCharts::AddField(IChartField* Field, VARIANT_BOOL* retVal) // ********************************************************** // InsertField2() // ********************************************************** -STDMETHODIMP CCharts::InsertField2 (long Index, long FieldIndex, OLE_COLOR Color, VARIANT_BOOL* retVal) +STDMETHODIMP CCharts::InsertField2(long Index, long FieldIndex, OLE_COLOR Color, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if(Index < 0 || Index > (long)_bars.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - *retVal = VARIANT_FALSE; - } - else - { - IChartField* chartField = NULL; - CoCreateInstance(CLSID_ChartField,NULL,CLSCTX_INPROC_SERVER,IID_IChartField,(void**)&chartField); - if (chartField) + if (Index < 0 || Index >(long)_bars.size()) { - chartField->put_Index(FieldIndex); - chartField->put_Color(Color); + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + *retVal = VARIANT_FALSE; } + else + { + IChartField* chartField = NULL; + CoCreateInstance(CLSID_ChartField, NULL, CLSCTX_INPROC_SERVER, IID_IChartField, (void**)&chartField); + if (chartField) + { + chartField->put_Index(FieldIndex); + chartField->put_Color(Color); + } - if (Index == _bars.size()) _bars.push_back(chartField); - else _bars.insert(_bars.begin() + Index, chartField); - *retVal = VARIANT_TRUE; - } + if (Index == _bars.size()) _bars.push_back(chartField); + else _bars.insert(_bars.begin() + Index, chartField); + *retVal = VARIANT_TRUE; + } return S_OK; } @@ -274,25 +274,25 @@ STDMETHODIMP CCharts::InsertField2 (long Index, long FieldIndex, OLE_COLOR Color STDMETHODIMP CCharts::InsertField(long Index, IChartField* Field, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if(Index < 0 || Index > (long)_bars.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - *retVal = VARIANT_FALSE; - } - else - { - if (!Field) + if (Index < 0 || Index >(long)_bars.size()) { - ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); *retVal = VARIANT_FALSE; } else { - _bars.insert(_bars.begin() + Index, Field); - Field->AddRef(); - *retVal = VARIANT_TRUE; + if (!Field) + { + ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + *retVal = VARIANT_FALSE; + } + else + { + _bars.insert(_bars.begin() + Index, Field); + Field->AddRef(); + *retVal = VARIANT_TRUE; + } } - } return S_OK; } @@ -302,17 +302,17 @@ STDMETHODIMP CCharts::InsertField(long Index, IChartField* Field, VARIANT_BOOL* STDMETHODIMP CCharts::RemoveField(long Index, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if(Index < 0 || Index > (long)_bars.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - *retVal = VARIANT_FALSE; - } - else - { - _bars[Index]->Release(); - _bars.erase(_bars.begin() + Index); - *retVal = VARIANT_TRUE; - } + if (Index < 0 || Index >(long)_bars.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + *retVal = VARIANT_FALSE; + } + else + { + _bars[Index]->Release(); + _bars.erase(_bars.begin() + Index); + *retVal = VARIANT_TRUE; + } return S_OK; } @@ -322,7 +322,7 @@ STDMETHODIMP CCharts::RemoveField(long Index, VARIANT_BOOL* retVal) STDMETHODIMP CCharts::MoveField(long OldIndex, long NewIndex, VARIANT_BOOL* vbretval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - ErrorMessage(tkPROPERTY_NOT_IMPLEMENTED); + ErrorMessage(tkPROPERTY_NOT_IMPLEMENTED); return S_OK; } @@ -332,17 +332,17 @@ STDMETHODIMP CCharts::MoveField(long OldIndex, long NewIndex, VARIANT_BOOL* vbre STDMETHODIMP CCharts::Generate(tkLabelPositioning Position, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if (!_shapefile) - { - ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); - *retVal = VARIANT_FALSE; - } - else - { - ((CShapefile*)_shapefile)->SetChartsPositions(Position); - _chartsExist = true; - *retVal = VARIANT_TRUE; - } + if (!_shapefile) + { + ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); + *retVal = VARIANT_FALSE; + } + else + { + ((CShapefile*)_shapefile)->SetChartsPositions(Position); + _chartsExist = true; + *retVal = VARIANT_TRUE; + } return S_OK; } @@ -374,13 +374,13 @@ IShapefile* CCharts::get_ParentShapefile() STDMETHODIMP CCharts::get_Thickness(double* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.thickness; + *retVal = _options.thickness; return S_OK; } STDMETHODIMP CCharts::put_Thickness(double newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.thickness = newVal; + _options.thickness = newVal; return S_OK; } @@ -390,13 +390,13 @@ STDMETHODIMP CCharts::put_Thickness(double newVal) STDMETHODIMP CCharts::get_Tilt(double* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.tilt; + *retVal = _options.tilt; return S_OK; } STDMETHODIMP CCharts::put_Tilt(double newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.tilt = newVal; + _options.tilt = newVal; return S_OK; } @@ -406,13 +406,13 @@ STDMETHODIMP CCharts::put_Tilt(double newVal) STDMETHODIMP CCharts::get_PieRadius2(LONG* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.radius2; + *retVal = _options.radius2; return S_OK; } STDMETHODIMP CCharts::put_PieRadius2(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.radius2 = newVal; + _options.radius2 = newVal; return S_OK; } @@ -422,13 +422,13 @@ STDMETHODIMP CCharts::put_PieRadius2(LONG newVal) STDMETHODIMP CCharts::get_SizeField(LONG* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.sizeField; + *retVal = _options.sizeField; return S_OK; } STDMETHODIMP CCharts::put_SizeField(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.sizeField = newVal; + _options.sizeField = newVal; return S_OK; } @@ -438,13 +438,13 @@ STDMETHODIMP CCharts::put_SizeField(LONG newVal) STDMETHODIMP CCharts::get_NormalizationField(LONG* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.normalizationField; + *retVal = _options.normalizationField; return S_OK; } STDMETHODIMP CCharts::put_NormalizationField(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.normalizationField = newVal; + _options.normalizationField = newVal; return S_OK; } @@ -454,13 +454,13 @@ STDMETHODIMP CCharts::put_NormalizationField(LONG newVal) STDMETHODIMP CCharts::get_UseVariableRadius(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.useVariableRadius; + *retVal = _options.useVariableRadius; return S_OK; } STDMETHODIMP CCharts::put_UseVariableRadius(VARIANT_BOOL newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.useVariableRadius = newVal?true:false; + _options.useVariableRadius = newVal ? true : false; return S_OK; } @@ -470,16 +470,16 @@ STDMETHODIMP CCharts::put_UseVariableRadius(VARIANT_BOOL newVal) STDMETHODIMP CCharts::get_Transparency(SHORT* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = (short)_options.transparency; + *retVal = (short)_options.transparency; return S_OK; } STDMETHODIMP CCharts::put_Transparency(SHORT newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if (newVal >= 0 && newVal <= 255) - _options.transparency = newVal; - else - ErrorMessage(tkINVALID_PARAMETER_VALUE); + if (newVal >= 0 && newVal <= 255) + _options.transparency = newVal; + else + ErrorMessage(tkINVALID_PARAMETER_VALUE); return S_OK; } @@ -489,13 +489,13 @@ STDMETHODIMP CCharts::put_Transparency(SHORT newVal) STDMETHODIMP CCharts::get_LineColor(OLE_COLOR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.lineColor; + *retVal = _options.lineColor; return S_OK; } STDMETHODIMP CCharts::put_LineColor(OLE_COLOR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.lineColor = newVal; + _options.lineColor = newVal; return S_OK; } @@ -505,29 +505,29 @@ STDMETHODIMP CCharts::put_LineColor(OLE_COLOR newVal) STDMETHODIMP CCharts::get_Use3DMode(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.use3Dmode; + *retVal = _options.use3Dmode; return S_OK; } STDMETHODIMP CCharts::put_Use3DMode(VARIANT_BOOL newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.use3Dmode = newVal?true:false; + _options.use3Dmode = newVal ? true : false; return S_OK; } // ********************************************************** // VerticalPosition // ********************************************************** -STDMETHODIMP CCharts::get_VerticalPosition (tkVerticalPosition* retVal) +STDMETHODIMP CCharts::get_VerticalPosition(tkVerticalPosition* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _options.verticalPosition; + *retVal = _options.verticalPosition; return S_OK; } -STDMETHODIMP CCharts::put_VerticalPosition (tkVerticalPosition newVal) +STDMETHODIMP CCharts::put_VerticalPosition(tkVerticalPosition newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _options.verticalPosition = newVal; + _options.verticalPosition = newVal; return S_OK; } @@ -537,53 +537,53 @@ STDMETHODIMP CCharts::put_VerticalPosition (tkVerticalPosition newVal) STDMETHODIMP CCharts::get_Chart(long ShapeIndex, IChart** retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - - if (!_shapefile) - { - ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); - *retVal = NULL; - return S_OK; - } - else - { - std::vector* positions = ((CShapefile*)_shapefile)->get_ShapeVector(); - if ( ShapeIndex < 0 || ShapeIndex > (long)positions->size()) + + if (!_shapefile) { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); *retVal = NULL; return S_OK; } else { - IChart* chart = NULL; - CoCreateInstance(CLSID_Chart,NULL,CLSCTX_INPROC_SERVER,IID_IChart,(void**)&chart); - if (chart) + std::vector* positions = ((CShapefile*)_shapefile)->get_ShapeVector(); + if (ShapeIndex < 0 || ShapeIndex >(long)positions->size()) { - ShapeRecord* data = (*positions)[ShapeIndex]; - ((CChart*)chart)->put_ChartData(reinterpret_cast(data->chart)); + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + *retVal = NULL; + return S_OK; + } + else + { + IChart* chart = NULL; + CoCreateInstance(CLSID_Chart, NULL, CLSCTX_INPROC_SERVER, IID_IChart, (void**)&chart); + if (chart) + { + ShapeRecord* data = (*positions)[ShapeIndex]; + ((CChart*)chart)->put_ChartData(reinterpret_cast(data->chart)); + } + *retVal = chart; } - *retVal = chart; } - } return S_OK; } // ********************************************************** // get_Field // ********************************************************** -STDMETHODIMP CCharts::get_Field (long FieldIndex, IChartField** retVal) +STDMETHODIMP CCharts::get_Field(long FieldIndex, IChartField** retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - - if(FieldIndex < 0 || FieldIndex > (long)_bars.size() - 1) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - *retVal = _bars[FieldIndex]; - (*retVal)->AddRef(); - } + + if (FieldIndex < 0 || FieldIndex >(long)_bars.size() - 1) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + *retVal = _bars[FieldIndex]; + (*retVal)->AddRef(); + } return S_OK; } @@ -593,8 +593,8 @@ STDMETHODIMP CCharts::get_Field (long FieldIndex, IChartField** retVal) STDMETHODIMP CCharts::get_LastErrorCode(long *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - - *pVal = _lastErrorCode; + + *pVal = _lastErrorCode; _lastErrorCode = tkNO_ERROR; return S_OK; @@ -606,8 +606,8 @@ STDMETHODIMP CCharts::get_LastErrorCode(long *pVal) STDMETHODIMP CCharts::get_ErrorMsg(long ErrorCode, BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - - USES_CONVERSION; + + USES_CONVERSION; *pVal = A2BSTR(ErrorMsg(ErrorCode)); return S_OK; @@ -619,8 +619,8 @@ STDMETHODIMP CCharts::get_ErrorMsg(long ErrorCode, BSTR *pVal) STDMETHODIMP CCharts::get_GlobalCallback(ICallback **pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *pVal = _globalCallback; - if( _globalCallback ) + *pVal = _globalCallback; + if (_globalCallback) { _globalCallback->AddRef(); } @@ -629,7 +629,7 @@ STDMETHODIMP CCharts::get_GlobalCallback(ICallback **pVal) STDMETHODIMP CCharts::put_GlobalCallback(ICallback *newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - ComHelper::SetRef(newVal, (IDispatch**)&_globalCallback); + ComHelper::SetRef(newVal, (IDispatch**)&_globalCallback); return S_OK; } @@ -639,24 +639,24 @@ STDMETHODIMP CCharts::put_GlobalCallback(ICallback *newVal) STDMETHODIMP CCharts::get_Count(long *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if(!_shapefile) - { - ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); - *retVal = 0; - } - else - { - if (_chartsExist) + if (!_shapefile) { - long numShapes; - _shapefile->get_NumShapes(&numShapes); - *retVal = numShapes; + ErrorMessage(tkPARENT_SHAPEFILE_NOT_EXISTS); + *retVal = 0; } else { - *retVal = 0; + if (_chartsExist) + { + long numShapes; + _shapefile->get_NumShapes(&numShapes); + *retVal = numShapes; + } + else + { + *retVal = 0; + } } - } return S_OK; } @@ -666,10 +666,10 @@ STDMETHODIMP CCharts::get_Count(long *retVal) STDMETHODIMP CCharts::ClearFields() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - for (unsigned int i = 0; i < _bars.size(); i++) - { - _bars[i]->Release(); - } + for (unsigned int i = 0; i < _bars.size(); i++) + { + _bars[i]->Release(); + } _bars.clear(); return S_OK; } @@ -680,10 +680,9 @@ STDMETHODIMP CCharts::ClearFields() STDMETHODIMP CCharts::Clear() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - IShapefile* sf = this->get_ParentShapefile(); + IShapefile* sf = this->get_ParentShapefile(); if (sf) { - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); std::vector* data = ((CShapefile*)sf)->get_ShapeVector(); for (unsigned int i = 0; i < data->size(); i++) { @@ -706,13 +705,13 @@ STDMETHODIMP CCharts::Clear() STDMETHODIMP CCharts::DrawChart(int hdc, float x, float y, VARIANT_BOOL hideLabels, OLE_COLOR backColor, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - - if (!hdc) - { - ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); - return S_OK; - } - + + if (!hdc) + { + ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + return S_OK; + } + CDC* dc = CDC::FromHandle((HDC)hdc); *retVal = DrawChartCore(dc, x, y, hideLabels, backColor); return S_OK; @@ -740,7 +739,7 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide ErrorMessage(tkFAILED_TO_OBTAIN_DC); return VARIANT_FALSE; } - + long numBars; this->get_NumFields(&numBars); bool noFields = false; @@ -753,24 +752,24 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide // initializing graphics Gdiplus::Graphics g(dc->GetSafeHdc()); - long alpha =_options.transparency << 24; + long alpha = _options.transparency << 24; Gdiplus::Pen pen(Utility::OleColor2GdiPlus(_options.lineColor, (BYTE)_options.transparency)); Gdiplus::Color clr = Utility::OleColor2GdiPlus(backColor, 255); Gdiplus::SolidBrush brushBackground(clr); Gdiplus::Pen penBackground(clr); - + CFont* oldFont = NULL; CFont fnt; CBrush brushFrame(_options.valuesFrameColor); - + // values font initialization bool vertical = (_options.valuesStyle == vsVertical); CString sFormat = "%g"; // format for numbers if (_options.valuesVisible && !hideLabels) { - LOGFONT lf; + LOGFONT lf; CString s(_options.valuesFontName); fnt.CreatePointFont(_options.valuesFontSize * 10, s); @@ -780,16 +779,16 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide { lf.lfEscapement = 900; } - + dc->SetTextColor(_options.valuesFontColor); lf.lfItalic = (BYTE)_options.valuesFontItalic; - if (_options.valuesFontBold) + if (_options.valuesFontBold) lf.lfWeight = FW_BOLD; - else + else lf.lfWeight = 0; - + fnt.DeleteObject(); fnt.CreateFontIndirectA(&lf); oldFont = dc->SelectObject(&fnt); @@ -803,31 +802,31 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide // drawing pie charts if (_options.chartType == chtPieChart) { - Gdiplus::REAL pieThickness = (Gdiplus::REAL)(_options.thickness *_options.tilt/90.0); - + Gdiplus::REAL pieThickness = (Gdiplus::REAL)(_options.thickness *_options.tilt / 90.0); + Gdiplus::REAL pieHeight; if (_options.use3Dmode) - pieHeight = (Gdiplus::REAL)(_options.radius * (1.0 -_options.tilt/90.0) * 2.0); + pieHeight = (Gdiplus::REAL)(_options.radius * (1.0 - _options.tilt / 90.0) * 2.0); else - pieHeight =(Gdiplus::REAL)(_options.radius * 2.0); + pieHeight = (Gdiplus::REAL)(_options.radius * 2.0); + + Gdiplus::REAL pieWidth = (Gdiplus::REAL)(_options.radius * 2.0); - Gdiplus::REAL pieWidth =(Gdiplus::REAL)(_options.radius * 2.0); - double sum = 0.0; std::vector values; - + for (int j = 0; j < numBars; j++) { - values.push_back(100.0/(double)numBars); + values.push_back(100.0 / (double)numBars); sum += values[j]; } - + Gdiplus::REAL xStart = (Gdiplus::REAL)x; //0 Gdiplus::REAL yStart = (Gdiplus::REAL)y; //0 - + Gdiplus::REAL startAngle = 0.0, sweepAngle = 0.0; Gdiplus::GraphicsPath path; - + for (int j = 0; j < numBars; j++) { // retrieving color @@ -842,27 +841,27 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide this->get_Field(j, &fld); fld->get_Color(&color); } - + // initializing brushes Gdiplus::Color clr(alpha | BGR_TO_RGB(color)); Gdiplus::Color clrDimmed = Utility::ChangeBrightness(color, -100, alpha); Gdiplus::SolidBrush brush(clr); Gdiplus::SolidBrush brushDimmed(clrDimmed); - sweepAngle = (Gdiplus::REAL)(values[j]/sum * 360.0); + sweepAngle = (Gdiplus::REAL)(values[j] / sum * 360.0); g.FillPie(&brushBackground, xStart, yStart, pieWidth, pieHeight, startAngle, sweepAngle); g.FillPie(&brush, xStart, yStart, pieWidth, pieHeight, startAngle, sweepAngle); path.AddPie(xStart, yStart, pieWidth, pieHeight, startAngle, sweepAngle); - + // 3D mode - if ( startAngle < 180.0 &&_options.use3Dmode) + if (startAngle < 180.0 &&_options.use3Dmode) { Gdiplus::GraphicsPath pathBottom; if (startAngle + sweepAngle > 180.0) pathBottom.AddArc(xStart, yStart + pieThickness, pieWidth, pieHeight, startAngle, 180 - startAngle); else pathBottom.AddArc(xStart, yStart + pieThickness, pieWidth, pieHeight, startAngle, sweepAngle); - + Gdiplus::PathData pathData; pathBottom.GetPathData(&pathData); Gdiplus::PointF* pntStart, *pntEnd; @@ -879,9 +878,9 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide } else pathBottom.AddArc(xStart, yStart, pieWidth, pieHeight, startAngle + sweepAngle, -sweepAngle); - + pathBottom.AddLine(pntStart->X, pntStart->Y - (Gdiplus::REAL)pieThickness, pntStart->X, pntStart->Y); - + g.FillPath(&brushBackground, &pathBottom); g.FillPath(&brushDimmed, &pathBottom); g.DrawPath(&penBackground, &pathBottom); @@ -897,12 +896,12 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide { CCollisionList collisionList; startAngle = 0.0; - xStart += pieWidth/2.0f; - yStart += pieHeight/2.0f; - + xStart += pieWidth / 2.0f; + yStart += pieHeight / 2.0f; + for (int j = 0; j < numBars; j++) { - sweepAngle = (Gdiplus::REAL)(values[j]/sum * 360.0); + sweepAngle = (Gdiplus::REAL)(values[j] / sum * 360.0); // label drawing ValueRectangle value; @@ -910,39 +909,39 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide value.string = Utility::FormatNumber(values[j], CString("%g")); dc->DrawText(value.string, rect, DT_CALCRECT); // add alignment - - Gdiplus::REAL labelAngle = startAngle + sweepAngle/2.0f + 90.0f; + + Gdiplus::REAL labelAngle = startAngle + sweepAngle / 2.0f + 90.0f; if (labelAngle > 360.0f) { labelAngle = labelAngle - 360.0f; } - - int x = (int)(xStart + sin(labelAngle/180.0 * pi_) * _options.radius); - int y = (int)(yStart - cos(labelAngle/180.0 * pi_) * _options.radius); - + + int x = (int)(xStart + sin(labelAngle / 180.0 * pi_) * _options.radius); + int y = (int)(yStart - cos(labelAngle / 180.0 * pi_) * _options.radius); + if (labelAngle >= 0.0 && labelAngle <= 180.0) { - x += rect->Width()/2; + x += rect->Width() / 2; } else { - x -= rect->Width()/2; + x -= rect->Width() / 2; } - if (labelAngle >= 90.0 && labelAngle <= 270.0 ) + if (labelAngle >= 90.0 && labelAngle <= 270.0) { - y += rect->Height()/2; + y += rect->Height() / 2; } else { - y -= rect->Height()/2; + y -= rect->Height() / 2; } - + startAngle += sweepAngle; - - rect->MoveToX(x - rect->Width()/2); - rect->MoveToY(y - rect->Height()/2); - + + rect->MoveToX(x - rect->Width() / 2); + rect->MoveToY(y - rect->Height() / 2); + if (collisionList.HaveCollision(*rect)) { continue; @@ -957,8 +956,8 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide if (_options.valuesFrameVisible) { CBrush* oldBrush = dc->SelectObject(&brushFrame); - - CRect r(rect->left -3, rect->top, rect->right +2, rect->bottom); + + CRect r(rect->left - 3, rect->top, rect->right + 2, rect->bottom); dc->Rectangle(r); dc->SelectObject(oldBrush); } @@ -972,25 +971,25 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide // ------------------------------------------------------------- // Bar charts drawing // ------------------------------------------------------------- - else if(_options.chartType == chtBarChart) + else if (_options.chartType == chtBarChart) { Gdiplus::PointF points[5]; - + std::vector values; - + for (int j = 1; j <= numBars; j++) { values.push_back(j); } - + double minValue = 1; double maxValue = numBars; - + int barHeight = _options.barHeight; // > 30 ? 30 : _options.barHeight; - double maxHeight = (double)barHeight; + double maxHeight = (double)barHeight; int xStart = (int)x; - int yStart = (int)y + (_options.use3Dmode?(int)(_options.thickness * _options.tilt/90.0 + 2):0); + int yStart = (int)y + (_options.use3Dmode ? (int)(_options.thickness * _options.tilt / 90.0 + 2) : 0); double angle = 45.0; @@ -1010,35 +1009,35 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide fld->Release(); fld = NULL; } - + // initializing brushes Gdiplus::Color clr(alpha | BGR_TO_RGB(color)); Gdiplus::Color clrDimmed = Utility::ChangeBrightness(color, -100, alpha); Gdiplus::SolidBrush brush(clr); Gdiplus::SolidBrush brushDimmed(clrDimmed); - - int height = int((double)barHeight/maxValue * values[j]); + + int height = int((double)barHeight / maxValue * values[j]); int offsetY = barHeight - height + yStart; - - if ( height != 0 ) + + if (height != 0) { g.FillRectangle(&brushBackground, xStart, offsetY, _options.barWidth, height); g.FillRectangle(&brush, xStart, offsetY, _options.barWidth, height); - + g.DrawRectangle(&penBackground, xStart, offsetY, _options.barWidth, height); g.DrawRectangle(&pen, xStart, offsetY, _options.barWidth, height); - + // 3D mode - if ( _options.use3Dmode ) + if (_options.use3Dmode) { points[0].X = (Gdiplus::REAL)xStart; - points[1].X = (Gdiplus::REAL)(xStart + sin(angle/180*pi_) * _options.thickness); + points[1].X = (Gdiplus::REAL)(xStart + sin(angle / 180 * pi_) * _options.thickness); points[2].X = (Gdiplus::REAL)points[1].X + _options.barWidth; points[3].X = (Gdiplus::REAL)xStart + _options.barWidth; points[4].X = (Gdiplus::REAL)xStart; points[0].Y = (Gdiplus::REAL)offsetY; - points[1].Y = (Gdiplus::REAL)(offsetY - cos(angle/180*pi_) * _options.thickness); + points[1].Y = (Gdiplus::REAL)(offsetY - cos(angle / 180 * pi_) * _options.thickness); points[2].Y = (Gdiplus::REAL)points[1].Y; points[3].Y = (Gdiplus::REAL)offsetY; points[4].Y = (Gdiplus::REAL)offsetY; @@ -1049,13 +1048,13 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide g.FillPolygon(&brushDimmed, points, 5); points[0].X = (Gdiplus::REAL)xStart + _options.barWidth; - points[1].X = (Gdiplus::REAL)(points[0].X + sin(angle/180*pi_) * _options.thickness); + points[1].X = (Gdiplus::REAL)(points[0].X + sin(angle / 180 * pi_) * _options.thickness); points[2].X = (Gdiplus::REAL)points[1].X; points[3].X = (Gdiplus::REAL)points[0].X; points[4].X = (Gdiplus::REAL)points[0].X; points[0].Y = (Gdiplus::REAL)offsetY; - points[1].Y = (Gdiplus::REAL)(points[0].Y - cos(angle/180*pi_) * _options.thickness); + points[1].Y = (Gdiplus::REAL)(points[0].Y - cos(angle / 180 * pi_) * _options.thickness); points[2].Y = (Gdiplus::REAL)points[1].Y + height; points[3].Y = (Gdiplus::REAL)points[0].Y + height; points[4].Y = (Gdiplus::REAL)points[0].Y; @@ -1068,25 +1067,25 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide } xStart += _options.barWidth; } - + // drawing the labels std::vector labels; if (_options.valuesVisible && !hideLabels) { - int xAdd = (int)(sin(45.0/180*pi_) * _options.thickness); - + int xAdd = (int)(sin(45.0 / 180 * pi_) * _options.thickness); + xStart = int(x); //- numBars * _options.barWidth/2.0); yStart = int(y + maxHeight); int x, y; - + // calculating position of drawing for (int j = 0; j < numBars; j++) { - int height = int((double)barHeight/maxValue * values[j]); - if ( height != 0 ) + int height = int((double)barHeight / maxValue * values[j]); + if (height != 0) { CString s = Utility::FormatNumber(values[j], sFormat); - + CRect* rect = new CRect(); dc->DrawText(s, rect, DT_CALCRECT); @@ -1094,17 +1093,17 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide { rect->MoveToY(yStart - rect->Height() - height - 3); - if (j == 0 ) + if (j == 0) { - rect->MoveToX(xStart + _options.barWidth/2 - rect->Width()); + rect->MoveToX(xStart + _options.barWidth / 2 - rect->Width()); } else if (j == numBars - 1) { - rect->MoveToX(xStart + _options.barWidth/2); + rect->MoveToX(xStart + _options.barWidth / 2); } else { - rect->MoveToX(xStart + _options.barWidth/2 - rect->Width()/2); + rect->MoveToX(xStart + _options.barWidth / 2 - rect->Width() / 2); } } else @@ -1115,22 +1114,22 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide rect->bottom = 0; rect->left = 0; rect->right = ht; - rect->top = - wd; - - x = xStart + _options.barWidth/2 - rect->Width()/2 + xAdd/2; + rect->top = -wd; + + x = xStart + _options.barWidth / 2 - rect->Width() / 2 + xAdd / 2; y = yStart - rect->Height() - height - 6; - + rect->MoveToXY(x, y); } - + // we shall store the label, to keep the collision list clean ValueRectangle value; value.string = s; - + // drawing frame if (!vertical) { - CRect r(rect->left-2, rect->top, rect->right + 2, rect->bottom); + CRect r(rect->left - 2, rect->top, rect->right + 2, rect->bottom); value.rect = r; } else @@ -1139,7 +1138,7 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide value.rect = r; } labels.push_back(value); - + } xStart += _options.barWidth; } // numBars @@ -1159,7 +1158,7 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide if (!vertical) { - dc->DrawText(labels[j].string, rect, DT_CENTER|DT_VCENTER); + dc->DrawText(labels[j].string, rect, DT_CENTER | DT_VCENTER); } else { @@ -1168,7 +1167,7 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide } } // valuesVisible } - + if (_options.valuesVisible) { dc->SelectObject(oldFont); @@ -1184,17 +1183,17 @@ VARIANT_BOOL CCharts::DrawChartCore(CDC* dc, float x, float y, VARIANT_BOOL hide STDMETHODIMP CCharts::get_IconWidth(long *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - if (_options.chartType == chtBarChart) - { - int barCount = _bars.size() == 0?1:_bars.size(); - *retVal = _options.barWidth * barCount + 2; - if (_options.use3Dmode) - *retVal += int(sqrt(2.0f)/2.0 * _options.thickness); // 45 degrees - } - else - { - *retVal = _options.radius * 2 + 2; - } + if (_options.chartType == chtBarChart) + { + int barCount = _bars.size() == 0 ? 1 : _bars.size(); + *retVal = _options.barWidth * barCount + 2; + if (_options.use3Dmode) + *retVal += int(sqrt(2.0f) / 2.0 * _options.thickness); // 45 degrees + } + else + { + *retVal = _options.radius * 2 + 2; + } return S_OK; } @@ -1205,39 +1204,39 @@ STDMETHODIMP CCharts::get_IconHeight(long *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) if (_options.chartType == chtBarChart) - { - *retVal = _options.barHeight + 2; - if (_options.use3Dmode) - *retVal += (int)(sqrt(2.0f)/2.0 * _options.thickness); - } - else - { - if (_options.use3Dmode) - *retVal = (long)(_options.radius * (1.0 -_options.tilt/90.0) * 2.0 + _options.thickness * _options.tilt/90.0 + 2); + { + *retVal = _options.barHeight + 2; + if (_options.use3Dmode) + *retVal += (int)(sqrt(2.0f) / 2.0 * _options.thickness); + } else - *retVal = (long)(_options.radius * 2.0 + 2); - } + { + if (_options.use3Dmode) + *retVal = (long)(_options.radius * (1.0 - _options.tilt / 90.0) * 2.0 + _options.thickness * _options.tilt / 90.0 + 2); + else + *retVal = (long)(_options.radius * 2.0 + 2); + } return S_OK; } // ***************************************************************** // FontName() // ***************************************************************** -STDMETHODIMP CCharts::get_ValuesFontName(BSTR* retval) +STDMETHODIMP CCharts::get_ValuesFontName(BSTR* retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; - *retval = OLE2BSTR(_options.valuesFontName); + USES_CONVERSION; + *retval = OLE2BSTR(_options.valuesFontName); return S_OK; -}; -STDMETHODIMP CCharts::put_ValuesFontName(BSTR newVal) +}; +STDMETHODIMP CCharts::put_ValuesFontName(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; + USES_CONVERSION; ::SysFreeString(_options.valuesFontName); _options.valuesFontName = OLE2BSTR(newVal); return S_OK; -}; +}; // ***************************************************************** // Select() @@ -1248,19 +1247,19 @@ STDMETHODIMP CCharts::Select(IExtents* BoundingBox, long Tolerance, SelectMode S *retval = VARIANT_FALSE; if (!BoundingBox) return S_OK; - if (!_chartsExist || !_shapefile) + if (!_chartsExist) { return S_OK; } double xMin, yMin, zMin, xMax, yMax, zMax; BoundingBox->GetBounds(&xMin, &yMin, &zMin, &xMax, &yMax, &zMax); - CRect box(int(xMin - Tolerance/2), int(yMin - Tolerance/2), int(xMax + Tolerance/2), int(yMax + Tolerance/2)); - + CRect box(int(xMin - Tolerance / 2), int(yMin - Tolerance / 2), int(xMax + Tolerance / 2), int(yMax + Tolerance / 2)); + vector results; - + IUtils* utils = NULL; - CoCreateInstance(CLSID_Utils,NULL,CLSCTX_INPROC_SERVER,IID_IUtils,(void**)&utils); + CoCreateInstance(CLSID_Utils, NULL, CLSCTX_INPROC_SERVER, IID_IUtils, (void**)&utils); long numShapes; _shapefile->get_NumShapes(&numShapes); @@ -1282,7 +1281,7 @@ STDMETHODIMP CCharts::Select(IExtents* BoundingBox, long Tolerance, SelectMode S results.push_back(i); } } - + } utils->Release(); @@ -1299,7 +1298,7 @@ STDMETHODIMP CCharts::Select(IExtents* BoundingBox, long Tolerance, SelectMode S STDMETHODIMP CCharts::Serialize(BSTR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CPLXMLNode* psTree = SerializeCore("ChartsClass"); + CPLXMLNode* psTree = SerializeCore("ChartsClass"); Utility::SerializeAndDestroyXmlTree(psTree, retVal); return S_OK; } @@ -1310,8 +1309,8 @@ STDMETHODIMP CCharts::Serialize(BSTR* retVal) CPLXMLNode* CCharts::SerializeCore(CString ElementName) { USES_CONVERSION; - - CPLXMLNode* psTree = CPLCreateXMLNode( NULL, CXT_Element, "ChartsClass"); + + CPLXMLNode* psTree = CPLCreateXMLNode(NULL, CXT_Element, "ChartsClass"); CString str; // fields @@ -1323,18 +1322,18 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) for (unsigned int i = 0; i < _bars.size(); i++) { CPLXMLNode* psNode = CPLCreateXMLNode(psFields, CXT_Element, "ChartFieldClass"); - + // name CComBSTR name; _bars[i]->get_Name(&name); str = OLE2CA(name); Utility::CPLCreateXMLAttributeAndValue(psNode, "Name", str); - + // color OLE_COLOR color; _bars[i]->get_Color(&color); Utility::CPLCreateXMLAttributeAndValue(psNode, "Color", CPLString().Printf("%d", color)); - + // index long index; _bars[i]->get_Index(&index); @@ -1345,10 +1344,10 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) // serializing data if (_chartsExist) - { + { if (_savingMode == modeStandard) { - CPLXMLNode* nodeCharts = this->SerializeChartData("Charts" ); + CPLXMLNode* nodeCharts = this->SerializeChartData("Charts"); if (nodeCharts) { CPLAddXMLChild(psTree, nodeCharts); @@ -1367,10 +1366,10 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) _shapefile->get_Filename(&name); CString path = Utility::GetPathWOExtension(OLE2CA(name)); path += ".chart"; - + if (Utility::FileExists(path) && _savingMode == modeXMLOverwrite) { - if( remove( path ) != 0 ) + if (remove(path) != 0) { ErrorMessage(tkCANT_DELETE_FILE); } @@ -1399,13 +1398,13 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) } ChartOptions opt; // to compare with default settings - + if (_options.avoidCollisions != opt.avoidCollisions) Utility::CPLCreateXMLAttributeAndValue(psTree, "AvoidCollisions", CPLString().Printf("%d", (int)_options.avoidCollisions)); if (_options.barHeight != opt.barHeight) Utility::CPLCreateXMLAttributeAndValue(psTree, "BarHeight", CPLString().Printf("%d", _options.barHeight)); - + if (_options.barWidth != opt.barWidth) Utility::CPLCreateXMLAttributeAndValue(psTree, "BarWidth", CPLString().Printf("%d", _options.barWidth)); @@ -1435,25 +1434,25 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) if (_options.tilt != opt.tilt) Utility::CPLCreateXMLAttributeAndValue(psTree, "Tilt", CPLString().Printf("%f", _options.tilt)); - + if (_options.transparency != opt.transparency) Utility::CPLCreateXMLAttributeAndValue(psTree, "Transparency", CPLString().Printf("%d", _options.transparency)); - + if (_options.use3Dmode != opt.use3Dmode) Utility::CPLCreateXMLAttributeAndValue(psTree, "Use3Dmode", CPLString().Printf("%d", (int)_options.use3Dmode)); - + if (_options.useVariableRadius != opt.useVariableRadius) Utility::CPLCreateXMLAttributeAndValue(psTree, "UseVariableRadius", CPLString().Printf("%d", (int)_options.useVariableRadius)); - + if (_options.valuesFontBold != opt.valuesFontBold) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesFontBold", CPLString().Printf("%d", (int)_options.valuesFontBold)); - + if (_options.valuesFontColor != opt.valuesFontColor) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesFontColor", CPLString().Printf("%d", _options.valuesFontColor)); - + if (_options.valuesFontItalic != opt.valuesFontItalic) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesFontItalic", CPLString().Printf("%d", (int)_options.valuesFontItalic)); - + str = OLE2A(_options.valuesFontName); if (str != OLE2A(opt.valuesFontName)) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesFontName", str); @@ -1466,20 +1465,20 @@ CPLXMLNode* CCharts::SerializeCore(CString ElementName) if (_options.valuesFrameVisible != opt.valuesFrameVisible) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesFrameVisible", CPLString().Printf("%d", (int)_options.valuesFrameVisible)); - + if (_options.valuesStyle != opt.valuesStyle) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesStyle", CPLString().Printf("%d", (int)_options.valuesStyle)); - + if (_options.valuesVisible != opt.valuesVisible) Utility::CPLCreateXMLAttributeAndValue(psTree, "ValuesVisible", CPLString().Printf("%d", (int)_options.valuesVisible)); - + if (_options.verticalPosition != opt.verticalPosition) Utility::CPLCreateXMLAttributeAndValue(psTree, "VerticalPosition", CPLString().Printf("%d", (int)_options.verticalPosition)); - + if (_options.visible != opt.visible) Utility::CPLCreateXMLAttributeAndValue(psTree, "Visible", CPLString().Printf("%d", (int)_options.visible)); - if (_savingMode != modeXML) + if (_savingMode != modeXML) Utility::CPLCreateXMLAttributeAndValue(psTree, "SavingMode", CPLString().Printf("%d", (int)_savingMode)); return psTree; @@ -1492,16 +1491,16 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) { if (!node) return false; - + // restoring fields this->ClearFields(); - + // we don't touch charts in this mode if (_savingMode != modeNone) { this->Clear(); } - + CString s; CPLXMLNode* nodeFields = CPLGetXMLNode(node, "ChartFields"); @@ -1513,20 +1512,20 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) if (strcmp(node->pszValue, "ChartFieldClass") == 0) { IChartField* field = NULL; - CoCreateInstance(CLSID_ChartField,NULL,CLSCTX_INPROC_SERVER,IID_IChartField,(void**)&field); - + CoCreateInstance(CLSID_ChartField, NULL, CLSCTX_INPROC_SERVER, IID_IChartField, (void**)&field); + // name - s = CPLGetXMLValue( node, "Name", NULL ); - CComBSTR vbstr( s ); + s = CPLGetXMLValue(node, "Name", NULL); + CComBSTR vbstr(s); field->put_Name(vbstr); - s = CPLGetXMLValue( node, "Color", NULL ); - OLE_COLOR color = atoi( s ); - field->put_Color( color ); + s = CPLGetXMLValue(node, "Color", NULL); + OLE_COLOR color = atoi(s); + field->put_Color(color); - s = CPLGetXMLValue( node, "Index", NULL ); - long index = atoi( s ); - field->put_Index( index ); + s = CPLGetXMLValue(node, "Index", NULL); + long index = atoi(s); + field->put_Index(index); VARIANT_BOOL vbretval; this->AddField(field, &vbretval); @@ -1534,13 +1533,13 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) field->Release(); } node = node->psNext; - } + } } - + // restoring labels if (_savingMode == modeStandard) { - node = CPLGetXMLNode( node, "Charts" ); + node = CPLGetXMLNode(node, "Charts"); if (node) { this->DeserializeChartData(node); @@ -1552,7 +1551,7 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) { tkShapefileSourceType sourceType; _shapefile->get_SourceType(&sourceType); - + if (sourceType == sstDiskBased) { // constructing the name of .lbl file @@ -1561,7 +1560,7 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) USES_CONVERSION; CString path = Utility::GetPathWOExtension(OLE2CA(name)); path += ".chart"; - + // restoring labels if (Utility::FileExists(path)) { @@ -1576,90 +1575,90 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) ChartOptions opt; // for default set of options // start labels specific options - s = CPLGetXMLValue( node, "AvoidCollisions", NULL ); + s = CPLGetXMLValue(node, "AvoidCollisions", NULL); _options.avoidCollisions = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.avoidCollisions; - s = CPLGetXMLValue( node, "BarHeight", NULL ); + s = CPLGetXMLValue(node, "BarHeight", NULL); _options.barHeight = (s != "") ? atoi(s.GetString()) : opt.barHeight; - s = CPLGetXMLValue( node, "BarWidth", NULL ); + s = CPLGetXMLValue(node, "BarWidth", NULL); _options.barWidth = (s != "") ? atoi(s.GetString()) : opt.barWidth; - - s = CPLGetXMLValue( node, "ChartType", NULL ); + + s = CPLGetXMLValue(node, "ChartType", NULL); _options.chartType = (s != "") ? (tkChartType)atoi(s.GetString()) : opt.chartType; - - s = CPLGetXMLValue( node, "LineColor", NULL ); + + s = CPLGetXMLValue(node, "LineColor", NULL); _options.lineColor = (s != "") ? (OLE_COLOR)atoi(s.GetString()) : opt.lineColor; - s = CPLGetXMLValue( node, "NormalizationField", NULL ); + s = CPLGetXMLValue(node, "NormalizationField", NULL); _options.normalizationField = (s != "") ? atoi(s.GetString()) : opt.normalizationField; - - s = CPLGetXMLValue( node, "Radius", NULL ); + + s = CPLGetXMLValue(node, "Radius", NULL); _options.radius = (s != "") ? atoi(s.GetString()) : opt.radius; - - s = CPLGetXMLValue( node, "Radius2", NULL ); + + s = CPLGetXMLValue(node, "Radius2", NULL); _options.radius2 = (s != "") ? atoi(s.GetString()) : opt.radius2; - - s = CPLGetXMLValue( node, "Rotation", NULL ); + + s = CPLGetXMLValue(node, "Rotation", NULL); _options.rotation = (s != "") ? atoi(s.GetString()) : opt.rotation; - s = CPLGetXMLValue( node, "SizeField", NULL ); + s = CPLGetXMLValue(node, "SizeField", NULL); _options.sizeField = (s != "") ? atoi(s.GetString()) : opt.sizeField; - s = CPLGetXMLValue( node, "Thickness", NULL ); + s = CPLGetXMLValue(node, "Thickness", NULL); _options.thickness = (s != "") ? Utility::atof_custom(s) : opt.thickness; - s = CPLGetXMLValue( node, "Tilt", NULL ); + s = CPLGetXMLValue(node, "Tilt", NULL); _options.tilt = (s != "") ? Utility::atof_custom(s) : opt.tilt; - s = CPLGetXMLValue( node, "Transparency", NULL ); + s = CPLGetXMLValue(node, "Transparency", NULL); _options.transparency = (s != "") ? atoi(s) : opt.transparency; - s = CPLGetXMLValue( node, "Use3Dmode", NULL ); + s = CPLGetXMLValue(node, "Use3Dmode", NULL); _options.use3Dmode = (s != "") ? (atoi(s) == 0 ? false : true) : opt.use3Dmode; - s = CPLGetXMLValue( node, "UseVariableRadius", NULL ); + s = CPLGetXMLValue(node, "UseVariableRadius", NULL); _options.useVariableRadius = (s != "") ? (atoi(s.GetString()) == 0 ? false : true) : opt.useVariableRadius; - s = CPLGetXMLValue( node, "ValuesFontBold", NULL ); + s = CPLGetXMLValue(node, "ValuesFontBold", NULL); _options.valuesFontBold = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesFontBold; - s = CPLGetXMLValue( node, "ValuesFontColor", NULL ); + s = CPLGetXMLValue(node, "ValuesFontColor", NULL); _options.valuesFontColor = (s != "") ? (OLE_COLOR)atoi(s.GetString()) : opt.valuesFontColor; - s = CPLGetXMLValue( node, "ValuesFontItalic", NULL ); + s = CPLGetXMLValue(node, "ValuesFontItalic", NULL); _options.valuesFontItalic = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesFontItalic; - s = CPLGetXMLValue( node, "ValuesFontName", NULL ); + s = CPLGetXMLValue(node, "ValuesFontName", NULL); if (s != "") { SysFreeString(_options.valuesFontName); _options.valuesFontName = A2BSTR(s); } - - s = CPLGetXMLValue( node, "ValuesFontSize", NULL ); - _options.valuesFontSize = (s != "") ? atoi(s.GetString()) : opt.valuesFontSize; - - s = CPLGetXMLValue( node, "ValuesFrameColor", NULL ); - _options.valuesFrameColor = (s != "") ? (OLE_COLOR)atoi(s.GetString()) : opt.valuesFrameColor; - - s = CPLGetXMLValue( node, "ValuesFrameVisible", NULL ); - _options.valuesFrameVisible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesFrameVisible; - s = CPLGetXMLValue( node, "ValuesStyle", NULL ); - _options.valuesStyle = (s != "") ? (tkChartValuesStyle)atoi(s.GetString()) : opt.valuesStyle; + s = CPLGetXMLValue(node, "ValuesFontSize", NULL); + _options.valuesFontSize = (s != "") ? atoi(s.GetString()) : opt.valuesFontSize; - s = CPLGetXMLValue( node, "ValuesVisible", NULL ); - _options.valuesVisible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesVisible; + s = CPLGetXMLValue(node, "ValuesFrameColor", NULL); + _options.valuesFrameColor = (s != "") ? (OLE_COLOR)atoi(s.GetString()) : opt.valuesFrameColor; - s = CPLGetXMLValue( node, "VerticalPosition", NULL ); - _options.verticalPosition = (s != "") ? (tkVerticalPosition)atoi(s.GetString()) : opt.verticalPosition; + s = CPLGetXMLValue(node, "ValuesFrameVisible", NULL); + _options.valuesFrameVisible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesFrameVisible; - s = CPLGetXMLValue( node, "Visible", NULL ); - _options.visible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.visible; + s = CPLGetXMLValue(node, "ValuesStyle", NULL); + _options.valuesStyle = (s != "") ? (tkChartValuesStyle)atoi(s.GetString()) : opt.valuesStyle; - s = CPLGetXMLValue( node, "SavingMode", NULL ); - _savingMode = (s != "") ? (tkSavingMode)atoi(s.GetString()) : modeXML; + s = CPLGetXMLValue(node, "ValuesVisible", NULL); + _options.valuesVisible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.valuesVisible; + + s = CPLGetXMLValue(node, "VerticalPosition", NULL); + _options.verticalPosition = (s != "") ? (tkVerticalPosition)atoi(s.GetString()) : opt.verticalPosition; + + s = CPLGetXMLValue(node, "Visible", NULL); + _options.visible = (s != "") ? (VARIANT_BOOL)atoi(s.GetString()) : opt.visible; + + s = CPLGetXMLValue(node, "SavingMode", NULL); + _savingMode = (s != "") ? (tkSavingMode)atoi(s.GetString()) : modeXML; return true; } @@ -1670,7 +1669,7 @@ bool CCharts::DeserializeCore(CPLXMLNode* node) STDMETHODIMP CCharts::Deserialize(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; + USES_CONVERSION; CString s = OLE2CA(newVal); CPLXMLNode* node = CPLParseXMLString(s.GetString()); @@ -1692,7 +1691,7 @@ STDMETHODIMP CCharts::Deserialize(BSTR newVal) STDMETHODIMP CCharts::SaveToXML(BSTR Filename, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = VARIANT_FALSE; + *retVal = VARIANT_FALSE; USES_CONVERSION; CStringW s = OLE2W(Filename); @@ -1707,8 +1706,8 @@ STDMETHODIMP CCharts::SaveToXML(BSTR Filename, VARIANT_BOOL* retVal) ErrorMessage(tkINVALID_FILENAME); return S_OK; } - - CPLXMLNode *psTree = CPLCreateXMLNode( NULL, CXT_Element, "MapWindow" ); + + CPLXMLNode *psTree = CPLCreateXMLNode(NULL, CXT_Element, "MapWindow"); if (psTree) { Utility::WriteXmlHeaderAttributes(psTree, "Charts"); @@ -1732,12 +1731,12 @@ STDMETHODIMP CCharts::SaveToXML(BSTR Filename, VARIANT_BOOL* retVal) // ******************************************************** CPLXMLNode* CCharts::SerializeChartData(CString ElementName) { - CPLXMLNode* psCharts = CPLCreateXMLNode( NULL, CXT_Element, ElementName ); + CPLXMLNode* psCharts = CPLCreateXMLNode(NULL, CXT_Element, ElementName); if (psCharts) { if (!_shapefile) return NULL; - + std::vector* data = ((CShapefile*)_shapefile)->get_ShapeVector(); if (data) { @@ -1756,7 +1755,7 @@ CPLXMLNode* CCharts::SerializeChartData(CString ElementName) CPLAddXMLSibling(nodeOld, nodeNew); nodeOld = nodeNew; } - + CChartInfo* info = (*data)[i]->chart; Utility::CPLCreateXMLAttributeAndValue(nodeOld, "X", CPLString().Printf("%f", info->x)); Utility::CPLCreateXMLAttributeAndValue(nodeOld, "Y", CPLString().Printf("%f", info->y)); @@ -1772,7 +1771,7 @@ CPLXMLNode* CCharts::SerializeChartData(CString ElementName) STDMETHODIMP CCharts::get_SavingMode(tkSavingMode* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = _savingMode; + *retVal = _savingMode; return S_OK; } @@ -1782,7 +1781,7 @@ STDMETHODIMP CCharts::get_SavingMode(tkSavingMode* retVal) STDMETHODIMP CCharts::put_SavingMode(tkSavingMode newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - _savingMode = newVal; + _savingMode = newVal; return S_OK; } @@ -1792,8 +1791,8 @@ STDMETHODIMP CCharts::put_SavingMode(tkSavingMode newVal) STDMETHODIMP CCharts::LoadFromXML(BSTR Filename, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - *retVal = VARIANT_FALSE; - + *retVal = VARIANT_FALSE; + USES_CONVERSION; CStringW name = OLE2W(Filename); if (!Utility::FileExistsW(name)) @@ -1802,13 +1801,13 @@ STDMETHODIMP CCharts::LoadFromXML(BSTR Filename, VARIANT_BOOL* retVal) return S_OK; } - CPLXMLNode* node = GdalHelper::ParseXMLFile(name); + CPLXMLNode* node = GdalHelper::ParseXMLFile(name); if (node) { node = CPLGetXMLNode(node, "=MapWindow"); if (node) { - CString s = CPLGetXMLValue( node, "FileVersion", "0" ); + CString s = CPLGetXMLValue(node, "FileVersion", "0"); int version = atoi(s); node = CPLGetXMLNode(node, "Charts"); @@ -1826,42 +1825,42 @@ STDMETHODIMP CCharts::LoadFromXML(BSTR Filename, VARIANT_BOOL* retVal) // ******************************************************** bool CCharts::DeserializeChartData(CPLXMLNode* node) { - if (!node || !_shapefile) - return false; - - CSingleLock sfLock(&((CShapefile*)_shapefile)->ShapefileLock, TRUE); - - std::vector* data = ((CShapefile*)_shapefile)->get_ShapeVector(); - if (!data) - return false; + if (node) + { + std::vector* data = ((CShapefile*)_shapefile)->get_ShapeVector(); + if (data) + { - this->Clear(); - ((CShapefile*)_shapefile)->SetChartsPositions(lpNone); + this->Clear(); + ((CShapefile*)_shapefile)->SetChartsPositions(lpNone); - CString s; - double x, y; - int i = 0; + CString s; + double x, y; + int i = 0; - node = CPLGetXMLNode(node, "Chart"); + node = CPLGetXMLNode(node, "Chart"); - int count = data->size(); - while (node && i < count) - { - s = CPLGetXMLValue(node, "X", "0.0"); - x = Utility::atof_custom(s); + int count = data->size(); + while (node && i < count) + { + s = CPLGetXMLValue(node, "X", "0.0"); + x = Utility::atof_custom(s); - s = CPLGetXMLValue(node, "Y", "0.0"); - y = Utility::atof_custom(s); + s = CPLGetXMLValue(node, "Y", "0.0"); + y = Utility::atof_custom(s); - CChartInfo* info = (*data)[i]->chart; - info->x = x; - info->y = y; - i++; + CChartInfo* info = (*data)[i]->chart; + info->x = x; + info->y = y; + i++; - node = node->psNext; - } - _chartsExist = true; - return true; + node = node->psNext; + } + _chartsExist = true; + return true; + } + } + return false; } #pragma endregion \ No newline at end of file diff --git a/src/COM classes/FieldStatOperations.cpp b/src/COM classes/FieldStatOperations.cpp index 67033153..e66f8cdb 100644 --- a/src/COM classes/FieldStatOperations.cpp +++ b/src/COM classes/FieldStatOperations.cpp @@ -1,7 +1,6 @@ // FieldStatOperations.cpp : Implementation of CFieldStatOperations #include "stdafx.h" -#include "Shapefile.h" #include "FieldStatOperations.h" //*********************************************************************** @@ -191,7 +190,6 @@ STDMETHODIMP CFieldStatOperations::Validate(IShapefile* sf, VARIANT_BOOL* retVal } else { - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); long numFields; sf->get_NumFields(&numFields); diff --git a/src/COM classes/OgrDatasource.cpp b/src/COM classes/OgrDatasource.cpp index 6c0dbe3b..610f9aed 100644 --- a/src/COM classes/OgrDatasource.cpp +++ b/src/COM classes/OgrDatasource.cpp @@ -405,8 +405,6 @@ STDMETHODIMP COgrDatasource::ImportShapefile(IShapefile* shapefile, BSTR newLaye return S_OK; } - CSingleLock sfLock(&((CShapefile*) shapefile)->ShapefileLock, TRUE); - CStringA name = OgrHelper::Bstr2OgrString(newLayerName); if (name.GetLength() == 0) { diff --git a/src/COM classes/OgrLayer.cpp b/src/COM classes/OgrLayer.cpp index ad346dbd..f8bdd1e7 100644 --- a/src/COM classes/OgrLayer.cpp +++ b/src/COM classes/OgrLayer.cpp @@ -12,15 +12,13 @@ #include "ShapefileCategories.h" #include "Templates.h" #include "ShapefileHelper.h" -#include "TableClass.h" -#include "TableHelper.h" // ************************************************************* // InjectShapefile() // ************************************************************* void COgrLayer::InjectShapefile(IShapefile* sfNew) -{ - CSingleLock lock(&_loader.ProviderLock, TRUE); +{ // Lock shape file + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); CloseShapefile(); _shapefile = sfNew; } @@ -30,7 +28,6 @@ void COgrLayer::InjectShapefile(IShapefile* sfNew) // ************************************************************* void COgrLayer::InitOpenedLayer() { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (Utility::FileExistsW(_connectionString)) { _sourceType = ogrFile; } @@ -61,7 +58,6 @@ void COgrLayer::InitOpenedLayer() //*********************************************************************** void COgrLayer::ClearCachedValues() { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (_envelope) { delete _envelope; @@ -79,7 +75,7 @@ void COgrLayer::ClearCachedValues() void COgrLayer::StopBackgroundLoading() { _loader.CancelAllTasks(); // notify working thread that it's time is over - CSingleLock lock(&_loader.LoadingLock, TRUE); + CSingleLock lock(&_loader.LoadingLock, _dynamicLoading ? TRUE : FALSE); } //*********************************************************************** @@ -87,10 +83,6 @@ void COgrLayer::StopBackgroundLoading() //*********************************************************************** IShapefile* COgrLayer::LoadShapefile() { - // Lock it all down: - CSingleLock ldLock(&_loader.LoadingLock, TRUE); - CSingleLock prLock(&_loader.ProviderLock, TRUE); - bool isTrimmed = false; IShapefile* sf = Ogr2Shape::Layer2Shapefile(_layer, _activeShapeType, _loader.GetMaxCacheCount(), isTrimmed, &_loader, _globalCallback); if (isTrimmed) { @@ -99,80 +91,6 @@ IShapefile* COgrLayer::LoadShapefile() return sf; } -//*********************************************************************** -//* UpdateShapefileFromOGRLoader() -//*********************************************************************** -void COgrLayer::UpdateShapefileFromOGRLoader() -{ - CSingleLock lock(&_loader.ProviderLock, TRUE); - if (!_shapefile) return; - - // Wait for tasks to finish loading: - _loader.AwaitTasks(); - - // Lock it all down: - CSingleLock ldLock(&_loader.LoadingLock, TRUE); - CSingleLock prLock(&_loader.ProviderLock, TRUE); - CSingleLock sfLock(&((CShapefile*) _shapefile)->ShapefileLock, TRUE); - - // Grab the loaded data: - vector data = _loader.FetchData(); - if (data.size() == 0) return; - - VARIANT_BOOL vb; - _shapefile->EditClear(&vb); - - ShpfileType shpType; - _shapefile->get_ShapefileType(&shpType); - - Debug::WriteWithThreadId(Debug::Format("Update shapefile: %d\n", data.size()), DebugOgrLoading); - - CComPtr table = NULL; - _shapefile->get_Table(&table); - - CComPtr labels = NULL; - _shapefile->get_Labels(&labels); - labels->Clear(); - - if (table) - { - CTableClass* tbl = TableHelper::Cast(table); - _shapefile->StartEditingShapes(VARIANT_TRUE, NULL, &vb); - long count = 0; - for (size_t i = 0; i < data.size(); i++) - { - CComPtr shp = NULL; - ComHelper::CreateShape(&shp); - if (shp) - { - shp->Create(shpType, &vb); - shp->ImportFromBinary(data[i]->Shape, &vb); - _shapefile->EditInsertShape(shp, &count, &vb); - - tbl->UpdateTableRow(data[i]->Row, count); - data[i]->Row = NULL; // we no longer own it; it'll be cleared by Shapefile.EditClear - - count++; - } - } - // inserted shapes were marked as modified, correct this - ShapefileHelper::ClearShapefileModifiedFlag(_shapefile); - - // Stop 'fake' editing session - _shapefile->StopEditingShapes(VARIANT_TRUE, VARIANT_TRUE, NULL, &vb); - - // Without this, categories are not correctly applied in the drawing function: - IShapefileCategories* cat; - _shapefile->get_Categories(&cat); - cat->ApplyExpressions(); - } - - // clean the data - for (size_t i = 0; i < data.size(); i++) { - delete data[i]; - } -} - //*********************************************************************** //* get/put_Key() //*********************************************************************** @@ -180,16 +98,14 @@ STDMETHODIMP COgrLayer::get_Key(BSTR *pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = OLE2BSTR(_key); return S_OK; } STDMETHODIMP COgrLayer::put_Key(BSTR newVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + ::SysFreeString(_key); USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); - ::SysFreeString(_key); _key = OLE2BSTR(newVal); return S_OK; } @@ -199,15 +115,13 @@ STDMETHODIMP COgrLayer::put_Key(BSTR newVal) //***********************************************************************/ void COgrLayer::ErrorMessage(long ErrorCode) { - CSingleLock lock(&_loader.ProviderLock, TRUE); _lastErrorCode = ErrorCode; CallbackHelper::ErrorMsg("OgrLayer", _globalCallback, _key, ErrorMsg(_lastErrorCode)); } STDMETHODIMP COgrLayer::get_LastErrorCode(long *pVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *pVal = _lastErrorCode; _lastErrorCode = tkNO_ERROR; return S_OK; @@ -215,8 +129,7 @@ STDMETHODIMP COgrLayer::get_LastErrorCode(long *pVal) STDMETHODIMP COgrLayer::get_ErrorMsg(long ErrorCode, BSTR *pVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) USES_CONVERSION; *pVal = A2BSTR(ErrorMsg(ErrorCode)); return S_OK; @@ -227,8 +140,7 @@ STDMETHODIMP COgrLayer::get_ErrorMsg(long ErrorCode, BSTR *pVal) //***********************************************************************/ STDMETHODIMP COgrLayer::get_GlobalCallback(ICallback **pVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *pVal = _globalCallback; if (_globalCallback != NULL) _globalCallback->AddRef(); return S_OK; @@ -236,8 +148,7 @@ STDMETHODIMP COgrLayer::get_GlobalCallback(ICallback **pVal) STDMETHODIMP COgrLayer::put_GlobalCallback(ICallback *newVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) ComHelper::SetRef(newVal, (IDispatch**)&_globalCallback); return S_OK; } @@ -247,7 +158,6 @@ STDMETHODIMP COgrLayer::put_GlobalCallback(ICallback *newVal) // ************************************************************* bool COgrLayer::CheckState() { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!_dataset) { ErrorMessage(tkOGR_LAYER_UNINITIALIZED); @@ -262,7 +172,6 @@ bool COgrLayer::CheckState() STDMETHODIMP COgrLayer::get_SourceType(tkOgrSourceType* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = _sourceType; return S_OK; } @@ -272,8 +181,7 @@ STDMETHODIMP COgrLayer::get_SourceType(tkOgrSourceType* retVal) // ************************************************************* STDMETHODIMP COgrLayer::Close() { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) StopBackgroundLoading(); @@ -315,8 +223,8 @@ STDMETHODIMP COgrLayer::Close() // CloseShapefile() // ************************************************************* void COgrLayer::CloseShapefile() -{ - CSingleLock lock(&_loader.ProviderLock, TRUE); +{ // Lock shape file + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); if (_shapefile) { VARIANT_BOOL vb; @@ -331,7 +239,6 @@ void COgrLayer::CloseShapefile() // ************************************************************* GDALDataset* COgrLayer::OpenDataset(BSTR connectionString, bool forUpdate) { - CSingleLock lock(&_loader.ProviderLock, TRUE); GDALDataset* ds = GdalHelper::OpenOgrDatasetW(OLE2W(connectionString), forUpdate, true); if (!ds) { @@ -347,7 +254,6 @@ GDALDataset* COgrLayer::OpenDataset(BSTR connectionString, bool forUpdate) STDMETHODIMP COgrLayer::OpenDatabaseLayer(BSTR connectionString, int layerIndex, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; GDALDataset* ds = OpenDataset(connectionString, forUpdate ? true : false); @@ -367,7 +273,6 @@ STDMETHODIMP COgrLayer::OpenDatabaseLayer(BSTR connectionString, int layerIndex, // ************************************************************* bool COgrLayer::OpenDatabaseLayerCore(GDALDataset* ds, CStringW connectionString, int layerIndex, VARIANT_BOOL forUpdate, VARIANT_BOOL externalDatasource) { - CSingleLock lock(&_loader.ProviderLock, TRUE); Close(); if (!ds) { @@ -406,49 +311,15 @@ bool COgrLayer::OpenDatabaseLayerCore(GDALDataset* ds, CStringW connectionString // ************************************************************* bool COgrLayer::InjectLayer(GDALDataset* ds, int layerIndex, CStringW connection, VARIANT_BOOL forUpdate) { - CSingleLock lock(&_loader.ProviderLock, TRUE); return OpenDatabaseLayerCore(ds, connection, layerIndex, forUpdate, VARIANT_TRUE); } -// ************************************************************* -// ExtendFromQuery() -// ************************************************************* -STDMETHODIMP COgrLayer::ExtendFromQuery(BSTR sql, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock ldLock(&_loader.LoadingLock, TRUE); - CSingleLock prLock(&_loader.ProviderLock, TRUE); - - *retVal = VARIANT_FALSE; - - GDALDataset* ds = OpenDataset(W2BSTR(_connectionString), false); - if (!ds) { - ErrorMessage(tkOGR_QUERY_FAILED); - return S_OK; - } - - OGRLayer* layer = ds->ExecuteSQL(OgrHelper::Bstr2OgrString(sql), NULL, NULL); - if (!layer) - { - ErrorMessage(tkOGR_QUERY_FAILED); - GdalHelper::CloseSharedOgrDataset(ds); - return S_OK; - } - - Ogr2Shape::ExtendShapefile(layer, _shapefile, true, _globalCallback); - GdalHelper::CloseSharedOgrDataset(ds); - *retVal = VARIANT_TRUE; - return S_OK; -} - // ************************************************************* // OpenFromQuery() // ************************************************************* STDMETHODIMP COgrLayer::OpenFromQuery(BSTR connectionString, BSTR sql, VARIANT_BOOL* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retVal = VARIANT_FALSE; Close(); @@ -482,9 +353,7 @@ STDMETHODIMP COgrLayer::OpenFromQuery(BSTR connectionString, BSTR sql, VARIANT_B // ************************************************************* STDMETHODIMP COgrLayer::OpenFromDatabase(BSTR connectionString, BSTR layerName, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retVal = VARIANT_FALSE; Close(); @@ -519,7 +388,6 @@ STDMETHODIMP COgrLayer::OpenFromDatabase(BSTR connectionString, BSTR layerName, STDMETHODIMP COgrLayer::OpenFromFile(BSTR Filename, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; Close(); @@ -554,8 +422,7 @@ STDMETHODIMP COgrLayer::OpenFromFile(BSTR Filename, VARIANT_BOOL forUpdate, VARI // ************************************************************* STDMETHODIMP COgrLayer::get_Name(BSTR* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) if (!CheckState()) { *retVal = A2BSTR(""); @@ -575,19 +442,23 @@ STDMETHODIMP COgrLayer::get_Name(BSTR* retVal) STDMETHODIMP COgrLayer::GetBuffer(IShapefile** retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = NULL; if (!CheckState()) return S_OK; // Lock shape file + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); if (!_shapefile) { if (_dynamicLoading) + { // Lock provider + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); _shapefile = Ogr2Shape::CreateShapefile(_layer, _activeShapeType); - else + } + else { _shapefile = LoadShapefile(); } + } if (_shapefile) { @@ -603,7 +474,6 @@ STDMETHODIMP COgrLayer::GetBuffer(IShapefile** retVal) STDMETHODIMP COgrLayer::ReloadFromSource(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -613,6 +483,8 @@ STDMETHODIMP COgrLayer::ReloadFromSource(VARIANT_BOOL* retVal) return S_OK; } + // Lock shape file + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); CloseShapefile(); _shapefile = LoadShapefile(); @@ -626,7 +498,6 @@ STDMETHODIMP COgrLayer::ReloadFromSource(VARIANT_BOOL* retVal) STDMETHODIMP COgrLayer::RedefineQuery(BSTR newSql, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -669,7 +540,6 @@ STDMETHODIMP COgrLayer::GetConnectionString(BSTR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = W2BSTR(_connectionString); return S_OK; } @@ -681,7 +551,6 @@ STDMETHODIMP COgrLayer::GetSourceQuery(BSTR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = W2BSTR(_sourceQuery); return S_OK; } @@ -692,14 +561,15 @@ STDMETHODIMP COgrLayer::GetSourceQuery(BSTR* retVal) STDMETHODIMP COgrLayer::get_GeoProjection(IGeoProjection** retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - IGeoProjection* gp = NULL; ComHelper::CreateInstance(idGeoProjection, (IDispatch**)&gp); *retVal = gp; if (!CheckState()) return S_OK; + // Locking provider here + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE: FALSE); + OGRSpatialReference* sr = _layer->GetSpatialRef(); // owned by OGRLayer if (sr) ((CGeoProjection*)gp)->InjectSpatialReference(sr); return S_OK; @@ -711,8 +581,6 @@ STDMETHODIMP COgrLayer::get_GeoProjection(IGeoProjection** retVal) STDMETHODIMP COgrLayer::get_ShapeType(ShpfileType* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - *retVal = SHP_NULLSHAPE; if (!CheckState()) return S_OK; *retVal = OgrConverter::GeometryType2ShapeType(_layer->GetGeomType()); @@ -725,8 +593,6 @@ STDMETHODIMP COgrLayer::get_ShapeType(ShpfileType* retVal) STDMETHODIMP COgrLayer::get_ShapeType2D(ShpfileType* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - get_ShapeType(pVal); *pVal = ShapeUtility::Convert2D(*pVal); return S_OK; @@ -738,8 +604,6 @@ STDMETHODIMP COgrLayer::get_ShapeType2D(ShpfileType* pVal) STDMETHODIMP COgrLayer::get_DataIsReprojected(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; if (!_shapefile) return S_OK; // data wasn't loaded yet @@ -767,8 +631,6 @@ STDMETHODIMP COgrLayer::get_DataIsReprojected(VARIANT_BOOL* retVal) STDMETHODIMP COgrLayer::get_FIDColumnName(BSTR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - if (CheckState()) { CStringW s = OgrHelper::OgrString2Unicode(_layer->GetFIDColumn()); @@ -785,8 +647,6 @@ STDMETHODIMP COgrLayer::get_FIDColumnName(BSTR* retVal) STDMETHODIMP COgrLayer::SaveChanges(int* savedCount, tkOgrSaveType saveType, VARIANT_BOOL validateShapes, tkOgrSaveResult* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); - *savedCount = 0; *retVal = osrNoChanges; _updateErrors.clear(); @@ -823,7 +683,8 @@ STDMETHODIMP COgrLayer::SaveChanges(int* savedCount, tkOgrSaveType saveType, VAR } { // Locking provider & shapefile here - CSingleLock lock(&_loader.ProviderLock, TRUE); + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); *savedCount = Shape2Ogr::SaveShapefileChanges(_layer, _shapefile, shapeCmnId, saveType, validateShapes ? true : false, _updateErrors); } @@ -844,15 +705,14 @@ STDMETHODIMP COgrLayer::SaveChanges(int* savedCount, tkOgrSaveType saveType, VAR STDMETHODIMP COgrLayer::HasLocalChanges(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState() || !_shapefile) return S_OK; { // Locking provider & shapefile here - CSingleLock lock(&_loader.ProviderLock, TRUE); - CSingleLock sfLock(&((CShapefile*)_shapefile)->ShapefileLock, TRUE); + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); long numShapes; _shapefile->get_NumShapes(&numShapes); @@ -918,7 +778,7 @@ long COgrLayer::GetFidForShapefile() { if (!_layer || !_shapefile) return -1; // Locking shapefile here - CSingleLock sfLock(&((CShapefile*)_shapefile)->ShapefileLock, TRUE); + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); CComBSTR bstr; get_FIDColumnName(&bstr); CComPtr table = NULL; @@ -934,8 +794,6 @@ long COgrLayer::GetFidForShapefile() STDMETHODIMP COgrLayer::TestCapability(tkOgrLayerCapability capability, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); - *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; int val = _layer->TestCapability(OgrHelper::GetLayerCapabilityString(capability)); @@ -949,8 +807,6 @@ STDMETHODIMP COgrLayer::TestCapability(tkOgrLayerCapability capability, VARIANT_ STDMETHODIMP COgrLayer::get_UpdateSourceErrorCount(int* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); - *retVal = _updateErrors.size(); return S_OK; } @@ -961,8 +817,6 @@ STDMETHODIMP COgrLayer::get_UpdateSourceErrorCount(int* retVal) STDMETHODIMP COgrLayer::get_UpdateSourceErrorMsg(int errorIndex, BSTR* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); - if (errorIndex < 0 || errorIndex >= (int)_updateErrors.size()) { *retVal = A2BSTR(""); @@ -979,8 +833,6 @@ STDMETHODIMP COgrLayer::get_UpdateSourceErrorMsg(int errorIndex, BSTR* retVal) STDMETHODIMP COgrLayer::get_UpdateSourceErrorShapeIndex(int errorIndex, int* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); - if (errorIndex < 0 || errorIndex >= (int)_updateErrors.size()) { *retVal = -1; @@ -997,11 +849,13 @@ STDMETHODIMP COgrLayer::get_UpdateSourceErrorShapeIndex(int errorIndex, int* ret STDMETHODIMP COgrLayer::get_FeatureCount(VARIANT_BOOL forceLoading, int* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = 0; if (!CheckState()) return S_OK; + { // Locking provider here + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); + if (_featureCount == -1 || forceLoading) { _featureCount = static_cast(_layer->GetFeatureCount(forceLoading == VARIANT_TRUE)); @@ -1009,6 +863,7 @@ STDMETHODIMP COgrLayer::get_FeatureCount(VARIANT_BOOL forceLoading, int* retVal) *retVal = _featureCount; return S_OK; } +} // ************************************************************* @@ -1016,13 +871,16 @@ STDMETHODIMP COgrLayer::get_FeatureCount(VARIANT_BOOL forceLoading, int* retVal) // ************************************************************* void COgrLayer::ForceCreateShapefile() { - CSingleLock lock(&_loader.ProviderLock, TRUE); tkOgrSourceType sourceType; get_SourceType(&sourceType); if (_dynamicLoading && !_shapefile && sourceType != ogrUninitialized) + { // Lock the provider & shapefile + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); _shapefile = Ogr2Shape::CreateShapefile(_layer, _activeShapeType); } +} // ************************************************************* // get_Extents() @@ -1030,7 +888,6 @@ void COgrLayer::ForceCreateShapefile() STDMETHODIMP COgrLayer::get_Extents(IExtents** extents, VARIANT_BOOL forceLoading, VARIANT_BOOL *retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock lock(&_loader.ProviderLock, TRUE); *extents = NULL; *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -1041,7 +898,8 @@ STDMETHODIMP COgrLayer::get_Extents(IExtents** extents, VARIANT_BOOL forceLoadin } if (!_envelope) - { + { // Locking provider here + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); _envelope = new OGREnvelope(); _layer->GetExtent(_envelope, forceLoading == VARIANT_TRUE); } @@ -1063,8 +921,7 @@ STDMETHODIMP COgrLayer::get_Extents(IExtents** extents, VARIANT_BOOL forceLoadin // ************************************************************* STDMETHODIMP COgrLayer::get_GeometryColumnName(BSTR* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) if (!CheckState()) return S_OK; CStringW name = OgrHelper::OgrString2Unicode(_layer->GetGeometryColumn()); USES_CONVERSION; @@ -1077,10 +934,9 @@ STDMETHODIMP COgrLayer::get_GeometryColumnName(BSTR* retVal) // ************************************************************* STDMETHODIMP COgrLayer::get_SupportsEditing(tkOgrSaveType editingType, VARIANT_BOOL* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retVal = VARIANT_FALSE; - if (!CheckState() || !_shapefile) return S_OK; + if (!CheckState()) return S_OK; // is it supported by driver? VARIANT_BOOL randomWrite; @@ -1093,7 +949,7 @@ STDMETHODIMP COgrLayer::get_SupportsEditing(tkOgrSaveType editingType, VARIANT_B // do we have FID column? { // Locking shapefile here - CSingleLock sfLock(&((CShapefile*)_shapefile)->ShapefileLock, TRUE); + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); if (_shapefile) { long fid = GetFidForShapefile(); @@ -1132,8 +988,7 @@ STDMETHODIMP COgrLayer::get_SupportsEditing(tkOgrSaveType editingType, VARIANT_B // ************************************************************* STDMETHODIMP COgrLayer::Serialize(BSTR* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) CPLXMLNode* psTree = this->SerializeCore("OgrLayerClass"); Utility::SerializeAndDestroyXmlTree(psTree, retVal); return S_OK; @@ -1144,7 +999,6 @@ STDMETHODIMP COgrLayer::Serialize(BSTR* retVal) // ************************************************************* CPLXMLNode* COgrLayer::SerializeCore(CString ElementName) { - CSingleLock lock(&_loader.ProviderLock, TRUE); CPLXMLNode* psTree = CPLCreateXMLNode(NULL, CXT_Element, ElementName); USES_CONVERSION; @@ -1163,11 +1017,14 @@ CPLXMLNode* COgrLayer::SerializeCore(CString ElementName) if (_loader.GetMaxCacheCount() != m_globalSettings.ogrLayerMaxFeatureCount) Utility::CPLCreateXMLAttributeAndValue(psTree, "MaxFeatureCount", CPLString().Printf("%d", (int)_loader.GetMaxCacheCount())); + { // Lock shape file + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); if (_shapefile) { CPLXMLNode* sfNode = ((CShapefile*)_shapefile)->SerializeCore(VARIANT_FALSE, "ShapefileData", true); CPLAddXMLChild(psTree, sfNode); } + } return psTree; } @@ -1176,8 +1033,7 @@ CPLXMLNode* COgrLayer::SerializeCore(CString ElementName) // ************************************************************* STDMETHODIMP COgrLayer::Deserialize(BSTR newVal, VARIANT_BOOL* retVal) { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); + AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retVal = VARIANT_FALSE; USES_CONVERSION; @@ -1201,7 +1057,6 @@ STDMETHODIMP COgrLayer::Deserialize(BSTR newVal, VARIANT_BOOL* retVal) // ************************************************************* bool COgrLayer::DeserializeCore(CPLXMLNode* node) { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!node) return false; Close(); @@ -1238,7 +1093,6 @@ bool COgrLayer::DeserializeCore(CPLXMLNode* node) // ************************************************************* bool COgrLayer::DeserializeOptions(CPLXMLNode* node) { - CSingleLock lock(&_loader.ProviderLock, TRUE); bool success = true; _loader.LabelExpression = Utility::ConvertFromUtf8(CPLGetXMLValue(node, "LabelExpression", "")); @@ -1257,15 +1111,15 @@ bool COgrLayer::DeserializeOptions(CPLXMLNode* node) CPLXMLNode* psChild = CPLGetXMLNode(node, "ShapefileData"); if (psChild) { // Lock shape file + CSingleLock sfLock(&_loader.ShapefileLock, _dynamicLoading ? TRUE : FALSE); if (!_shapefile) { IShapefile * sf = LoadShapefile(); _shapefile = sf; - } - CSingleLock sfLock(&((CShapefile*)_shapefile)->ShapefileLock, TRUE); bool result = ((CShapefile*)_shapefile)->DeserializeCore(VARIANT_FALSE, psChild); if (!result) success = false; } } + } CString key = CPLGetXMLValue(node, "Key", ""); if (key.GetLength() > 0) @@ -1282,7 +1136,6 @@ bool COgrLayer::DeserializeOptions(CPLXMLNode* node) STDMETHODIMP COgrLayer::get_GdalLastErrorMsg(BSTR* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); CStringW s = OgrHelper::OgrString2Unicode(CPLGetLastErrorMsg()); *pVal = W2BSTR(s); return S_OK; @@ -1300,7 +1153,6 @@ STDMETHODIMP COgrLayer::get_DynamicLoading(VARIANT_BOOL* pVal) STDMETHODIMP COgrLayer::put_DynamicLoading(VARIANT_BOOL newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); _dynamicLoading = newVal; if (newVal) { ForceCreateShapefile(); @@ -1314,14 +1166,12 @@ STDMETHODIMP COgrLayer::put_DynamicLoading(VARIANT_BOOL newVal) STDMETHODIMP COgrLayer::get_MaxFeatureCount(LONG* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = _loader.GetMaxCacheCount(); return S_OK; } STDMETHODIMP COgrLayer::put_MaxFeatureCount(LONG newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); _loader.SetMaxCacheCount(newVal <= 0 ? m_globalSettings.ogrLayerMaxFeatureCount : newVal); return S_OK; } @@ -1332,7 +1182,6 @@ STDMETHODIMP COgrLayer::put_MaxFeatureCount(LONG newVal) bool COgrLayer::HasStyleTable() { if (!CheckState()) return false; - CSingleLock lock(&_loader.ProviderLock, TRUE); return OgrStyleHelper::HasStyleTable(_dataset, GetLayerName()); } @@ -1341,7 +1190,6 @@ bool COgrLayer::HasStyleTable() // ************************************************************* CStringW COgrLayer::GetLayerName() { - CSingleLock lock(&_loader.ProviderLock, TRUE); return OgrHelper::OgrString2Unicode(_layer->GetName()); } @@ -1350,7 +1198,6 @@ CStringW COgrLayer::GetLayerName() // ************************************************************* CStringW COgrLayer::GetStyleTableName() { - CSingleLock lock(&_loader.ProviderLock, TRUE); return OgrStyleHelper::GetStyleTableName(GetLayerName()); } @@ -1360,7 +1207,6 @@ CStringW COgrLayer::GetStyleTableName() STDMETHODIMP COgrLayer::get_SupportsStyles(VARIANT_BOOL* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -1386,7 +1232,6 @@ STDMETHODIMP COgrLayer::get_SupportsStyles(VARIANT_BOOL* pVal) STDMETHODIMP COgrLayer::SaveStyle(BSTR Name, CStringW xml, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -1417,7 +1262,6 @@ STDMETHODIMP COgrLayer::SaveStyle(BSTR Name, CStringW xml, VARIANT_BOOL* retVal) STDMETHODIMP COgrLayer::GetNumStyles(LONG* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = -1; if (!CheckState()) return S_OK; @@ -1445,7 +1289,6 @@ STDMETHODIMP COgrLayer::GetNumStyles(LONG* pVal) STDMETHODIMP COgrLayer::get_StyleName(LONG styleIndex, BSTR* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!CheckState()) return S_OK; @@ -1484,8 +1327,8 @@ STDMETHODIMP COgrLayer::get_StyleName(LONG styleIndex, BSTR* pVal) // ************************************************************* CStringW COgrLayer::LoadStyleXML(CStringW name) { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!CheckState()) return L""; + CSingleLock lock(&_loader.ProviderLock, _dynamicLoading ? TRUE : FALSE); return OgrStyleHelper::LoadStyle(_dataset, GetStyleTableName(), GetLayerName(), name); } @@ -1495,7 +1338,6 @@ CStringW COgrLayer::LoadStyleXML(CStringW name) STDMETHODIMP COgrLayer::ClearStyles(VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!CheckState() || !HasStyleTable()) { @@ -1520,7 +1362,6 @@ STDMETHODIMP COgrLayer::ClearStyles(VARIANT_BOOL* retVal) STDMETHODIMP COgrLayer::RemoveStyle(BSTR styleName, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -1538,7 +1379,6 @@ STDMETHODIMP COgrLayer::get_LabelExpression(BSTR* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = W2BSTR(_loader.LabelExpression); return S_OK; } @@ -1546,7 +1386,6 @@ STDMETHODIMP COgrLayer::put_LabelExpression(BSTR newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock lock(&_loader.ProviderLock, TRUE); _loader.LabelExpression = OLE2W(newVal); return S_OK; } @@ -1557,14 +1396,12 @@ STDMETHODIMP COgrLayer::put_LabelExpression(BSTR newVal) STDMETHODIMP COgrLayer::get_LabelPosition(tkLabelPositioning* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = _loader.LabelPosition; return S_OK; } STDMETHODIMP COgrLayer::put_LabelPosition(tkLabelPositioning newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); _loader.LabelPosition = newVal; return S_OK; } @@ -1575,14 +1412,12 @@ STDMETHODIMP COgrLayer::put_LabelPosition(tkLabelPositioning newVal) STDMETHODIMP COgrLayer::get_LabelOrientation(tkLineLabelOrientation* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = _loader.LabelOrientation; return S_OK; } STDMETHODIMP COgrLayer::put_LabelOrientation(tkLineLabelOrientation newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); _loader.LabelOrientation = newVal; return S_OK; } @@ -1592,7 +1427,6 @@ STDMETHODIMP COgrLayer::put_LabelOrientation(tkLineLabelOrientation newVal) // ************************************************************* void COgrLayer::GetFieldValues(OGRFieldType fieldType, BSTR& fieldName, vector& values) { - CSingleLock lock(&_loader.ProviderLock, TRUE); if (_sourceType == ogrDbTable || _sourceType == ogrFile) { // load only the necessary column @@ -1620,7 +1454,6 @@ STDMETHODIMP COgrLayer::GenerateCategories(BSTR FieldName, tkClassificationType tkColorSchemeType schemeType, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *retVal = VARIANT_FALSE; if (!CheckState()) return S_OK; @@ -1702,7 +1535,6 @@ STDMETHODIMP COgrLayer::GenerateCategories(BSTR FieldName, tkClassificationType STDMETHODIMP COgrLayer::get_DriverName(BSTR* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); if (!CheckState()) { *pVal = A2BSTR(""); @@ -1722,7 +1554,6 @@ STDMETHODIMP COgrLayer::get_DriverName(BSTR* pVal) STDMETHODIMP COgrLayer::get_AvailableShapeTypes(VARIANT* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); vector result; if (!CheckState()) @@ -1778,7 +1609,6 @@ STDMETHODIMP COgrLayer::get_AvailableShapeTypes(VARIANT* pVal) // ************************************************************* void COgrLayer::GetMsSqlShapeTypes(vector& result) { - CSingleLock lock(&_loader.ProviderLock, TRUE); CStringW cmnName = Utility::ConvertFromUtf8(_layer->GetGeometryColumn()); CStringW layerName = Utility::ConvertFromUtf8(_layer->GetName()); CStringW sql; @@ -1823,7 +1653,6 @@ void COgrLayer::GetMsSqlShapeTypes(vector& result) STDMETHODIMP COgrLayer::get_ActiveShapeType(ShpfileType* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); ShpfileType shpType; get_ShapeType(&shpType); @@ -1836,7 +1665,6 @@ STDMETHODIMP COgrLayer::get_ActiveShapeType(ShpfileType* pVal) STDMETHODIMP COgrLayer::put_ActiveShapeType(ShpfileType newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); ShpfileType shpType; get_ShapeType(&shpType); @@ -1867,7 +1695,6 @@ STDMETHODIMP COgrLayer::put_ActiveShapeType(ShpfileType newVal) STDMETHODIMP COgrLayer::get_IsExternalDatasource(VARIANT_BOOL* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock lock(&_loader.ProviderLock, TRUE); *pVal = _externalDatasource; diff --git a/src/COM classes/OgrLayer.h b/src/COM classes/OgrLayer.h index 13cc714d..01eabad8 100644 --- a/src/COM classes/OgrLayer.h +++ b/src/COM classes/OgrLayer.h @@ -79,7 +79,6 @@ class ATL_NO_VTABLE COgrLayer : STDMETHOD(put_GlobalCallback)(/*[in]*/ ICallback * newVal); STDMETHOD(OpenDatabaseLayer)(BSTR connectionString, int layerIndex, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal); // not in public API STDMETHOD(OpenFromQuery)(BSTR connectionString, BSTR sql, VARIANT_BOOL* retVal); - STDMETHOD(ExtendFromQuery)(BSTR sql, VARIANT_BOOL* retVal); STDMETHOD(OpenFromDatabase)(BSTR connectionString, BSTR layerName, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal); STDMETHOD(Close)(); STDMETHOD(get_Name)(BSTR* retVal); @@ -174,7 +173,6 @@ class ATL_NO_VTABLE COgrLayer : public: void InjectShapefile(IShapefile* sfNew); - void UpdateShapefileFromOGRLoader(); OGRLayer* GetDatasource() { return _layer; } CPLXMLNode* SerializeCore(CString ElementName); bool DeserializeCore(CPLXMLNode* node); diff --git a/src/COM classes/ShapeEditor.cpp b/src/COM classes/ShapeEditor.cpp index 780d5db3..98a4b13c 100644 --- a/src/COM classes/ShapeEditor.cpp +++ b/src/COM classes/ShapeEditor.cpp @@ -1211,17 +1211,17 @@ bool CShapeEditor::TrySaveShape(IShape* shp) } VARIANT_BOOL vb; - long shapeIndex = _shapeIndex; - long layerHandle = _layerHandle; + int shapeIndex = _shapeIndex; + int layerHandle = _layerHandle; bool newShape = _shapeIndex == -1; if (newShape) { - long newIndex; - sf->EditAddShape(shp, &newIndex); + long numShapes = ShapefileHelper::GetNumShapes(sf); IUndoList* undoList = _mapCallback->_GetUndoList(); - undoList->Add(uoAddShape, (long)_layerHandle, newIndex, &vb); - shapeIndex = newIndex; + undoList->Add(uoAddShape, (long)_layerHandle, (long)numShapes, &vb); + sf->EditInsertShape(shp, &numShapes, &vb); + shapeIndex = numShapes; } else { diff --git a/src/COM classes/Shapefile.cpp b/src/COM classes/Shapefile.cpp index f0d22a53..9f6eee27 100644 --- a/src/COM classes/Shapefile.cpp +++ b/src/COM classes/Shapefile.cpp @@ -1,3594 +1,3489 @@ -//******************************************************************************************************** -//File name: Shapefile.cpp -//Description: Implementation of the CShapefile -//******************************************************************************************************** -//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); -//you may not use this file except in compliance with the License. You may obtain a copy of the License at -//http://www.mozilla.org/MPL/ -//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF -//ANY KIND, either express or implied. See the License for the specific language governing rights and -//limitations under the License. -// -//The Original Code is MapWindow Open Source. -// -//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by -//Utah State University and the Idaho National Engineering and Environmental Lab that were released as -//public domain in March 2004. -//******************************************************************************************************** -// -//Contributor(s): (Open source contributors should list themselves and their modifications here). -// ------------------------------------------------------------------------------------------------------- -// Paul Meems August 2018: Modernized the code as suggested by CLang and ReSharper - -#include "StdAfx.h" -#include -#include "Shapefile.h" -#include "Labels.h" -#include "Charts.h" -#include "GeoProjection.h" -#include "Templates.h" -#include -#include "ShapefileCategories.h" -#include "Shape.h" -#include "GeosConverter.h" -#include "ShapefileHelper.h" -#include "LabelsHelper.h" -#include "ShapeStyleHelper.h" -#include "TableClass.h" - -#ifdef _DEBUG - #define new DEBUG_NEW - #undef THIS_FILE - static char THIS_FILE[] = __FILE__; -#endif - -CShapefile::CShapefile() -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - - _pUnkMarshaler = nullptr; - - _sortingChanged = true; - _sortAscending = VARIANT_FALSE; - _sortField = SysAllocString(L""); - - _appendStartShapeCount = -1; - _appendMode = VARIANT_FALSE; - _snappable = VARIANT_TRUE; - _interactiveEditing = VARIANT_FALSE; - _hotTracking = VARIANT_TRUE; - _selectable = VARIANT_FALSE; - _geosGeometriesRead = false; - _stopExecution = nullptr; - - _selectionTransparency = 180; - _selectionAppearance = saSelectionColor; - _selectionColor = RGB(255, 255, 0); - _collisionMode = tkCollisionMode::LocalList; - - _geometryEngine = m_globalSettings.geometryEngine; - - _sourceType = sstUninitialized; - - _writing = false; - _reading = false; - - _isEditingShapes = FALSE; - _fastMode = m_globalSettings.shapefileFastMode ? TRUE : FALSE; - _minDrawingSize = 1; - _volatile = false; - - _useSpatialIndex = TRUE; - _hasSpatialIndex = FALSE; - _spatialIndexLoaded = FALSE; - _spatialIndexMaxAreaPercent = 0.5; - _spatialIndexNodeCapacity = 100; - - //Neio 20090721 - _useQTree = FALSE; - _cacheExtents = FALSE; - _qtree = nullptr; - _tempTree = nullptr; - - _shpfile = nullptr; - _shxfile = nullptr; - - _shpfiletype = SHP_NULLSHAPE; - _nextShapeHandle = 0; - - _minX = 0.0; - _minY = 0.0; - _minZ = 0.0; - _maxX = 0.0; - _maxY = 0.0; - _maxZ = 0.0; - _minM = 0.0; - _maxM = 0.0; - - _key = SysAllocString(L""); - _expression = SysAllocString(L""); - _globalCallback = nullptr; - _lastErrorCode = tkNO_ERROR; - _table = nullptr; - - // creation of children classes - _selectDrawOpt = nullptr; - _defaultDrawOpt = nullptr; - _labels = nullptr; - _categories = nullptr; - _charts = nullptr; - _geoProjection = nullptr; - - ComHelper::CreateInstance(idShapeValidationInfo, (IDispatch**)&_inputValidation); - ComHelper::CreateInstance(idShapeValidationInfo, (IDispatch**)&_outputValidation); - - CoCreateInstance(CLSID_ShapeDrawingOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IShapeDrawingOptions, - (void**)&_selectDrawOpt); - CoCreateInstance(CLSID_ShapeDrawingOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IShapeDrawingOptions, - (void**)&_defaultDrawOpt); - CoCreateInstance(CLSID_ShapefileCategories, nullptr, CLSCTX_INPROC_SERVER, IID_IShapefileCategories, - (void**)&_categories); - CoCreateInstance(CLSID_Labels, nullptr, CLSCTX_INPROC_SERVER, IID_ILabels, (void**)&_labels); - CoCreateInstance(CLSID_Charts, nullptr, CLSCTX_INPROC_SERVER, IID_ICharts, (void**)&_charts); - CoCreateInstance(CLSID_GeoProjection, nullptr, CLSCTX_INPROC_SERVER, IID_IGeoProjection, (void**)&_geoProjection); - - this->put_ReferenceToLabels(); - this->put_ReferenceToCategories(); - this->put_ReferenceToCharts(); - - ComHelper::CreateInstance(idUndoList, (IDispatch**)&_undoList); - - gReferenceCounter.AddRef(tkInterface::idShapefile); -} - -CShapefile::~CShapefile() -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - - VARIANT_BOOL vbretval; - this->CShapefile::Close(&vbretval); - - SysFreeString(_key); - SysFreeString(_expression); - SysFreeString(_sortField); - - if (_selectDrawOpt != nullptr) - _selectDrawOpt->Release(); - - if (_defaultDrawOpt != nullptr) - _defaultDrawOpt->Release(); - - if (_labels != nullptr) - { - put_ReferenceToLabels(true); // labels class maybe referenced by client and won't be deleted as a result - _labels->Release(); // therefore we must clear the reference to the parent as it will be invalid - } - - if (_categories != nullptr) - { - put_ReferenceToCategories(true); - _categories->Release(); - } - - if (_charts != nullptr) - { - put_ReferenceToCharts(true); - _charts->Release(); - } - - if (_stopExecution) - _stopExecution->Release(); - - if (_geoProjection) - _geoProjection->Release(); - - if (_undoList) - { - _undoList->Release(); - } - gReferenceCounter.Release(tkInterface::idShapefile); -} - -std::vector* CShapefile::get_ShapeVector() -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - return &_shapeData; -} - -IShapeWrapper* CShapefile::get_ShapeWrapper(int ShapeIndex) -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - return ((CShape*)_shapeData[ShapeIndex]->shape)->get_ShapeWrapper(); -} - -IShapeData* CShapefile::get_ShapeRenderingData(int ShapeIndex) -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - return _shapeData[ShapeIndex]->get_RenderingData(); -} - -void CShapefile::put_ShapeRenderingData(int ShapeIndex, CShapeData* data) -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - return _shapeData[ShapeIndex]->put_RenderingData(data); -} - -void CShapefile::SetValidationInfo(IShapeValidationInfo* info, tkShapeValidationType validationType) -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - ComHelper::SetRef(info, - (IDispatch**)&(validationType == svtInput ? _inputValidation : _outputValidation), true); -} - -#pragma region Properties - -// ************************************************************ -// get_EditingShapes() -// ************************************************************ -STDMETHODIMP CShapefile::get_EditingShapes(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _isEditingShapes ? VARIANT_TRUE : VARIANT_FALSE; - return S_OK; -} - -// ************************************************************ -// get_LastErrorCode() -// ************************************************************ -STDMETHODIMP CShapefile::get_LastErrorCode(long* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _lastErrorCode; - _lastErrorCode = tkNO_ERROR; - return S_OK; -} - -// ************************************************************ -// get_CdlgFilter() -// ************************************************************ -STDMETHODIMP CShapefile::get_CdlgFilter(BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - *pVal = A2BSTR("ESRI Shapefiles (*.shp)|*.shp"); - return S_OK; -} - -// ************************************************************ -// LastInputValidation -// ************************************************************ -STDMETHODIMP CShapefile::get_LastInputValidation(IShapeValidationInfo** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_inputValidation) - _inputValidation->AddRef(); - *retVal = _inputValidation; - return S_OK; -} - -// ************************************************************ -// LastOutputValidation -// ************************************************************ -STDMETHODIMP CShapefile::get_LastOutputValidation(IShapeValidationInfo** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_outputValidation) - _outputValidation->AddRef(); - *retVal = _outputValidation; - return S_OK; -} - -// ************************************************************ -// get/put_GlobalCallback() -// ************************************************************ -STDMETHODIMP CShapefile::get_GlobalCallback(ICallback** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = _globalCallback; - if (_globalCallback != nullptr) - _globalCallback->AddRef(); - return S_OK; -} - -STDMETHODIMP CShapefile::put_GlobalCallback(ICallback* newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - ComHelper::SetRef(newVal, (IDispatch**)&_globalCallback); - if (_table != nullptr) - _table->put_GlobalCallback(newVal); - - return S_OK; -} - -// ************************************************************ -// StopExecution -// ************************************************************ -STDMETHODIMP CShapefile::put_StopExecution(IStopExecution* stopper) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - ComHelper::SetRef((IDispatch*)stopper, (IDispatch**)&_stopExecution, true); - return S_OK; -} - -// ************************************************************ -// get/put_Key() -// ************************************************************ -STDMETHODIMP CShapefile::get_Key(BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - *pVal = OLE2BSTR(_key); - return S_OK; -} - -STDMETHODIMP CShapefile::put_Key(BSTR newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - SysFreeString(_key); - _key = OLE2BSTR(newVal); - return S_OK; -} - -// ************************************************************ -// get/put_VisibilityExpression -// ************************************************************ -STDMETHODIMP CShapefile::get_VisibilityExpression(BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - *pVal = OLE2BSTR(_expression); - return S_OK; -} - -STDMETHODIMP CShapefile::put_VisibilityExpression(BSTR newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - SysFreeString(_expression); - _expression = OLE2BSTR(newVal); - return S_OK; -} - -// ************************************************************ -// get/put_Volatile -// ************************************************************ -STDMETHODIMP CShapefile::get_Volatile(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_interactiveEditing) - { - *pVal = VARIANT_TRUE; - } - else - { - *pVal = _volatile ? VARIANT_TRUE : VARIANT_FALSE; - } - return S_OK; -} - -STDMETHODIMP CShapefile::put_Volatile(VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _volatile = newVal == VARIANT_TRUE; - return S_OK; -} - -// ***************************************************************** -// get_NumShapes() -// ***************************************************************** -STDMETHODIMP CShapefile::get_NumShapes(long* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _shapeData.size(); //_numShapes; - return S_OK; -} - -// ************************************************************** -// get_NumFields() -// ************************************************************** -STDMETHODIMP CShapefile::get_NumFields(long* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_table != nullptr) - _table->get_NumFields(pVal); - else - { - ErrorMessage(tkFILE_NOT_OPEN); - *pVal = 0; - } - return S_OK; -} - -// ************************************************************ -// get_ShapefileType() -// ************************************************************ -STDMETHODIMP CShapefile::get_ShapefileType(ShpfileType* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _shpfiletype; - return S_OK; -} - -// ***************************************************************** -// get_ErrorMsg() -// ***************************************************************** -STDMETHODIMP CShapefile::get_ErrorMsg(long ErrorCode, BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - *pVal = A2BSTR(ErrorMsg(ErrorCode)); - return S_OK; -} - -// ***************************************************************** -// get_FileHandle() -// ***************************************************************** -STDMETHODIMP CShapefile::get_FileHandle(long* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_shpfile != nullptr) - { - const int handle = _fileno(_shpfile); - *pVal = _dup(handle); - } - else - *pVal = -1; - - return S_OK; -} - -// ************************************************************** -// get_Filename() -// ************************************************************** -STDMETHODIMP CShapefile::get_Filename(BSTR* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = W2BSTR(_shpfileName); - - return S_OK; -} - -// ************************************************************** -// ErrorMessage() -// ************************************************************** -void CShapefile::ErrorMessage(long ErrorCode) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - _lastErrorCode = ErrorCode; - CallbackHelper::ErrorMsg("Shapefile", _globalCallback, _key, ErrorMsg(_lastErrorCode)); -} - -void CShapefile::ErrorMessage(long ErrorCode, ICallback* cBack) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - _lastErrorCode = ErrorCode; - CallbackHelper::ErrorMsg("Shapefile", _globalCallback, _key, ErrorMsg(_lastErrorCode)); - if (cBack != _globalCallback) - CallbackHelper::ErrorMsg("Shapefile", cBack, _key, ErrorMsg(_lastErrorCode)); -} - -// ************************************************************ -// get_MinDrawingSize() -// ************************************************************ -STDMETHODIMP CShapefile::get_MinDrawingSize(LONG* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _minDrawingSize; - return S_OK; -} - -STDMETHODIMP CShapefile::put_MinDrawingSize(LONG newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _minDrawingSize = newVal; - return S_OK; -} - -// ************************************************************ -// get_SourceType() -// ************************************************************ -STDMETHODIMP CShapefile::get_SourceType(tkShapefileSourceType* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _sourceType; - return S_OK; -} - -#pragma endregion - -#pragma region CreateAndOpen - - -// ************************************************************ -// LoadDataFrom() -// ************************************************************ -// Loads shape and DBF data from disk file into in-memory mode -STDMETHODIMP CShapefile::LoadDataFrom(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - USES_CONVERSION; - *retval = VARIANT_FALSE; - if (_sourceType != sstInMemory) - { - ErrorMessage(tkINMEMORY_SHAPEFILE_EXPECTED); - return S_OK; - } - - if (OpenCore(OLE2CA(ShapefileName), cBack)) - { - // loading data in-memory - VARIANT_BOOL vb; - _isEditingShapes = false; - StartEditingShapes(VARIANT_TRUE, cBack, &vb); - - // this will trigger loading of all DBF values into the memory - long numFields; - this->get_NumFields(&numFields); - if (numFields > 0) - { - CComVariant var; - for (size_t i = 0; i < _shapeData.size(); i++) - { - _table->get_CellValue(0, i, &var); - } - } - - // closing disk file despite the result success or failure - _shpfileName = ""; - _shxfileName = ""; - _dbffileName = ""; - - if (_shpfile != nullptr) - fclose(_shpfile); - _shpfile = nullptr; - - if (_shxfile != nullptr) - fclose(_shxfile); - _shxfile = nullptr; - - if (_table != nullptr) - ((CTableClass*)_table)->CloseUnderlyingFile(); - - *retval = vb; - } - return S_OK; -} - -// ************************************************************ -// OpenCore() -// ************************************************************ -bool CShapefile::OpenCore(CStringW tmpShpfileName, ICallback* cBack) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - VARIANT_BOOL vbretval; - - // saving the provided names; - // from now on we must clean the class variables in case the operation won't succeed - _shpfileName = tmpShpfileName; - _shxfileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"shx"; - _dbffileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"dbf"; - _prjfileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"prj"; - - // read mode - _shpfile = _wfopen(_shpfileName, L"rb"); - _shxfile = _wfopen(_shxfileName, L"rb"); - - // opening DBF - if (!_table) - { - CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); - } - else - { - VARIANT_BOOL vb; - _table->Close(&vb); - } - - _table->put_GlobalCallback(_globalCallback); - ((CTableClass*)_table)->InjectShapefile(this); - - const CComBSTR bstrDbf(_dbffileName); - _table->Open(bstrDbf, cBack, &vbretval); - - if (_shpfile == nullptr) - { - ErrorMessage(tkCANT_OPEN_SHP); - this->Close(&vbretval); - } - else if (_shxfile == nullptr) - { - ErrorMessage(tkCANT_OPEN_SHX); - this->Close(&vbretval); - } - else if (vbretval == VARIANT_FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - ErrorMessage(_lastErrorCode); - this->Close(&vbretval); - } - else - { - if (!ReadShx()) // shapefile header is read here as well - { - ErrorMessage(tkINVALID_SHX_FILE); - this->Close(&vbretval); - } - else - { - //Check for supported types - if (_shpfiletype != SHP_NULLSHAPE && - _shpfiletype != SHP_POINT && - _shpfiletype != SHP_POLYLINE && - _shpfiletype != SHP_POLYGON && - _shpfiletype != SHP_POINTZ && - _shpfiletype != SHP_POLYLINEZ && - _shpfiletype != SHP_POLYGONZ && - _shpfiletype != SHP_MULTIPOINT && - _shpfiletype != SHP_MULTIPOINTZ && - _shpfiletype != SHP_POLYLINEM && - _shpfiletype != SHP_POLYGONM && - _shpfiletype != SHP_POINTM && - _shpfiletype != SHP_MULTIPOINTM) - { - ErrorMessage(tkUNSUPPORTED_SHAPEFILE_TYPE); - this->Close(&vbretval); - } - else - { - _shapeData.reserve(_shpOffsets.size()); - for (size_t i = 0; i < _shpOffsets.size(); i++) - { - _shapeData.push_back(new ShapeRecord()); - } - return true; - } - } - } - return false; -} - -// ************************************************************ -// Open() -// ************************************************************ -STDMETHODIMP CShapefile::Open(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - VARIANT_BOOL vbretval; - - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - USES_CONVERSION; - CStringW tmp_shpfileName = OLE2CW(ShapefileName); - - if (tmp_shpfileName.GetLength() == 0) - { - // better to use CreateNew directly, but this call will be preserved for backward compatibility - this->CreateNew(m_globalSettings.emptyBstr, _shpfiletype, &vbretval); - } - else if (tmp_shpfileName.GetLength() <= 3) - { - ErrorMessage(tkINVALID_FILENAME); - } - else - { - // close the opened shapefile - this->Close(&vbretval); - - if (vbretval == VARIANT_FALSE) - { - // error code in the function - return S_OK; - } - - if (OpenCore(tmp_shpfileName, cBack)) - { - _sourceType = sstDiskBased; - - // reading projection - const CComBSTR bstrPrj(_prjfileName); - _geoProjection->ReadFromFileEx(bstrPrj, VARIANT_TRUE, &vbretval); - - ShapeStyleHelper::ApplyRandomDrawingOptions(this); - LabelsHelper::UpdateLabelsPositioning(this); - *retval = VARIANT_TRUE; - } - } - return S_OK; -} - -// ********************************************************* -// CreateNew() -// ********************************************************* -STDMETHODIMP CShapefile::CreateNew(BSTR ShapefileName, ShpfileType ShapefileType, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - return this->CreateNewCore(ShapefileName, ShapefileType, true, retval); -} - -// ********************************************************* -// CreateNewCore() -// ********************************************************* -HRESULT CShapefile::CreateNewCore(BSTR ShapefileName, ShpfileType ShapefileType, bool applyRandomOptions, - VARIANT_BOOL* retval) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - VARIANT_BOOL vb; - - // check for supported types - if (ShapefileType != SHP_NULLSHAPE && - ShapefileType != SHP_POINT && - ShapefileType != SHP_POLYLINE && - ShapefileType != SHP_POLYGON && - ShapefileType != SHP_POINTZ && - ShapefileType != SHP_POLYLINEZ && - ShapefileType != SHP_POLYGONZ && - ShapefileType != SHP_MULTIPOINT && - ShapefileType != SHP_MULTIPOINTZ && - ShapefileType != SHP_POINTM && // MWGIS-69 - ShapefileType != SHP_POLYLINEM && - ShapefileType != SHP_POLYGONM && - ShapefileType != SHP_MULTIPOINTM) - { - ErrorMessage(tkUNSUPPORTED_SHAPEFILE_TYPE); - return S_OK; - } - - USES_CONVERSION; - CString tmp_shpfileName = OLE2CA(ShapefileName); - - // ---------------------------------------------- - // in memory shapefile (without name) - // ---------------------------------------------- - if (tmp_shpfileName.GetLength() == 0) - { - // closing the old shapefile (error code inside the function) - Close(&vb); - - if (vb == VARIANT_TRUE) - { - CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); - - _table->CreateNew(m_globalSettings.emptyBstr, &vb); - - if (!vb) - { - long error; - _table->get_LastErrorCode(&error); - ErrorMessage(error); - _table->Release(); - _table = nullptr; - } - else - { - _shpfiletype = ShapefileType; - _isEditingShapes = true; - _sourceType = sstInMemory; - - if (applyRandomOptions) - { - ShapeStyleHelper::ApplyRandomDrawingOptions(this); - } - - *retval = VARIANT_TRUE; - } - } - - return S_OK; - } - - if (tmp_shpfileName.GetLength() <= 3) - { - ErrorMessage(tkINVALID_FILENAME); - return S_OK; - } - - const CString& shpName = tmp_shpfileName; - const CString shxName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "shx"; - const CString dbfName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; - const CString prjName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "prj"; - - // new file is created, so there must not be any files with this names - if (Utility::FileExists(shpName) != FALSE) - { - ErrorMessage(tkSHP_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExists(shxName) != FALSE) - { - ErrorMessage(tkSHX_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExists(dbfName) != FALSE) - { - ErrorMessage(tkDBF_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExists(prjName) != FALSE) - { - ErrorMessage(tkPRJ_FILE_EXISTS); - return S_OK; - } - - // closing the old shapefile (error code inside the function) - this->Close(&vb); - - if (vb == VARIANT_TRUE) - { - CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); - - _table->put_GlobalCallback(_globalCallback); - - const CString newDbfName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; - const CComBSTR bstrName(newDbfName); - _table->CreateNew(bstrName, &vb); - - if (!vb) - { - _table->get_LastErrorCode(&_lastErrorCode); - ErrorMessage(_lastErrorCode); - _table->Release(); - _table = nullptr; - } - else - { - _shpfileName = tmp_shpfileName; - _shxfileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "shx"; - _dbffileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; - _prjfileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "prj"; - - _shpfiletype = ShapefileType; - _isEditingShapes = true; - _sourceType = sstInMemory; - - if (applyRandomOptions) - { - ShapeStyleHelper::ApplyRandomDrawingOptions(this); - } - - *retval = VARIANT_TRUE; - } - } - - LabelsHelper::UpdateLabelsPositioning(this); - - return S_OK; -} - -// ********************************************************* -// CreateNewWithShapeID() -// ********************************************************* -STDMETHODIMP CShapefile::CreateNewWithShapeID(BSTR ShapefileName, ShpfileType ShapefileType, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - USES_CONVERSION; - CSingleLock sfLock(&ShapefileLock, TRUE); - - CreateNew(ShapefileName, ShapefileType, retval); - - if (*retval) - ShapefileHelper::InsertMwShapeIdField(this); - - return S_OK; -} - -#pragma endregion - -#pragma region SaveAndClose -// ***************************************************************** -// Close() -// ***************************************************************** -STDMETHODIMP CShapefile::Close(VARIANT_BOOL* retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_appendMode) - { - StopAppendMode(); - } - - ClearCachedGeometries(); - - if (_isEditingShapes) - { - // just stop editing shapes, if the shape is in open status - this->StopEditingShapes(VARIANT_FALSE, VARIANT_TRUE, nullptr, retval); - } - - // stop editing table in case only it have been edited - VARIANT_BOOL isEditingTable = VARIANT_FALSE; - if (_table) - { - _table->get_EditingTable(&isEditingTable); - if (isEditingTable) - { - this->StopEditingTable(VARIANT_FALSE, _globalCallback, retval); - _table->get_EditingTable(&isEditingTable); - } - } - - // removing shape data - this->ReleaseMemoryShapes(); - for (auto& i : _shapeData) - { - delete i; - } - _shapeData.clear(); - - if (_spatialIndexLoaded) - IndexSearching::unloadSpatialIndex(_spatialIndexID); - - _sourceType = sstUninitialized; - _shpfiletype = SHP_NULLSHAPE; - LabelsHelper::UpdateLabelsPositioning(this); - - _shpfileName = ""; - _shxfileName = ""; - _dbffileName = ""; - - _minX = 0.0; - _minY = 0.0; - _minZ = 0.0; - _maxX = 0.0; - _maxY = 0.0; - _maxZ = 0.0; - _minM = 0.0; - _maxM = 0.0; - - if (_inputValidation != nullptr) - { - _inputValidation->Release(); - _inputValidation = nullptr; - } - - if (_outputValidation != nullptr) - { - _outputValidation->Release(); - _outputValidation = nullptr; - } - - if (_shpfile != nullptr) fclose(_shpfile); - _shpfile = nullptr; - - if (_shxfile != nullptr) fclose(_shxfile); - _shxfile = nullptr; - - if (_table != nullptr) - { - VARIANT_BOOL vbretval; - _table->Close(&vbretval); - _table->Release(); - _table = nullptr; - } - if (_labels) - { - _labels->Clear(); - _labels->ClearCategories(); - } - if (_charts) - { - _charts->Clear(); - } - if (_categories) - { - _categories->Clear(); - } - *retval = VARIANT_TRUE; - - return S_OK; -} - -// ********************************************************** -// Dump() -// ********************************************************** -//Saves shapefile without reopening it in a new location -STDMETHODIMP CShapefile::Dump(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - const bool callbackIsNull = _globalCallback == nullptr; - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if (_table == nullptr || _sourceType == sstUninitialized) - { - ErrorMessage(tkSHAPEFILE_UNINITIALIZED); - return S_OK; - } - - // in case someone else is writing, we leave - if (_writing) - { - ErrorMessage(tkSHP_WRITE_VIOLATION); - return S_OK; - } - - if (!this->ValidateOutput(this, "Dump", "Shapefile", false)) - return S_OK; - - USES_CONVERSION; - CString sa_shpfileName = OLE2CA(ShapefileName); - - if (sa_shpfileName.GetLength() <= 3) - { - ErrorMessage(tkINVALID_FILENAME); - } - else - { - const CString sa_shxfileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + "shx"; - CString sa_dbffileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + "dbf"; - - // ----------------------------------------------- - // it's not allowed to rewrite the existing files - // ----------------------------------------------- - if (Utility::FileExists(sa_shpfileName)) - { - ErrorMessage(tkSHP_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExists(sa_shxfileName)) - { - ErrorMessage(tkSHX_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExists(sa_dbffileName)) - { - ErrorMessage(tkDBF_FILE_EXISTS); - return S_OK; - } - - // ----------------------------------------------- - // checking in-memory shapes - // ----------------------------------------------- - if (_isEditingShapes) - { - if (VerifyMemShapes(cBack) == FALSE) - { - // error Code is set in function - return S_OK; - } - - // refresh extents - VARIANT_BOOL retVal; - this->RefreshExtents(&retVal); - } - - // ----------------------------------------------- - // opening files - // ----------------------------------------------- - FILE* shpfile = fopen(sa_shpfileName, "wb+"); - if (shpfile == nullptr) - { - ErrorMessage(tkCANT_CREATE_SHP); - return S_OK; - } - - //shx - FILE* shxfile = fopen(sa_shxfileName, "wb+"); - if (shxfile == nullptr) - { - fclose(shpfile); - ErrorMessage(tkCANT_CREATE_SHX); - return S_OK; - } - - // ------------------------------------------------ - // writing the files - // ------------------------------------------------ - this->WriteShp(shpfile, cBack); - this->WriteShx(shxfile, cBack); - - fclose(shpfile); - fclose(shxfile); - - // ------------------------------------------------ - // saving dbf table - // ------------------------------------------------ - _table->Dump(sa_dbffileName.AllocSysString(), cBack, retval); - if (*retval == FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - return S_OK; - } - - // saving projection in new format - VARIANT_BOOL vbretval; - const CStringW prjfileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + L"prj"; - const CComBSTR bstr(prjfileName); - _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); - - *retval = VARIANT_TRUE; - } - - // restoring callback - if (callbackIsNull) - { - _globalCallback = nullptr; - } - - return S_OK; -} - -// ********************************************************** -// SaveAs() -// ********************************************************** -// Saves shapefile to the new or the same location. Doesn't stop editing mode. -STDMETHODIMP CShapefile::SaveAs(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - const bool callbackIsNull = _globalCallback == nullptr; - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if (_table == nullptr || _sourceType == sstUninitialized) - { - ErrorMessage(tkSHAPEFILE_UNINITIALIZED); - return S_OK; - } - - // in case someone else is writing, we leave - if (_writing) - { - ErrorMessage(tkSHP_WRITE_VIOLATION); - return S_OK; - } - - if (!this->ValidateOutput(this, "SaveAs", "Shapefile", false)) - return S_OK; - - USES_CONVERSION; - CStringW newShpName = OLE2W(ShapefileName); - - if (newShpName.GetLength() <= 3) - { - ErrorMessage(tkINVALID_FILENAME); - } - else if (!Utility::EndsWith(newShpName, L".shp")) - { - ErrorMessage(tkINVALID_FILE_EXTENSION); - } - else - { - const CStringW newShxName = newShpName.Left(newShpName.GetLength() - 3) + L"shx"; - const CStringW newDbfName = newShpName.Left(newShpName.GetLength() - 3) + L"dbf"; - - // ----------------------------------------------- - // it's not allowed to rewrite the existing files - // ----------------------------------------------- - if (Utility::FileExistsW(newShpName)) - { - ErrorMessage(tkSHP_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExistsW(newShxName)) - { - ErrorMessage(tkSHX_FILE_EXISTS); - return S_OK; - } - if (Utility::FileExistsW(newDbfName)) - { - ErrorMessage(tkDBF_FILE_EXISTS); - return S_OK; - } - - // ----------------------------------------------- - // checking in-memory shapes - // ----------------------------------------------- - if (_isEditingShapes) - { - if (VerifyMemShapes(cBack) == FALSE) - { - // error Code is set in function - return S_OK; - } - - // refresh extents - VARIANT_BOOL retVal; - RefreshExtents(&retVal); - } - - // ----------------------------------------------- - // opening files - // ----------------------------------------------- - FILE* shpfile = _wfopen(newShpName, L"wb+"); - if (shpfile == nullptr) - { - ErrorMessage(tkCANT_CREATE_SHP); - return S_OK; - } - - //shx - FILE* shxfile = _wfopen(newShxName, L"wb+"); - if (shxfile == nullptr) - { - fclose(shpfile); - ErrorMessage(tkCANT_CREATE_SHX); - return S_OK; - } - - // ------------------------------------------------ - // writing the files - // ------------------------------------------------ - WriteShp(shpfile, cBack); - WriteShx(shxfile, cBack); - - fclose(shpfile); - fclose(shxfile); - - // ------------------------------------------------ - // saving dbf table - // ------------------------------------------------ - const CComBSTR bstrDbf(newDbfName); - _table->SaveAs(bstrDbf, cBack, retval); - - if (*retval != VARIANT_TRUE) - { - _table->get_LastErrorCode(&_lastErrorCode); - _wunlink(newShpName); - _wunlink(newShxName); - return S_OK; - } - - // ------------------------------------------------- - // switching to the new files - // ------------------------------------------------- - shpfile = _wfopen(newShpName, L"rb"); - shxfile = _wfopen(newShxName, L"rb"); - - if (_shpfile != nullptr) fclose(_shpfile); - _shpfile = shpfile; - - if (_shxfile != nullptr) fclose(_shxfile); - _shxfile = shxfile; - - // update all filenames: - _shpfileName = newShpName; // saving of shp filename should be done before writing the projection; - _shxfileName = newShxName; // otherwise projection string will be written to the memory - _dbffileName = newDbfName; - _prjfileName = newShpName.Left(newShpName.GetLength() - 3) + L"prj"; - - _sourceType = sstDiskBased; - - // saving projection in new format - VARIANT_BOOL vbretval, isEmpty; - _geoProjection->get_IsEmpty(&isEmpty); - if (!isEmpty) - { - const CComBSTR bstr(_prjfileName); - _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); - } - - if (_useQTree) - GenerateQTree(); - - *retval = VARIANT_TRUE; - } - - // restoring callback - if (callbackIsNull) - { - _globalCallback = nullptr; - } - - return S_OK; -} - -// ************************************************************** -// Save() -// ************************************************************** -// saving without exiting edit mode -STDMETHODIMP CShapefile::Save(ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - // no edits were made; it doesn't make sense to save it - if (_isEditingShapes == FALSE) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - return S_OK; - } - - if (VerifyMemShapes(_globalCallback) == FALSE) - { - // error Code is set in function - return S_OK; - } - - if (!this->ValidateOutput(this, "Save", "Shapefile", false)) - return S_OK; - - // compute the extents - VARIANT_BOOL res; - RefreshExtents(&res); - - // ------------------------------------------------- - // Reopen the files in the write mode - // ------------------------------------------------- - if (_shpfile && _shxfile) - { - _shpfile = _wfreopen(_shpfileName, L"wb+", _shpfile); - _shxfile = _wfreopen(_shxfileName, L"wb+", _shxfile); - } - else - { - _shpfile = _wfopen(_shpfileName, L"wb+"); - _shxfile = _wfopen(_shxfileName, L"wb+"); - } - - if (_shpfile == nullptr || _shxfile == nullptr) - { - if (_shxfile != nullptr) - { - fclose(_shxfile); - _shxfile = nullptr; - _lastErrorCode = tkCANT_OPEN_SHX; - } - if (_shpfile != nullptr) - { - fclose(_shpfile); - _shpfile = nullptr; - _lastErrorCode = tkCANT_OPEN_SHP; - } - *retval = FALSE; - - ErrorMessage(_lastErrorCode); - } - else - { - _writing = true; - - // ------------------------------------------------- - // Writing the files - // ------------------------------------------------- - WriteShp(_shpfile, cBack); - WriteShx(_shxfile, cBack); - - if (_useQTree) - GenerateQTree(); - - // ------------------------------------------------- - // Reopen the updated files - // ------------------------------------------------- - _shpfile = _wfreopen(_shpfileName, L"rb+", _shpfile); - _shxfile = _wfreopen(_shxfileName, L"rb+", _shxfile); - - if (_shpfile == nullptr || _shxfile == nullptr) - { - if (_shxfile != nullptr) - { - fclose(_shxfile); - _shxfile = nullptr; - _lastErrorCode = tkCANT_OPEN_SHX; - } - if (_shpfile != nullptr) - { - fclose(_shpfile); - _shpfile = nullptr; - _lastErrorCode = tkCANT_OPEN_SHP; - } - *retval = FALSE; - - ErrorMessage(_lastErrorCode); - } - else - { - //Save the table file - _table->Save(cBack, retval); - - _sourceType = sstDiskBased; - - // saving projection in new format - VARIANT_BOOL vbretval, isEmpty; - _geoProjection->get_IsEmpty(&isEmpty); - if (!isEmpty) - { - const CComBSTR bstr(_prjfileName); - _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); - } - - *retval = VARIANT_TRUE; - } - } - - _writing = false; - return S_OK; -} - -// ************************************************************ -// Resource() -// ************************************************************ -STDMETHODIMP CShapefile::Resource(BSTR newShpPath, VARIANT_BOOL* retval) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - Close(retval); - Open(newShpPath, nullptr, retval); - return S_OK; -} -#pragma endregion - -// *********************************************************************** -// Clone() -// *********************************************************************** -// Creates new shapefile with the same type and fields as existing one -STDMETHODIMP CShapefile::Clone(IShapefile** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - ShapefileHelper::CloneCore(this, retVal, _shpfiletype); - return S_OK; -} - -// ************************************************************ -// get_Extents() -// ************************************************************ -STDMETHODIMP CShapefile::get_Extents(IExtents** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - IExtents* bBox = nullptr; - ComHelper::CreateExtents(&bBox); - - // Extents could change because of the moving of points of a single shape - // It's difficult to track such changes, so we still need to recalculate them - // here to enforce proper drawing; _fastMode mode - for those who want - // to call refresh extents theirselfs - if (!_fastMode) - { - VARIANT_BOOL vbretval; - this->RefreshExtents(&vbretval); - } - - bBox->SetBounds(_minX, _minY, _minZ, _maxX, _maxY, _maxZ); - bBox->SetMeasureBounds(_minM, _maxM); - *pVal = bBox; - - return S_OK; -} - -#pragma region AttributeTable -// **************************************************************** -// EditInsertField() -// **************************************************************** -STDMETHODIMP CShapefile::EditInsertField(IField* NewField, long* FieldIndex, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (cBack == nullptr && _globalCallback != nullptr) - cBack = _globalCallback; - - if (_table != nullptr) - { - _table->EditInsertField(NewField, FieldIndex, cBack, retval); - } - else - { - *retval = VARIANT_FALSE; - _lastErrorCode = tkFILE_NOT_OPEN; - ErrorMessage(_lastErrorCode, cBack); - return S_OK; - } - - if (*retval == VARIANT_FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - *retval = VARIANT_FALSE; - } - - return S_OK; -} - -// **************************************************************** -// EditDeleteField() -// **************************************************************** -STDMETHODIMP CShapefile::EditDeleteField(long FieldIndex, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if (_table != nullptr) - { - _table->EditDeleteField(FieldIndex, cBack, retval); - } - else - { - *retval = VARIANT_FALSE; - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - if (*retval == VARIANT_FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - *retval = VARIANT_FALSE; - } - - return S_OK; -} - -// **************************************************************** -// EditCellValue() -// **************************************************************** -STDMETHODIMP CShapefile::EditCellValue(long FieldIndex, long ShapeIndex, VARIANT NewVal, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_table != nullptr) - { - _table->EditCellValue(FieldIndex, ShapeIndex, NewVal, retval); - } - else - { - *retval = VARIANT_FALSE; - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - if (*retval == VARIANT_FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - } - - return S_OK; -} - -// **************************************************************** -// StartEditingTable() -// **************************************************************** -STDMETHODIMP CShapefile::StartEditingTable(ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_appendMode) - { - ErrorMessage(tkDBF_NO_EDIT_MODE_WHEN_APPENDING); - *retval = VARIANT_FALSE; - return S_OK; - } - - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if (_table != nullptr) - { - _table->StartEditingTable(cBack, retval); - } - else - { - *retval = VARIANT_FALSE; - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - if (*retval == VARIANT_FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - *retval = VARIANT_FALSE; - } - - return S_OK; -} - -// **************************************************************** -// StopEditingTable() -// **************************************************************** -STDMETHODIMP CShapefile::StopEditingTable(VARIANT_BOOL ApplyChanges, ICallback* cBack, VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_globalCallback == nullptr && cBack != nullptr) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if (_table != nullptr) - { - _table->StopEditingTable(ApplyChanges, cBack, retval); - } - else - { - *retval = VARIANT_FALSE; - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - if (*retval == FALSE) - { - _table->get_LastErrorCode(&_lastErrorCode); - *retval = VARIANT_FALSE; - } - - return S_OK; -} - -// ***************************************************************** -// get_Field() -// ***************************************************************** -STDMETHODIMP CShapefile::get_Field(long FieldIndex, IField** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_table != nullptr) - { - _table->get_Field(FieldIndex, pVal); - if (*pVal != nullptr) - { - // we need to report error from field class, and will use callback from this class for it - ICallback* cBack = nullptr; - if ((*pVal)->get_GlobalCallback(&cBack) == NULL && this->_globalCallback != nullptr) - (*pVal)->put_GlobalCallback(_globalCallback); - - if (cBack != nullptr) - cBack->Release(); // we put a reference in field class so must release it here - } - } - else - { - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - return S_OK; -} - -// ***************************************************************** -// get_FieldByName() -// ***************************************************************** -STDMETHODIMP CShapefile::get_FieldByName(BSTR Fieldname, IField** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - long max; - - CString strFieldname; - IField* testVal; - - _table->get_NumFields(&max); - if (_table != nullptr) - { - if (_tcslen(OLE2CA(Fieldname)) > 0) - { - strFieldname = OLE2A(Fieldname); - } - else - { - ErrorMessage(tkZERO_LENGTH_STRING); - } - - for (int fld = 0; fld < max; fld++) - { - _table->get_Field(fld, &testVal); - CComBSTR Testname; - testVal->get_Name(&Testname); - CString strTestname = OLE2A(Testname); - if (strTestname.CompareNoCase(strFieldname) == 0) - { - *pVal = testVal; - return S_OK; - } - testVal->Release(); - } - } - else - { - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - // we did not have a file error, but we also didn't match the name - pVal = nullptr; - return S_OK; -} - -// ***************************************************************** -// get_CellValue() -// ***************************************************************** -STDMETHODIMP CShapefile::get_CellValue(long FieldIndex, long ShapeIndex, VARIANT* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_table != nullptr) - { - _table->get_CellValue(FieldIndex, ShapeIndex, pVal); - } - else - { - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - return S_OK; -} - -// ***************************************************************** -// get_EditingTable() -// ***************************************************************** -STDMETHODIMP CShapefile::get_EditingTable(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_table != nullptr) - { - _table->get_EditingTable(pVal); - } - else - { - *pVal = VARIANT_FALSE; - ErrorMessage(tkFILE_NOT_OPEN); - return S_OK; - } - - return S_OK; -} - -// ************************************************************* -// get_Table() -// ************************************************************* -STDMETHODIMP CShapefile::get_Table(ITable** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retVal = _table; - if (_table) - { - _table->AddRef(); - } - return S_OK; -} -#pragma endregion - -#pragma region DrawingOptions - -// ************************************************************* -// get_ShapeRotation() -// ************************************************************* -STDMETHODIMP CShapefile::get_ShapeRotation(long ShapeIndex, double* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - *pVal = -1; - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - *pVal = _shapeData[ShapeIndex]->rotation; - return S_OK; -} - -STDMETHODIMP CShapefile::put_ShapeRotation(long ShapeIndex, double newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - _shapeData[ShapeIndex]->rotation = static_cast(newVal); - - return S_OK; -} - -// ************************************************************* -// get_ShapeVisible() -// ************************************************************* -STDMETHODIMP CShapefile::get_ShapeVisible(long ShapeIndex, VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = VARIANT_FALSE; - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - // this particular shape was not hidden explicitly or via visibility expression - if (!_shapeData[ShapeIndex]->hidden() && _shapeData[ShapeIndex]->isVisible()) - { - long ctIndex = -1; - get_ShapeCategory(ShapeIndex, &ctIndex); - if (ctIndex == -1) - { - // no category, check default options - _defaultDrawOpt->get_Visible(pVal); - } - else - { - // there is category, check whether it is visible - CComPtr ct = nullptr; - get_ShapeCategory3(ShapeIndex, &ct); - if (ct) - { - CComPtr options = nullptr; - ct->get_DrawingOptions(&options); - if (options) - { - options->get_Visible(pVal); - } - } - } - } - } - return S_OK; -} - -// ************************************************************* -// ShapeIsHidden() -// ************************************************************* -STDMETHODIMP CShapefile::get_ShapeIsHidden(LONG shapeIndex, VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) - { - *pVal = VARIANT_FALSE; - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - *pVal = _shapeData[shapeIndex]->hidden() ? VARIANT_TRUE : VARIANT_FALSE; - } - return S_OK; -} - -STDMETHODIMP CShapefile::put_ShapeIsHidden(LONG shapeIndex, VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - _shapeData[shapeIndex]->hidden(newVal != 0); - - return S_OK; -} - -// ************************************************************* -// get_ShapeModified() -// ************************************************************* -STDMETHODIMP CShapefile::get_ShapeModified(long ShapeIndex, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - *retVal = -1; - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - *retVal = _shapeData[ShapeIndex]->modified() ? VARIANT_TRUE : VARIANT_FALSE; - } - - return S_OK; -} - -STDMETHODIMP CShapefile::put_ShapeModified(long ShapeIndex, VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - _shapeData[ShapeIndex]->modified(newVal != 0); - } - - return S_OK; -} - - -// ************************************************************* -// get_ShapeCategory() -// ************************************************************* -STDMETHODIMP CShapefile::get_ShapeCategory(long ShapeIndex, long* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) //_numShapes) - { - *pVal = -1; - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - *pVal = _shapeData[ShapeIndex]->category; - return S_OK; -} - -STDMETHODIMP CShapefile::put_ShapeCategory(long ShapeIndex, long newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) //_numShapes ) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - _shapeData[ShapeIndex]->category = (int)newVal; - - return S_OK; -} - -// ************************************************************* -// get_ShapeCategory2() -// ************************************************************* -STDMETHODIMP CShapefile::put_ShapeCategory2(long ShapeIndex, BSTR categoryName) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - int index; - _categories->get_CategoryIndexByName(categoryName, &index); - if (index == -1) - { - ErrorMessage(tkCATEGORY_WASNT_FOUND); - } - else - { - _shapeData[ShapeIndex]->category = (int)index; - } - } - return S_OK; -} - -STDMETHODIMP CShapefile::get_ShapeCategory2(long ShapeIndex, BSTR* categoryName) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - const int index = _shapeData[ShapeIndex]->category; - long count; - _categories->get_Count(&count); - if (index >= 0 && index < count) - { - IShapefileCategory* ct; - _categories->get_Item(index, &ct); - ct->get_Name(categoryName); - ct->Release(); - return S_OK; - } - ErrorMessage(tkCATEGORY_WASNT_FOUND); - } - *categoryName = SysAllocString(L""); - return S_OK; -} - -// ************************************************************* -// put_ShapeCategory3() -// ************************************************************* -STDMETHODIMP CShapefile::put_ShapeCategory3(long ShapeIndex, IShapefileCategory* category) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - int index; - _categories->get_CategoryIndex(category, &index); - if (index == -1) - { - ErrorMessage(tkCATEGORY_WASNT_FOUND); - } - else - { - _shapeData[ShapeIndex]->category = (int)index; - } - } - return S_OK; -} - -STDMETHODIMP CShapefile::get_ShapeCategory3(long ShapeIndex, IShapefileCategory** category) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *category = nullptr; - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - const int index = _shapeData[ShapeIndex]->category; - long count; - _categories->get_Count(&count); - if (index >= 0 && index < count) - { - IShapefileCategory* ct; - _categories->get_Item(index, &ct); - *category = ct; // ref was added in the get_Item - } - else - { - ErrorMessage(tkCATEGORY_WASNT_FOUND); - } - } - return S_OK; -} - -// ******************************************************************* -// SelectionDrawingOptions() -// ******************************************************************* -// Returns and sets parameters used to draw selection for the shapefile. -STDMETHODIMP CShapefile::get_SelectionDrawingOptions(IShapeDrawingOptions** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _selectDrawOpt; - if (_selectDrawOpt) - _selectDrawOpt->AddRef(); - return S_OK; -} - -STDMETHODIMP CShapefile::put_SelectionDrawingOptions(IShapeDrawingOptions* newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (!newVal) - { - ErrorMessage(tkINVALID_PARAMETER_VALUE); - } - else - { - ComHelper::SetRef(newVal, (IDispatch**)&_selectDrawOpt, false); - } - return S_OK; -} - -// ******************************************************************* -// DeafultDrawingOptions() -// ******************************************************************* -// Returns and sets parameters used to draw shapefile by default. -STDMETHODIMP CShapefile::get_DefaultDrawingOptions(IShapeDrawingOptions** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _defaultDrawOpt; - if (_defaultDrawOpt) - _defaultDrawOpt->AddRef(); - return S_OK; -} - -STDMETHODIMP CShapefile::put_DefaultDrawingOptions(IShapeDrawingOptions* newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (!newVal) - { - ErrorMessage(tkINVALID_PARAMETER_VALUE); - } - else - { - ComHelper::SetRef(newVal, (IDispatch**)&_defaultDrawOpt); - } - return S_OK; -} - -// *********************************************************************** -// put_ReferenceToCategories -// *********************************************************************** -void CShapefile::put_ReferenceToCategories(bool bNullReference) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (_categories == nullptr) return; - auto* coCategories = dynamic_cast(_categories); - if (!bNullReference) - coCategories->put_ParentShapefile(this); - else - coCategories->put_ParentShapefile(nullptr); -}; - -// *********************************************************************** -// get/put_Categories -// *********************************************************************** -STDMETHODIMP CShapefile::get_Categories(IShapefileCategories** pVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _categories; - if (_categories != nullptr) - _categories->AddRef(); - return S_OK; -} - -STDMETHODIMP CShapefile::put_Categories(IShapefileCategories* newVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (ComHelper::SetRef((IDispatch*)newVal, (IDispatch**)&_categories, false)) - { - ((CShapefileCategories*)_categories)->put_ParentShapefile(this); - } - return S_OK; -} -#pragma endregion - -// ******************************************************************** -// get_SelectionColor -// ******************************************************************** -STDMETHODIMP CShapefile::get_SelectionColor(OLE_COLOR* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = _selectionColor; - return S_OK; -} - -STDMETHODIMP CShapefile::put_SelectionColor(OLE_COLOR newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _selectionColor = newVal; - return S_OK; -} - -// ******************************************************************** -// get_SelectionTransparency -// ******************************************************************** -STDMETHODIMP CShapefile::get_SelectionTransparency(BYTE* retval) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - *retval = _selectionTransparency; - return S_OK; -} - -STDMETHODIMP CShapefile::put_SelectionTransparency(BYTE newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (newVal > 255) newVal = 255; - _selectionTransparency = newVal; - return S_OK; -} - -// ******************************************************************** -// get_SelectionAppearance -// ******************************************************************** -STDMETHODIMP CShapefile::get_SelectionAppearance(tkSelectionAppearance* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = _selectionAppearance; - return S_OK; -} - -STDMETHODIMP CShapefile::put_SelectionAppearance(tkSelectionAppearance newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _selectionAppearance = newVal; - return S_OK; -} - -// ******************************************************************** -// get_PointCollisionMode -// ******************************************************************** -STDMETHODIMP CShapefile::get_CollisionMode(tkCollisionMode* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = _collisionMode; - return S_OK; -} - -STDMETHODIMP CShapefile::put_CollisionMode(tkCollisionMode newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _collisionMode = newVal; - return S_OK; -} - -#pragma region "Seialization" -// ******************************************************** -// Serialize() -// ******************************************************** -STDMETHODIMP CShapefile::Serialize(VARIANT_BOOL SaveSelection, BSTR* retVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - return Serialize2(SaveSelection, VARIANT_FALSE, retVal); -} - -STDMETHODIMP CShapefile::Serialize2(VARIANT_BOOL SaveSelection, VARIANT_BOOL SerializeCategories, BSTR* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - CPLXMLNode* psTree = this->SerializeCore(VARIANT_TRUE, "ShapefileClass", SerializeCategories != 0); - Utility::SerializeAndDestroyXmlTree(psTree, retVal); - return S_OK; -} - -// ******************************************************** -// SerializeCore() -// ******************************************************** -CPLXMLNode* CShapefile::SerializeCore(VARIANT_BOOL SaveSelection, CString ElementName, bool serializeCategories) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - CPLXMLNode* psTree = CPLCreateXMLNode(nullptr, CXT_Element, ElementName); - - if (psTree) - { - CString s = OLE2CA(_expression); - if (s != "") - Utility::CPLCreateXMLAttributeAndValue(psTree, "VisibilityExpression", s); - - - if (_useQTree != FALSE) - Utility::CPLCreateXMLAttributeAndValue(psTree, "UseQTree", CPLString().Printf("%d", (int)_useQTree)); - - if (_collisionMode != LocalList) - Utility::CPLCreateXMLAttributeAndValue(psTree, "CollisionMode", - CPLString().Printf("%d", (int)_collisionMode)); - - if (_selectionAppearance != saSelectionColor) - Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionAppearance", - CPLString().Printf("%d", (int)_selectionAppearance)); - - if (_selectionColor != RGB(255, 255, 0)) - Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionColor", - CPLString().Printf("%d", (int)_selectionColor)); - - if (_selectionTransparency != 180) - Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionTransparency", - CPLString().Printf("%d", (int)_selectionTransparency)); - - if (_minDrawingSize != 1) - Utility::CPLCreateXMLAttributeAndValue(psTree, "MinDrawingSize", CPLString().Printf("%d", _minDrawingSize)); - - // for in-memory shapefiles only - if (_sourceType == sstInMemory) - Utility::CPLCreateXMLAttributeAndValue(psTree, "ShpType", - CPLString().Printf("%d", (int)this->_shpfiletype)); - - s = OLE2CA(_sortField); - if (s != "") - Utility::CPLCreateXMLAttributeAndValue(psTree, "SortField", s); - - if (_sortAscending != VARIANT_FALSE) - Utility::CPLCreateXMLAttributeAndValue(psTree, "SortAscending", - CPLString().Printf("%d", (int)_sortAscending)); - - // drawing options - CPLXMLNode* node = ((CShapeDrawingOptions*)_defaultDrawOpt)->SerializeCore("DefaultDrawingOptions"); - if (node) - { - CPLAddXMLChild(psTree, node); - } - - if (_selectionAppearance == saDrawingOptions) - { - node = ((CShapeDrawingOptions*)_selectDrawOpt)->SerializeCore("SelectionDrawingOptions"); - if (node) - { - CPLAddXMLChild(psTree, node); - } - } - - // categories - node = ((CShapefileCategories*)_categories)->SerializeCore("ShapefileCategoriesClass"); - if (node) - { - CPLAddXMLChild(psTree, node); - } - - // labels - CPLXMLNode* psLabels = ((CLabels*)_labels)->SerializeCore("LabelsClass"); - if (psLabels) - { - CPLAddXMLChild(psTree, psLabels); - } - - // charts - CPLXMLNode* psCharts = ((CCharts*)_charts)->SerializeCore("ChartsClass"); - if (psCharts) - { - CPLAddXMLChild(psTree, psCharts); - } - - // ---------------------------------------------------- - // selection - // ---------------------------------------------------- - long numSelected; - this->get_NumSelected(&numSelected); - - if (numSelected > 0 && SaveSelection) - { - auto* selection = new char[_shapeData.size() + 1]; - selection[_shapeData.size()] = '\0'; - for (unsigned int i = 0; i < _shapeData.size(); i++) - { - selection[i] = _shapeData[i]->selected() ? '1' : '0'; - } - - CPLXMLNode* nodeSelection = CPLCreateXMLElementAndValue(psTree, "Selection", selection); - if (nodeSelection) - { - Utility::CPLCreateXMLAttributeAndValue(nodeSelection, "TotalCount", - CPLString().Printf("%d", _shapeData.size())); - Utility::CPLCreateXMLAttributeAndValue(nodeSelection, "SelectedCount", - CPLString().Printf("%d", numSelected)); - } - delete[] selection; - } - - // ---------------------------------------------------- - // serialization of category indices - // ---------------------------------------------------- - // Paul Meems TODO: This variable comes in as a parameter as well. - // Is this correct? - bool serializeCategories = false; - - for (auto& i : _shapeData) - { - if (i->category != -1) - { - serializeCategories = true; - } - } - - if (serializeCategories) - { - s = ""; - // doing it with CString is ugly of course, better to allocate a buffer - CString temp; - for (auto& i : _shapeData) - { - temp.Format("%d,", i->category); - s += temp; - } - - // when there are no indices assigned, write an empty node with Count = 0; - // to signal, that categories must not be applied automatically (behavior for older versions) - CPLXMLNode* nodeCats = CPLCreateXMLElementAndValue(psTree, "CategoryIndices", s.GetBuffer()); - if (nodeCats) - { - Utility::CPLCreateXMLAttributeAndValue(nodeCats, "Count", - CPLString().Printf( - "%d", serializeCategories ? _shapeData.size() : 0)); - } - } - - // ---------------------------------------------------- - // table - // ---------------------------------------------------- - if (_table) - { - CPLXMLNode* psTable = ((CTableClass*)_table)->SerializeCore("TableClass"); - if (psTable) - { - CPLAddXMLChild(psTree, psTable); - } - } - } - return psTree; -} - -// ******************************************************** -// Deserialize() -// ******************************************************** -STDMETHODIMP CShapefile::Deserialize(VARIANT_BOOL LoadSelection, BSTR newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - CString s = OLE2CA(newVal); - CPLXMLNode* node = CPLParseXMLString(s.GetString()); - if (node) - { - CPLXMLNode* nodeSf = CPLGetXMLNode(node, "=ShapefileClass"); - if (nodeSf) - { - this->DeserializeCore(VARIANT_TRUE, nodeSf); - } - CPLDestroyXMLNode(node); - } - return S_OK; -} - -// ******************************************************** -// DeserializeCore() -// ******************************************************** -bool CShapefile::DeserializeCore(VARIANT_BOOL LoadSelection, CPLXMLNode* node) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - if (!node) - return false; - - CString s = CPLGetXMLValue(node, "VisibilityExpression", nullptr); - SysFreeString(_expression); - _expression = A2BSTR(s); - - s = CPLGetXMLValue(node, "UseQTree", nullptr); - _useQTree = s != "" ? (BOOL)atoi(s.GetString()) : FALSE; - - s = CPLGetXMLValue(node, "CollisionMode", nullptr); - _collisionMode = s != "" ? (tkCollisionMode)atoi(s.GetString()) : LocalList; - - s = CPLGetXMLValue(node, "SelectionAppearance", nullptr); - _selectionAppearance = s != "" ? (tkSelectionAppearance)atoi(s.GetString()) : saSelectionColor; - - s = CPLGetXMLValue(node, "SelectionColor", nullptr); - _selectionColor = s != "" ? (OLE_COLOR)atoi(s.GetString()) : RGB(255, 255, 0); - - s = CPLGetXMLValue(node, "SelectionTransparency", nullptr); - _selectionTransparency = s != "" ? (unsigned char)atoi(s.GetString()) : 180; - - s = CPLGetXMLValue(node, "MinDrawingSize", nullptr); - _minDrawingSize = s != "" ? atoi(s.GetString()) : 1; - - s = CPLGetXMLValue(node, "SortField", nullptr); - const CComBSTR bstrSortField = A2W(s); - this->put_SortField(bstrSortField); - - s = CPLGetXMLValue(node, "SortAscending", nullptr); - const VARIANT_BOOL sortAsc = s != "" ? (VARIANT_BOOL)atoi(s.GetString()) : VARIANT_FALSE; - this->put_SortAscending(sortAsc); - - if (_sourceType == sstInMemory) - { - s = CPLGetXMLValue(node, "ShpType", nullptr); - if (s != "") - { - _shpfiletype = (ShpfileType)atoi(s.GetString()); - } - } - - // drawing options - CPLXMLNode* psChild = CPLGetXMLNode(node, "DefaultDrawingOptions"); - if (psChild) - { - ((CShapeDrawingOptions*)_defaultDrawOpt)->DeserializeCore(psChild); - } - - if (_selectionAppearance == saDrawingOptions) - { - psChild = CPLGetXMLNode(node, "SelectionDrawingOptions"); - if (psChild) - { - ((CShapeDrawingOptions*)_selectDrawOpt)->DeserializeCore(psChild); - } - } - - // Categories - psChild = CPLGetXMLNode(node, "ShapefileCategoriesClass"); - if (psChild) - { - ((CShapefileCategories*)_categories)->DeserializeCore(psChild, false); - } - - CPLXMLNode* nodeCats = CPLGetXMLNode(node, "CategoryIndices"); - bool needsApplyExpression = true; - if (nodeCats) - { - CString indices = CPLGetXMLValue(nodeCats, "=CategoryIndices", ""); - if (indices.GetLength() > 0) - { - s = CPLGetXMLValue(nodeCats, "Count", "0"); - const long savedCount = atoi(s); - int foundCount = 0; - char* buffer = indices.GetBuffer(); - for (int i = 0; i < indices.GetLength(); i++) - { - if (buffer[i] == ',') - { - foundCount++; - } - } - - if (foundCount == savedCount && foundCount == _shapeData.size()) - { - const int size = _shapeData.size(); - int pos = 0, count = 0; - CString ct = indices.Tokenize(",", pos); - while (ct.GetLength() != 0 && count < size) - { - _shapeData[count]->category = atoi(ct); - ct = indices.Tokenize(",", pos); - count++; - }; - bool needsApplyExpression = false; - } - } - } - - // If no indeces or invalid indeces, re-apply: - if (needsApplyExpression) - { - ((CShapefileCategories*)_categories)->ApplyExpressions(); - } - - // Labels - psChild = CPLGetXMLNode(node, "LabelsClass"); - if (psChild) - { - ((CLabels*)_labels)->DeserializeCore(psChild); - } - - // Charts - psChild = CPLGetXMLNode(node, "ChartsClass"); - if (psChild) - { - ((CCharts*)_charts)->DeserializeCore(psChild); - } - - // selection - CPLXMLNode* nodeSelection = CPLGetXMLNode(node, "Selection"); - if (nodeSelection && LoadSelection) - { - this->SelectNone(); - - s = CPLGetXMLValue(nodeSelection, "TotalCount", "0"); - const long count = atoi(s); - s = CPLGetXMLValue(nodeSelection, "=Selection", ""); - if (s.GetLength() == count && s.GetLength() == _shapeData.size()) - { - char* selection = s.GetBuffer(); - for (unsigned int i = 0; i < _shapeData.size(); i++) - { - if (selection[i] == '1') - { - _shapeData[i]->selected(true); - } - } - } - } - - - // table - if (_table) - { - psChild = CPLGetXMLNode(node, "TableClass"); - if (psChild) - { - ((CTableClass*)_table)->DeserializeCore(psChild); - } - } - return true; -} -#pragma endregion - - -#pragma region Projection -// ***************************************************************** -// get_Projection() -// ***************************************************************** -STDMETHODIMP CShapefile::get_Projection(BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _geoProjection->ExportToProj4(pVal); - return S_OK; -} - -// ***************************************************************** -// put_Projection() -// ***************************************************************** -STDMETHODIMP CShapefile::put_Projection(BSTR proj4Projection) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - VARIANT_BOOL vbretval; - _geoProjection->ImportFromProj4(proj4Projection, &vbretval); - if (vbretval) - { - const CComBSTR bstrFilename(_prjfileName); - _geoProjection->WriteToFileEx(bstrFilename, VARIANT_TRUE, &vbretval); - } - return S_OK; -} - -// ***************************************************************** -// get_GeoProjection() -// ***************************************************************** -STDMETHODIMP CShapefile::get_GeoProjection(IGeoProjection** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_geoProjection) - _geoProjection->AddRef(); - - *retVal = _geoProjection; - return S_OK; -} - -// ***************************************************************** -// put_GeoProjection() -// ***************************************************************** -STDMETHODIMP CShapefile::put_GeoProjection(IGeoProjection* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - ComHelper::SetRef((IDispatch*)pVal, (IDispatch**)&_geoProjection, false); - if (_prjfileName.GetLength() != 0) - { - VARIANT_BOOL vbretval; - const CComBSTR bstr(_prjfileName); - _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); - } - return S_OK; -} - -// **************************************************************** -// get_IsGeographicProjection -// **************************************************************** -STDMETHODIMP CShapefile::get_IsGeographicProjection(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = VARIANT_FALSE; - - if (_geoProjection) - _geoProjection->get_IsGeographic(pVal); - - return S_OK; -} - -// ***************************************************************** -// Reproject() -// ***************************************************************** -STDMETHODIMP CShapefile::Reproject(IGeoProjection* newProjection, LONG* reprojectedCount, IShapefile** retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - if (!this->ReprojectCore(newProjection, reprojectedCount, retVal, false)) - *retVal = nullptr; - return S_OK; -} - -// ***************************************************************** -// ReprojectInPlace() -// ***************************************************************** -STDMETHODIMP CShapefile::ReprojectInPlace(IGeoProjection* newProjection, LONG* reprojectedCount, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (!_isEditingShapes) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - *retVal = VARIANT_FALSE; - } - else - { - if (this->ReprojectCore(newProjection, reprojectedCount, nullptr, true)) - { - // spatial index must be deleted, as it became useful all the same - VARIANT_BOOL vb; - RemoveSpatialIndex(&vb); - - // update qtree - if (_useQTree) - GenerateQTree(); - - VARIANT_BOOL vbretval; - this->RefreshExtents(&vbretval); - *retVal = VARIANT_TRUE; - return S_OK; - } - *retVal = NULL; - } - return S_OK; -} - -// ***************************************************************** -// ReprojectCore() -// ***************************************************************** -bool CShapefile::ReprojectCore(IGeoProjection* newProjection, LONG* reprojectedCount, IShapefile** retVal, - bool reprojectInPlace) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // ------------------------------------------------------ - // Validation - // ------------------------------------------------------ - if (!newProjection) - { - ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); - return false; - } - - VARIANT_BOOL isEmpty1, isEmpty2; - newProjection->get_IsEmpty(&isEmpty1); - _geoProjection->get_IsEmpty(&isEmpty2); - if (isEmpty1 || isEmpty2) - { - ErrorMessage(tkPROJECTION_NOT_INITIALIZED); - return false; - } - - if (!ValidateInput(this, "Reproject/ReprojectInPlace", "this", VARIANT_FALSE)) - return false; - - m_globalSettings.gdalErrorMessage = ""; - OGRSpatialReference* projSource = ((CGeoProjection*)_geoProjection)->get_SpatialReference(); - OGRSpatialReference* projTarget = ((CGeoProjection*)newProjection)->get_SpatialReference(); - - OGRCoordinateTransformation* transf = OGRCreateCoordinateTransformation(projSource, projTarget); - if (!transf) - { - m_globalSettings.gdalErrorMessage = CPLGetLastErrorMsg(); - ErrorMessage(tkFAILED_TO_REPROJECT); - return false; - } - - // ------------------------------------------------------ - // Creating output - // ------------------------------------------------------ - if (!reprojectInPlace) - this->Clone(retVal); - - // ------------------------------------------------------ - // Processing - // ------------------------------------------------------ - CComVariant var; - const long numShapes = _shapeData.size(); - long newIndex = 0; - - long numFields, percent = 0; - this->get_NumFields(&numFields); - - VARIANT_BOOL vb = VARIANT_FALSE; - *reprojectedCount = 0; - - for (long i = 0; i < numShapes; i++) - { - CallbackHelper::Progress(_globalCallback, i, numShapes, "Reprojecting...", _key, percent); - - IShape* shp = nullptr; - this->GetValidatedShape(i, &shp); - if (!shp) continue; - - if (!reprojectInPlace) - { - IShape* shpNew = nullptr; - shp->Clone(&shpNew); - shp->Release(); - shp = shpNew; - } - - if (shp) - { - long numPoints; - shp->get_NumPoints(&numPoints); - - if (numPoints > 0) - { - auto* x = new double[numPoints]; - auto* y = new double[numPoints]; - - // extracting coordinates - for (long j = 0; j < numPoints; j++) - { - shp->get_XY(j, x + j, y + j, &vb); - } - - // will work faster after embedding to the CShape class - const BOOL res = transf->Transform(numPoints, x, y); - if (!res) - { - // save error message and continue - if (m_globalSettings.gdalErrorMessage == "") - m_globalSettings.gdalErrorMessage = CPLGetLastErrorMsg(); - } - else - { - // saving updated coordinates - for (long j = 0; j < numPoints; j++) - { - shp->put_XY(j, x[j], y[j], &vb); - } - - if (!reprojectInPlace) - { - // get next available index - (*retVal)->get_NumShapes(&newIndex); - // insert Shape into target at new index - (*retVal)->EditInsertShape(shp, &newIndex, &vb); - - // copy attributes - for (long j = 0; j < numFields; j++) - { - // get cell value at source index i - this->get_CellValue(j, i, &var); - // set cell value into target at new index - (*retVal)->EditCellValue(j, newIndex, var, &vb); - } - } - // - (*reprojectedCount)++; - } - delete[] x; - delete[] y; - } - shp->Release(); - } - } - - if (transf) - { - OGRCoordinateTransformation::DestroyCT(transf); - transf = nullptr; - } - - // function result will be based on successful projection setting - vb = VARIANT_FALSE; - // if at least some rows were reprojected... - if (*reprojectedCount > 0) - { - // setting new projection - if (reprojectInPlace) - { - // vb result will be used to determine overall success - _geoProjection->CopyFrom(newProjection, &vb); - } - else - { - IGeoProjection* proj = nullptr; - (*retVal)->get_GeoProjection(&proj); - if (proj) - { - // vb result will be used to determine overall success - proj->CopyFrom(newProjection, &vb); - proj->Release(); - } - } - } - - // inserted shapes were marked as modified, correct this - if (reprojectInPlace) - ShapefileHelper::ClearShapefileModifiedFlag(this); - else - ShapefileHelper::ClearShapefileModifiedFlag(*retVal); - - // -------------------------------------- - // Output validation - // -------------------------------------- - CallbackHelper::ProgressCompleted(_globalCallback, _key); - - if (!reprojectInPlace) - { - this->ValidateOutput(retVal, "Reproject/ReprojectInPlace", "Shapefile", false); - } - else - { - this->ValidateOutput(this, "Reproject/ReprojectInPlace", "Shapefile", false); - } - - // it's critical to set correct projection, so false will be returned if it wasn't done - return vb != 0; -} -#pragma endregion - -// ***************************************************************** -// FixUpShapes() -// ***************************************************************** -STDMETHODIMP CShapefile::FixUpShapes(IShapefile** retVal, VARIANT_BOOL* fixed) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - // MWGIS-90: default to all shapes: - FixUpShapes2(VARIANT_FALSE, retVal, fixed); - - return S_OK; -} - -// ********************************************************* -// FixUpShapes2() -// ********************************************************* -STDMETHODIMP CShapefile::FixUpShapes2(VARIANT_BOOL SelectedOnly, IShapefile** result, VARIANT_BOOL* fixed) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *fixed = VARIANT_FALSE; - - if (*result == nullptr) - { - Clone(result); - } - - *fixed = FixupShapesCore(SelectedOnly, *result); - - return S_OK; -} - -// ********************************************************* -// FixupShapesCore() -// ********************************************************* -VARIANT_BOOL CShapefile::FixupShapesCore(VARIANT_BOOL selectedOnly, IShapefile* result) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!result) return VARIANT_FALSE; - - tkUnitsOfMeasure units; - _geoProjection->get_LinearUnits(&units); - - long numFields; - this->get_NumFields(&numFields); - - long percent = 0; - const int numShapes = _shapeData.size(); - // VARIANT_BOOL fixed = VARIANT_TRUE; - - for (int i = 0; i < numShapes; i++) - { - CallbackHelper::Progress(_globalCallback, i, numShapes, "Fixing...", _key, percent); - - if (!ShapeAvailable(i, selectedOnly)) - continue; - - IShape* shp = nullptr; - get_Shape(i, &shp); - if (!shp) - { - continue; - } - - IShape* shpNew = nullptr; - shp->FixUp2(units, &shpNew); - shp->Release(); - - // failed to fix the shape? skip it. - if (!shpNew) - { - CString s; - s.Format("Failed to fix shape: %d", i); - CallbackHelper::ErrorMsg("Shapefile", nullptr, "", s); - continue; - } - - long shapeIndex = 0; - result->get_NumShapes(&shapeIndex); - - VARIANT_BOOL vbretval = VARIANT_FALSE; - result->EditInsertShape(shpNew, &shapeIndex, &vbretval); - shpNew->Release(); - - if (vbretval) - { - // TODO: extract, it's definitely used in other methods as well - CComVariant var; - for (int iFld = 0; iFld < numFields; iFld++) - { - get_CellValue(iFld, i, &var); - result->EditCellValue(iFld, shapeIndex, var, &vbretval); - } - } - } - - CallbackHelper::ProgressCompleted(_globalCallback, _key); - - return VARIANT_TRUE; -} - -// ********************************************************* -// GetRelatedShapes() -// ********************************************************* -STDMETHODIMP CShapefile::GetRelatedShapes(long referenceIndex, tkSpatialRelation relation, VARIANT* resultArray, - VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - if (referenceIndex < 0 || referenceIndex > (long)_shapeData.size()) - { - this->ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - return S_OK; - } - - IShape* shp = nullptr; - this->get_Shape(referenceIndex, &shp); - if (shp) - { - this->GetRelatedShapeCore(shp, referenceIndex, relation, resultArray, retval); - shp->Release(); - } - return S_OK; -} - -// ********************************************************* -// GetRelatedShapes2() -// ********************************************************* -STDMETHODIMP CShapefile::GetRelatedShapes2(IShape* referenceShape, tkSpatialRelation relation, VARIANT* resultArray, - VARIANT_BOOL* retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - if (!referenceShape) - { - this->ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); - return S_OK; - } - - this->GetRelatedShapeCore(referenceShape, -1, relation, resultArray, retval); - return S_OK; -} - -// ********************************************************* -// GetRelatedShapeCore() -// ********************************************************* -void CShapefile::GetRelatedShapeCore(IShape* referenceShape, long referenceIndex, tkSpatialRelation relation, - VARIANT* resultArray, VARIANT_BOOL* retval) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (relation == srDisjoint) - { - // TODO: implement - ErrorMessage(tkMETHOD_NOT_IMPLEMENTED); - return; - } - - // rather than generate geometries for all shapes, - // only generate for those within qtree extent (see below) - //this->ReadGeosGeometries(VARIANT_FALSE); - - // turns on the quad tree - VARIANT_BOOL useQTree = VARIANT_FALSE; - this->get_UseQTree(&useQTree); - if (!useQTree) this->put_UseQTree(VARIANT_TRUE); - - double xMin, xMax, yMin, yMax; - if (((CShape*)referenceShape)->get_ExtentsXY(xMin, yMin, xMax, yMax)) - { - const QTreeExtent query(xMin, xMax, yMax, yMin); - std::vector shapes = this->_qtree->GetNodes(query); - std::vector arr; - - // generate GEOS geometries only for shapes within qtree extent - for (size_t i = 0; i < shapes.size(); i++) - // minimize work by 'select'ing necessary shapes - this->put_ShapeSelected(shapes[i], VARIANT_TRUE); - // now generate only for 'select'ed shapes - this->ReadGeosGeometries(VARIANT_TRUE); - // don't leave shapes 'select'ed - for (size_t i = 0; i < shapes.size(); i++) - this->put_ShapeSelected(shapes[i], VARIANT_FALSE); - - GEOSGeom geomBase; - if (referenceIndex > 0) - { - geomBase = _shapeData[referenceIndex]->geosGeom; - } - else - { - geomBase = GeosConverter::ShapeToGeom(referenceShape); - } - - if (geomBase) - { - for (size_t i = 0; i < shapes.size(); i++) - { - if (i == referenceIndex) - continue; // it doesn't make sense to compare the shape with itself - - // ReSharper disable once CppLocalVariableMayBeConst - GEOSGeom geom = _shapeData[shapes[i]]->geosGeom; - if (geom != nullptr) - { - char res = 0; - switch (relation) - { - case srContains: res = GeosHelper::Contains(geomBase, geom); - break; - case srCrosses: res = GeosHelper::Crosses(geomBase, geom); - break; - case srEquals: res = GeosHelper::Equals(geomBase, geom); - break; - case srIntersects: res = GeosHelper::Intersects(geomBase, geom); - break; - case srOverlaps: res = GeosHelper::Overlaps(geomBase, geom); - break; - case srTouches: res = GeosHelper::Touches(geomBase, geom); - break; - case srWithin: res = GeosHelper::Within(geomBase, geom); - break; - case srDisjoint: break; - default: ; - } - if (res) - { - arr.push_back(shapes[i]); - } - } - } - - if (referenceIndex == -1) - GeosHelper::DestroyGeometry(geomBase); - // the geometry was created in this function so it must be destroyed - } - - *retval = Templates::Vector2SafeArray(&arr, VT_I4, resultArray); - } - - // Don't clear the list here as function may be called in a loop - //this->ClearCachedGeometries(); -} - -// *************************************************** -// get_Identifiable -// *************************************************** -STDMETHODIMP CShapefile::get_Identifiable(VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retVal = _hotTracking; - return S_OK; -} - -STDMETHODIMP CShapefile::put_Identifiable(VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _hotTracking = newVal; - return S_OK; -} - -// ***************************************************************** -// EditAddField() -// ***************************************************************** -STDMETHODIMP CShapefile::EditAddField(BSTR name, FieldType type, int precision, int width, long* fieldIndex) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (!this->_table) - { - this->ErrorMessage(tkDBF_FILE_DOES_NOT_EXIST); - } - else - { - _table->EditAddField(name, type, precision, width, fieldIndex); - } - return S_OK; -} - -// ***************************************************************** -// EditAddShape() -// ***************************************************************** -STDMETHODIMP CShapefile::EditAddShape(IShape* shape, long* shapeIndex) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - VARIANT_BOOL retval; - *shapeIndex = _shapeData.size(); - - EditInsertShape(shape, shapeIndex, &retval); - - if (retval == VARIANT_FALSE) - *shapeIndex = -1; - - return S_OK; -} - -// ***************************************************************** -// GetClosestVertex() -// ***************************************************************** -STDMETHODIMP CShapefile::GetClosestVertex(double x, double y, double maxDistance, - long* shapeIndex, long* pointIndex, double* distance, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *retVal = VARIANT_FALSE; - *shapeIndex = -1; - *pointIndex = -1; - - bool result = false; - if (maxDistance <= 0.0) - { - // search through all shapefile - std::vector ids; - for (size_t i = 0; i < _shapeData.size(); i++) - { - ids.push_back(i); - } - result = ShapefileHelper::GetClosestPoint(this, x, y, maxDistance, ids, shapeIndex, pointIndex, *distance); - } - else - { - std::vector ids; - Extent box(x - maxDistance, x + maxDistance, y - maxDistance, y + maxDistance); - if (this->SelectShapesCore(box, 0.0, SelectMode::INTERSECTION, ids, false)) - { - result = ShapefileHelper::GetClosestPoint(this, x, y, maxDistance, ids, shapeIndex, pointIndex, *distance); - } - } - *retVal = result ? VARIANT_TRUE : VARIANT_FALSE; - return S_OK; -} - -// ***************************************************************** -// GetClosestSnapPosition() -// ***************************************************************** -STDMETHODIMP CShapefile::GetClosestSnapPosition(double x, double y, double maxDistance, - long* shapeIndex, double* fx, double* fy, double* distance, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *retVal = VARIANT_FALSE; - *shapeIndex = -1; - - bool result = false; - if (maxDistance <= 0.0) - { - // search through all shapefile - std::vector ids; - for (size_t i = 0; i < _shapeData.size(); i++) - { - ids.push_back(i); - } - result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance); - } - else - { - std::vector ids; - Extent box(x - maxDistance, x + maxDistance, y - maxDistance, y + maxDistance); - if (this->SelectShapesCore(box, 0.0, SelectMode::INTERSECTION, ids, false)) - { - result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance); - } - } - *retVal = result ? VARIANT_TRUE : VARIANT_FALSE; - return S_OK; -} - -// ***************************************************************** -// HasInvalidShapes() -// ***************************************************************** -STDMETHODIMP CShapefile::HasInvalidShapes(VARIANT_BOOL* result) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *result = VARIANT_FALSE; - const int numShapes = _shapeData.size(); - - for (int i = 0; i < numShapes; i++) - { - IShape* shp = nullptr; - this->get_Shape(i, &shp); - - if (!shp) - { - *result = VARIANT_TRUE; - break; - } - - VARIANT_BOOL retval = VARIANT_TRUE; - shp->get_IsValid(&retval); - shp->Release(); - if (retval == VARIANT_FALSE) - { - *result = VARIANT_TRUE; - break; - } - } - return S_OK; -} - -// ***************************************************************** -// get_UndoList() -// ***************************************************************** -STDMETHODIMP CShapefile::get_UndoList(IUndoList** pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - if (_undoList) - _undoList->AddRef(); - *pVal = _undoList; - return S_OK; -} - -// ***************************************************************** -// Snappable() -// ***************************************************************** -STDMETHODIMP CShapefile::get_Snappable(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _snappable; - return S_OK; -} - -STDMETHODIMP CShapefile::put_Snappable(VARIANT_BOOL newVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - _snappable = newVal; - return S_OK; -} - -// ***************************************************************** -// ShapefileType2D() -// ***************************************************************** -STDMETHODIMP CShapefile::get_ShapefileType2D(ShpfileType* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = ShapeUtility::Convert2D(_shpfiletype); - return S_OK; -} - -// ***************************************************************** -// FieldIndexByName() -// ***************************************************************** -STDMETHODIMP CShapefile::get_FieldIndexByName(BSTR FieldName, LONG* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _table->get_FieldIndexByName(FieldName, pVal); - return S_OK; -} - -// *************************************************** -// get_Selectable -// *************************************************** -STDMETHODIMP CShapefile::get_Selectable(VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retVal = _selectable; - return S_OK; -} - -STDMETHODIMP CShapefile::put_Selectable(VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - _selectable = newVal; - return S_OK; -} - -// ***************************************************************** -// Move() -// ***************************************************************** -STDMETHODIMP CShapefile::Move(DOUBLE xProjOffset, DOUBLE yProjOffset, VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retVal = VARIANT_FALSE; - if (_sourceType != sstInMemory) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - return S_OK; - } - long numShapes; - get_NumShapes(&numShapes); - for (long i = 0; i < numShapes; i++) - { - CComPtr shp = nullptr; - get_Shape(i, &shp); - if (shp) - { - shp->Move(xProjOffset, yProjOffset); - } - } - *retVal = VARIANT_TRUE; - return S_OK; -} - -// ***************************************************************** -// get_ShapeRendered() -// ***************************************************************** -STDMETHODIMP CShapefile::get_ShapeRendered(LONG ShapeIndex, VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = VARIANT_FALSE; - if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - *pVal = _shapeData[ShapeIndex]->wasRendered() ? VARIANT_TRUE : VARIANT_FALSE; - } - return S_OK; -} - -// ***************************************************************** -// MarkUndrawn() -// ***************************************************************** -void CShapefile::MarkUndrawn() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - for (auto& i : _shapeData) - { - i->wasRendered(false); - } -} - -// ************************************************************* -// SortField() -// ************************************************************* -STDMETHODIMP CShapefile::get_SortField(BSTR* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - USES_CONVERSION; - *pVal = OLE2BSTR(_sortField); - - return S_OK; -} - -STDMETHODIMP CShapefile::put_SortField(BSTR newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - SysFreeString(_sortField); - USES_CONVERSION; - _sortField = OLE2BSTR(newVal); - - _sortingChanged = true; - - if (_labels) - { - _labels->UpdateSizeField(); - } - - return S_OK; -} - -// ************************************************************* -// SortAscending() -// ************************************************************* -STDMETHODIMP CShapefile::get_SortAscending(VARIANT_BOOL* pVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = _sortAscending; - - return S_OK; -} - -STDMETHODIMP CShapefile::put_SortAscending(VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - _sortAscending = newVal; - _sortingChanged = true; - - return S_OK; -} - -// ************************************************************* -// UpdateSorting() -// ************************************************************* -STDMETHODIMP CShapefile::UpdateSortField() -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - // this will trigger rereading of the table on next redraw - _sortingChanged = true; - - return S_OK; -} - -// ************************************************************* -// GetSorting() -// ************************************************************* -bool CShapefile::GetSorting(vector** indices) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - *indices = nullptr; - - if (!_sortingChanged) - { - *indices = &_sorting; - return true; - } - - long fieldIndex; - get_FieldIndexByName(_sortField, &fieldIndex); - - if (fieldIndex == -1) - { - return false; - } - - if (!_table) - { - return false; - } - - _sortingChanged = false; - - if (((CTableClass*)_table)->GetSorting(fieldIndex, _sorting)) - { - if (!_sortAscending) - { - std::reverse(_sorting.begin(), _sorting.end()); - } - - *indices = &_sorting; - return true; - } - CallbackHelper::ErrorMsg("Failed to sort labels"); - - return false; -} +//******************************************************************************************************** +//File name: Shapefile.cpp +//Description: Implementation of the CShapefile +//******************************************************************************************************** +//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); +//you may not use this file except in compliance with the License. You may obtain a copy of the License at +//http://www.mozilla.org/MPL/ +//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF +//ANY KIND, either express or implied. See the License for the specific language governing rights and +//limitations under the License. +// +//The Original Code is MapWindow Open Source. +// +//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by +//Utah State University and the Idaho National Engineering and Environmental Lab that were released as +//public domain in March 2004. +//******************************************************************************************************** +// +//Contributor(s): (Open source contributors should list themselves and their modifications here). +// ------------------------------------------------------------------------------------------------------- +// Paul Meems August 2018: Modernized the code as suggested by CLang and ReSharper + +#include "StdAfx.h" +#include +#include "Shapefile.h" +#include "Labels.h" +#include "Charts.h" +#include "GeoProjection.h" +#include "Templates.h" +#include +#include "ShapefileCategories.h" +#include "Shape.h" +#include "GeosConverter.h" +#include "ShapefileHelper.h" +#include "LabelsHelper.h" +#include "ShapeStyleHelper.h" +#include "TableClass.h" + +#ifdef _DEBUG + #define new DEBUG_NEW + #undef THIS_FILE + static char THIS_FILE[] = __FILE__; +#endif + +CShapefile::CShapefile() +{ + _pUnkMarshaler = nullptr; + + _sortingChanged = true; + _sortAscending = VARIANT_FALSE; + _sortField = SysAllocString(L""); + + _appendStartShapeCount = -1; + _appendMode = VARIANT_FALSE; + _snappable = VARIANT_TRUE; + _interactiveEditing = VARIANT_FALSE; + _hotTracking = VARIANT_TRUE; + _selectable = VARIANT_FALSE; + _geosGeometriesRead = false; + _stopExecution = nullptr; + + _selectionTransparency = 180; + _selectionAppearance = saSelectionColor; + _selectionColor = RGB(255, 255, 0); + _collisionMode = tkCollisionMode::LocalList; + + _geometryEngine = m_globalSettings.geometryEngine; + + _sourceType = sstUninitialized; + + _writing = false; + _reading = false; + + _isEditingShapes = FALSE; + _fastMode = m_globalSettings.shapefileFastMode ? TRUE : FALSE; + _minDrawingSize = 1; + _volatile = false; + + _useSpatialIndex = TRUE; + _hasSpatialIndex = FALSE; + _spatialIndexLoaded = FALSE; + _spatialIndexMaxAreaPercent = 0.5; + _spatialIndexNodeCapacity = 100; + + //Neio 20090721 + _useQTree = FALSE; + _cacheExtents = FALSE; + _qtree = nullptr; + _tempTree = nullptr; + + _shpfile = nullptr; + _shxfile = nullptr; + + _shpfiletype = SHP_NULLSHAPE; + _nextShapeHandle = 0; + + _minX = 0.0; + _minY = 0.0; + _minZ = 0.0; + _maxX = 0.0; + _maxY = 0.0; + _maxZ = 0.0; + _minM = 0.0; + _maxM = 0.0; + + _key = SysAllocString(L""); + _expression = SysAllocString(L""); + _globalCallback = nullptr; + _lastErrorCode = tkNO_ERROR; + _table = nullptr; + + // creation of children classes + _selectDrawOpt = nullptr; + _defaultDrawOpt = nullptr; + _labels = nullptr; + _categories = nullptr; + _charts = nullptr; + _geoProjection = nullptr; + + ComHelper::CreateInstance(idShapeValidationInfo, (IDispatch**)&_inputValidation); + ComHelper::CreateInstance(idShapeValidationInfo, (IDispatch**)&_outputValidation); + + CoCreateInstance(CLSID_ShapeDrawingOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IShapeDrawingOptions, + (void**)&_selectDrawOpt); + CoCreateInstance(CLSID_ShapeDrawingOptions, nullptr, CLSCTX_INPROC_SERVER, IID_IShapeDrawingOptions, + (void**)&_defaultDrawOpt); + CoCreateInstance(CLSID_ShapefileCategories, nullptr, CLSCTX_INPROC_SERVER, IID_IShapefileCategories, + (void**)&_categories); + CoCreateInstance(CLSID_Labels, nullptr, CLSCTX_INPROC_SERVER, IID_ILabels, (void**)&_labels); + CoCreateInstance(CLSID_Charts, nullptr, CLSCTX_INPROC_SERVER, IID_ICharts, (void**)&_charts); + CoCreateInstance(CLSID_GeoProjection, nullptr, CLSCTX_INPROC_SERVER, IID_IGeoProjection, (void**)&_geoProjection); + + this->put_ReferenceToLabels(); + this->put_ReferenceToCategories(); + this->put_ReferenceToCharts(); + + ComHelper::CreateInstance(idUndoList, (IDispatch**)&_undoList); + + gReferenceCounter.AddRef(tkInterface::idShapefile); +} + +CShapefile::~CShapefile() +{ + VARIANT_BOOL vbretval; + this->CShapefile::Close(&vbretval); + + SysFreeString(_key); + SysFreeString(_expression); + SysFreeString(_sortField); + + if (_selectDrawOpt != nullptr) + _selectDrawOpt->Release(); + + if (_defaultDrawOpt != nullptr) + _defaultDrawOpt->Release(); + + if (_labels != nullptr) + { + put_ReferenceToLabels(true); // labels class maybe referenced by client and won't be deleted as a result + _labels->Release(); // therefore we must clear the reference to the parent as it will be invalid + } + + if (_categories != nullptr) + { + put_ReferenceToCategories(true); + _categories->Release(); + } + + if (_charts != nullptr) + { + put_ReferenceToCharts(true); + _charts->Release(); + } + + if (_stopExecution) + _stopExecution->Release(); + + if (_geoProjection) + _geoProjection->Release(); + + if (_undoList) + { + _undoList->Release(); + } + gReferenceCounter.Release(tkInterface::idShapefile); +} + +std::vector* CShapefile::get_ShapeVector() +{ + return &_shapeData; +} + +IShapeWrapper* CShapefile::get_ShapeWrapper(int ShapeIndex) +{ + return ((CShape*)_shapeData[ShapeIndex]->shape)->get_ShapeWrapper(); +} + +IShapeData* CShapefile::get_ShapeRenderingData(int ShapeIndex) +{ + return _shapeData[ShapeIndex]->get_RenderingData(); +} + +void CShapefile::put_ShapeRenderingData(int ShapeIndex, CShapeData* data) +{ + return _shapeData[ShapeIndex]->put_RenderingData(data); +} + +void CShapefile::SetValidationInfo(IShapeValidationInfo* info, tkShapeValidationType validationType) +{ + ComHelper::SetRef(info, + (IDispatch**)&(validationType == svtInput ? _inputValidation : _outputValidation), true); +} + +#pragma region Properties + +// ************************************************************ +// get_EditingShapes() +// ************************************************************ +STDMETHODIMP CShapefile::get_EditingShapes(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *pVal = _isEditingShapes ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; +} + +// ************************************************************ +// get_LastErrorCode() +// ************************************************************ +STDMETHODIMP CShapefile::get_LastErrorCode(long* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *pVal = _lastErrorCode; + _lastErrorCode = tkNO_ERROR; + return S_OK; +} + +// ************************************************************ +// get_CdlgFilter() +// ************************************************************ +STDMETHODIMP CShapefile::get_CdlgFilter(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + *pVal = A2BSTR("ESRI Shapefiles (*.shp)|*.shp"); + return S_OK; +} + +// ************************************************************ +// LastInputValidation +// ************************************************************ +STDMETHODIMP CShapefile::get_LastInputValidation(IShapeValidationInfo** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_inputValidation) + _inputValidation->AddRef(); + *retVal = _inputValidation; + return S_OK; +} + +// ************************************************************ +// LastOutputValidation +// ************************************************************ +STDMETHODIMP CShapefile::get_LastOutputValidation(IShapeValidationInfo** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_outputValidation) + _outputValidation->AddRef(); + *retVal = _outputValidation; + return S_OK; +} + +// ************************************************************ +// get/put_GlobalCallback() +// ************************************************************ +STDMETHODIMP CShapefile::get_GlobalCallback(ICallback** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + *pVal = _globalCallback; + if (_globalCallback != nullptr) + _globalCallback->AddRef(); + return S_OK; +} + +STDMETHODIMP CShapefile::put_GlobalCallback(ICallback* newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + ComHelper::SetRef(newVal, (IDispatch**)&_globalCallback); + if (_table != nullptr) + _table->put_GlobalCallback(newVal); + + return S_OK; +} + +// ************************************************************ +// StopExecution +// ************************************************************ +STDMETHODIMP CShapefile::put_StopExecution(IStopExecution* stopper) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + ComHelper::SetRef((IDispatch*)stopper, (IDispatch**)&_stopExecution, true); + return S_OK; +} + +// ************************************************************ +// get/put_Key() +// ************************************************************ +STDMETHODIMP CShapefile::get_Key(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + *pVal = OLE2BSTR(_key); + return S_OK; +} + +STDMETHODIMP CShapefile::put_Key(BSTR newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + SysFreeString(_key); + _key = OLE2BSTR(newVal); + return S_OK; +} + +// ************************************************************ +// get/put_VisibilityExpression +// ************************************************************ +STDMETHODIMP CShapefile::get_VisibilityExpression(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + *pVal = OLE2BSTR(_expression); + return S_OK; +} + +STDMETHODIMP CShapefile::put_VisibilityExpression(BSTR newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + SysFreeString(_expression); + _expression = OLE2BSTR(newVal); + return S_OK; +} + +// ************************************************************ +// get/put_Volatile +// ************************************************************ +STDMETHODIMP CShapefile::get_Volatile(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_interactiveEditing) + { + *pVal = VARIANT_TRUE; + } + else + { + *pVal = _volatile ? VARIANT_TRUE : VARIANT_FALSE; + } + return S_OK; +} + +STDMETHODIMP CShapefile::put_Volatile(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + _volatile = newVal == VARIANT_TRUE; + return S_OK; +} + +// ***************************************************************** +// get_NumShapes() +// ***************************************************************** +STDMETHODIMP CShapefile::get_NumShapes(long* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *pVal = _shapeData.size(); //_numShapes; + return S_OK; +} + +// ************************************************************** +// get_NumFields() +// ************************************************************** +STDMETHODIMP CShapefile::get_NumFields(long* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_table != nullptr) + _table->get_NumFields(pVal); + else + { + ErrorMessage(tkFILE_NOT_OPEN); + *pVal = 0; + } + return S_OK; +} + +// ************************************************************ +// get_ShapefileType() +// ************************************************************ +STDMETHODIMP CShapefile::get_ShapefileType(ShpfileType* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *pVal = _shpfiletype; + return S_OK; +} + +// ***************************************************************** +// get_ErrorMsg() +// ***************************************************************** +STDMETHODIMP CShapefile::get_ErrorMsg(long ErrorCode, BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + *pVal = A2BSTR(ErrorMsg(ErrorCode)); + return S_OK; +} + +// ***************************************************************** +// get_FileHandle() +// ***************************************************************** +STDMETHODIMP CShapefile::get_FileHandle(long* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_shpfile != nullptr) + { + const int handle = _fileno(_shpfile); + *pVal = _dup(handle); + } + else + *pVal = -1; + + return S_OK; +} + +// ************************************************************** +// get_Filename() +// ************************************************************** +STDMETHODIMP CShapefile::get_Filename(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + *pVal = W2BSTR(_shpfileName); + + return S_OK; +} + +// ************************************************************** +// ErrorMessage() +// ************************************************************** +void CShapefile::ErrorMessage(long ErrorCode) +{ + _lastErrorCode = ErrorCode; + CallbackHelper::ErrorMsg("Shapefile", _globalCallback, _key, ErrorMsg(_lastErrorCode)); +} + +void CShapefile::ErrorMessage(long ErrorCode, ICallback* cBack) +{ + _lastErrorCode = ErrorCode; + CallbackHelper::ErrorMsg("Shapefile", _globalCallback, _key, ErrorMsg(_lastErrorCode)); + if (cBack != _globalCallback) + CallbackHelper::ErrorMsg("Shapefile", cBack, _key, ErrorMsg(_lastErrorCode)); +} + +// ************************************************************ +// get_MinDrawingSize() +// ************************************************************ +STDMETHODIMP CShapefile::get_MinDrawingSize(LONG* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _minDrawingSize; + return S_OK; +} + +STDMETHODIMP CShapefile::put_MinDrawingSize(LONG newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _minDrawingSize = newVal; + return S_OK; +} + +// ************************************************************ +// get_SourceType() +// ************************************************************ +STDMETHODIMP CShapefile::get_SourceType(tkShapefileSourceType* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _sourceType; + return S_OK; +} + +#pragma endregion + +#pragma region CreateAndOpen + + +// ************************************************************ +// LoadDataFrom() +// ************************************************************ +// Loads shape and DBF data from disk file into in-memory mode +STDMETHODIMP CShapefile::LoadDataFrom(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + USES_CONVERSION; + *retval = VARIANT_FALSE; + if (_sourceType != sstInMemory) + { + ErrorMessage(tkINMEMORY_SHAPEFILE_EXPECTED); + return S_OK; + } + + if (OpenCore(OLE2CA(ShapefileName), cBack)) + { + // loading data in-memory + VARIANT_BOOL vb; + _isEditingShapes = false; + StartEditingShapes(VARIANT_TRUE, cBack, &vb); + + // this will trigger loading of all DBF values into the memory + long numFields; + this->get_NumFields(&numFields); + if (numFields > 0) + { + CComVariant var; + for (size_t i = 0; i < _shapeData.size(); i++) + { + _table->get_CellValue(0, i, &var); + } + } + + // closing disk file despite the result success or failure + _shpfileName = ""; + _shxfileName = ""; + _dbffileName = ""; + + if (_shpfile != nullptr) + fclose(_shpfile); + _shpfile = nullptr; + + if (_shxfile != nullptr) + fclose(_shxfile); + _shxfile = nullptr; + + if (_table != nullptr) + ((CTableClass*)_table)->CloseUnderlyingFile(); + + *retval = vb; + } + return S_OK; +} + +// ************************************************************ +// OpenCore() +// ************************************************************ +bool CShapefile::OpenCore(CStringW tmpShpfileName, ICallback* cBack) +{ + USES_CONVERSION; + VARIANT_BOOL vbretval; + + // saving the provided names; + // from now on we must clean the class variables in case the operation won't succeed + _shpfileName = tmpShpfileName; + _shxfileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"shx"; + _dbffileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"dbf"; + _prjfileName = tmpShpfileName.Left(tmpShpfileName.GetLength() - 3) + L"prj"; + + // read mode + _shpfile = _wfopen(_shpfileName, L"rb"); + _shxfile = _wfopen(_shxfileName, L"rb"); + + // opening DBF + if (!_table) + { + CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); + } + else + { + VARIANT_BOOL vb; + _table->Close(&vb); + } + + _table->put_GlobalCallback(_globalCallback); + ((CTableClass*)_table)->InjectShapefile(this); + + const CComBSTR bstrDbf(_dbffileName); + _table->Open(bstrDbf, cBack, &vbretval); + + if (_shpfile == nullptr) + { + ErrorMessage(tkCANT_OPEN_SHP); + this->Close(&vbretval); + } + else if (_shxfile == nullptr) + { + ErrorMessage(tkCANT_OPEN_SHX); + this->Close(&vbretval); + } + else if (vbretval == VARIANT_FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + ErrorMessage(_lastErrorCode); + this->Close(&vbretval); + } + else + { + if (!ReadShx()) // shapefile header is read here as well + { + ErrorMessage(tkINVALID_SHX_FILE); + this->Close(&vbretval); + } + else + { + //Check for supported types + if (_shpfiletype != SHP_NULLSHAPE && + _shpfiletype != SHP_POINT && + _shpfiletype != SHP_POLYLINE && + _shpfiletype != SHP_POLYGON && + _shpfiletype != SHP_POINTZ && + _shpfiletype != SHP_POLYLINEZ && + _shpfiletype != SHP_POLYGONZ && + _shpfiletype != SHP_MULTIPOINT && + _shpfiletype != SHP_MULTIPOINTZ && + _shpfiletype != SHP_POLYLINEM && + _shpfiletype != SHP_POLYGONM && + _shpfiletype != SHP_POINTM && + _shpfiletype != SHP_MULTIPOINTM) + { + ErrorMessage(tkUNSUPPORTED_SHAPEFILE_TYPE); + this->Close(&vbretval); + } + else + { + _shapeData.reserve(_shpOffsets.size()); + for (size_t i = 0; i < _shpOffsets.size(); i++) + { + _shapeData.push_back(new ShapeRecord()); + } + return true; + } + } + } + return false; +} + +// ************************************************************ +// Open() +// ************************************************************ +STDMETHODIMP CShapefile::Open(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + VARIANT_BOOL vbretval; + + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + USES_CONVERSION; + CStringW tmp_shpfileName = OLE2CW(ShapefileName); + + if (tmp_shpfileName.GetLength() == 0) + { + // better to use CreateNew directly, but this call will be preserved for backward compatibility + this->CreateNew(m_globalSettings.emptyBstr, _shpfiletype, &vbretval); + } + else if (tmp_shpfileName.GetLength() <= 3) + { + ErrorMessage(tkINVALID_FILENAME); + } + else + { + // close the opened shapefile + this->Close(&vbretval); + + if (vbretval == VARIANT_FALSE) + { + // error code in the function + return S_OK; + } + + if (OpenCore(tmp_shpfileName, cBack)) + { + _sourceType = sstDiskBased; + + // reading projection + const CComBSTR bstrPrj(_prjfileName); + _geoProjection->ReadFromFileEx(bstrPrj, VARIANT_TRUE, &vbretval); + + ShapeStyleHelper::ApplyRandomDrawingOptions(this); + LabelsHelper::UpdateLabelsPositioning(this); + *retval = VARIANT_TRUE; + } + } + return S_OK; +} + +// ********************************************************* +// CreateNew() +// ********************************************************* +STDMETHODIMP CShapefile::CreateNew(BSTR ShapefileName, ShpfileType ShapefileType, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + return this->CreateNewCore(ShapefileName, ShapefileType, true, retval); +} + +// ********************************************************* +// CreateNewCore() +// ********************************************************* +HRESULT CShapefile::CreateNewCore(BSTR ShapefileName, ShpfileType ShapefileType, bool applyRandomOptions, + VARIANT_BOOL* retval) +{ + *retval = VARIANT_FALSE; + VARIANT_BOOL vb; + + // check for supported types + if (ShapefileType != SHP_NULLSHAPE && + ShapefileType != SHP_POINT && + ShapefileType != SHP_POLYLINE && + ShapefileType != SHP_POLYGON && + ShapefileType != SHP_POINTZ && + ShapefileType != SHP_POLYLINEZ && + ShapefileType != SHP_POLYGONZ && + ShapefileType != SHP_MULTIPOINT && + ShapefileType != SHP_MULTIPOINTZ && + ShapefileType != SHP_POINTM && // MWGIS-69 + ShapefileType != SHP_POLYLINEM && + ShapefileType != SHP_POLYGONM && + ShapefileType != SHP_MULTIPOINTM) + { + ErrorMessage(tkUNSUPPORTED_SHAPEFILE_TYPE); + return S_OK; + } + + USES_CONVERSION; + CString tmp_shpfileName = OLE2CA(ShapefileName); + + // ---------------------------------------------- + // in memory shapefile (without name) + // ---------------------------------------------- + if (tmp_shpfileName.GetLength() == 0) + { + // closing the old shapefile (error code inside the function) + Close(&vb); + + if (vb == VARIANT_TRUE) + { + CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); + + _table->CreateNew(m_globalSettings.emptyBstr, &vb); + + if (!vb) + { + long error; + _table->get_LastErrorCode(&error); + ErrorMessage(error); + _table->Release(); + _table = nullptr; + } + else + { + _shpfiletype = ShapefileType; + _isEditingShapes = true; + _sourceType = sstInMemory; + + if (applyRandomOptions) + { + ShapeStyleHelper::ApplyRandomDrawingOptions(this); + } + + *retval = VARIANT_TRUE; + } + } + + return S_OK; + } + + if (tmp_shpfileName.GetLength() <= 3) + { + ErrorMessage(tkINVALID_FILENAME); + return S_OK; + } + + const CString& shpName = tmp_shpfileName; + const CString shxName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "shx"; + const CString dbfName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; + const CString prjName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "prj"; + + // new file is created, so there must not be any files with this names + if (Utility::FileExists(shpName) != FALSE) + { + ErrorMessage(tkSHP_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExists(shxName) != FALSE) + { + ErrorMessage(tkSHX_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExists(dbfName) != FALSE) + { + ErrorMessage(tkDBF_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExists(prjName) != FALSE) + { + ErrorMessage(tkPRJ_FILE_EXISTS); + return S_OK; + } + + // closing the old shapefile (error code inside the function) + this->Close(&vb); + + if (vb == VARIANT_TRUE) + { + CoCreateInstance(CLSID_Table, nullptr, CLSCTX_INPROC_SERVER, IID_ITable, (void**)&_table); + + _table->put_GlobalCallback(_globalCallback); + + const CString newDbfName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; + const CComBSTR bstrName(newDbfName); + _table->CreateNew(bstrName, &vb); + + if (!vb) + { + _table->get_LastErrorCode(&_lastErrorCode); + ErrorMessage(_lastErrorCode); + _table->Release(); + _table = nullptr; + } + else + { + _shpfileName = tmp_shpfileName; + _shxfileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "shx"; + _dbffileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "dbf"; + _prjfileName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 3) + "prj"; + + _shpfiletype = ShapefileType; + _isEditingShapes = true; + _sourceType = sstInMemory; + + if (applyRandomOptions) + { + ShapeStyleHelper::ApplyRandomDrawingOptions(this); + } + + *retval = VARIANT_TRUE; + } + } + + LabelsHelper::UpdateLabelsPositioning(this); + + return S_OK; +} + +// ********************************************************* +// CreateNewWithShapeID() +// ********************************************************* +STDMETHODIMP CShapefile::CreateNewWithShapeID(BSTR ShapefileName, ShpfileType ShapefileType, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + CreateNew(ShapefileName, ShapefileType, retval); + + if (*retval) + ShapefileHelper::InsertMwShapeIdField(this); + + return S_OK; +} + +#pragma endregion + +#pragma region SaveAndClose +// ***************************************************************** +// Close() +// ***************************************************************** +STDMETHODIMP CShapefile::Close(VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_appendMode) + { + StopAppendMode(); + } + + ClearCachedGeometries(); + + if (_isEditingShapes) + { + // just stop editing shapes, if the shape is in open status + this->StopEditingShapes(VARIANT_FALSE, VARIANT_TRUE, nullptr, retval); + } + + // stop editing table in case only it have been edited + VARIANT_BOOL isEditingTable = VARIANT_FALSE; + if (_table) + { + _table->get_EditingTable(&isEditingTable); + if (isEditingTable) + { + this->StopEditingTable(VARIANT_FALSE, _globalCallback, retval); + _table->get_EditingTable(&isEditingTable); + } + } + + // removing shape data + this->ReleaseMemoryShapes(); + for (auto& i : _shapeData) + { + delete i; + } + _shapeData.clear(); + + if (_spatialIndexLoaded) + IndexSearching::unloadSpatialIndex(_spatialIndexID); + + _sourceType = sstUninitialized; + _shpfiletype = SHP_NULLSHAPE; + LabelsHelper::UpdateLabelsPositioning(this); + + _shpfileName = ""; + _shxfileName = ""; + _dbffileName = ""; + + _minX = 0.0; + _minY = 0.0; + _minZ = 0.0; + _maxX = 0.0; + _maxY = 0.0; + _maxZ = 0.0; + _minM = 0.0; + _maxM = 0.0; + + if (_inputValidation != nullptr) + { + _inputValidation->Release(); + _inputValidation = nullptr; + } + + if (_outputValidation != nullptr) + { + _outputValidation->Release(); + _outputValidation = nullptr; + } + + if (_shpfile != nullptr) fclose(_shpfile); + _shpfile = nullptr; + + if (_shxfile != nullptr) fclose(_shxfile); + _shxfile = nullptr; + + if (_table != nullptr) + { + VARIANT_BOOL vbretval; + _table->Close(&vbretval); + _table->Release(); + _table = nullptr; + } + if (_labels) + { + _labels->Clear(); + _labels->ClearCategories(); + } + if (_charts) + { + _charts->Clear(); + } + if (_categories) + { + _categories->Clear(); + } + *retval = VARIANT_TRUE; + + return S_OK; +} + +// ********************************************************** +// Dump() +// ********************************************************** +//Saves shapefile without reopening it in a new location +STDMETHODIMP CShapefile::Dump(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + const bool callbackIsNull = _globalCallback == nullptr; + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if (_table == nullptr || _sourceType == sstUninitialized) + { + ErrorMessage(tkSHAPEFILE_UNINITIALIZED); + return S_OK; + } + + // in case someone else is writing, we leave + if (_writing) + { + ErrorMessage(tkSHP_WRITE_VIOLATION); + return S_OK; + } + + if (!this->ValidateOutput(this, "Dump", "Shapefile", false)) + return S_OK; + + USES_CONVERSION; + CString sa_shpfileName = OLE2CA(ShapefileName); + + if (sa_shpfileName.GetLength() <= 3) + { + ErrorMessage(tkINVALID_FILENAME); + } + else + { + const CString sa_shxfileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + "shx"; + CString sa_dbffileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + "dbf"; + + // ----------------------------------------------- + // it's not allowed to rewrite the existing files + // ----------------------------------------------- + if (Utility::FileExists(sa_shpfileName)) + { + ErrorMessage(tkSHP_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExists(sa_shxfileName)) + { + ErrorMessage(tkSHX_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExists(sa_dbffileName)) + { + ErrorMessage(tkDBF_FILE_EXISTS); + return S_OK; + } + + // ----------------------------------------------- + // checking in-memory shapes + // ----------------------------------------------- + if (_isEditingShapes) + { + if (VerifyMemShapes(cBack) == FALSE) + { + // error Code is set in function + return S_OK; + } + + // refresh extents + VARIANT_BOOL retVal; + this->RefreshExtents(&retVal); + } + + // ----------------------------------------------- + // opening files + // ----------------------------------------------- + FILE* shpfile = fopen(sa_shpfileName, "wb+"); + if (shpfile == nullptr) + { + ErrorMessage(tkCANT_CREATE_SHP); + return S_OK; + } + + //shx + FILE* shxfile = fopen(sa_shxfileName, "wb+"); + if (shxfile == nullptr) + { + fclose(shpfile); + ErrorMessage(tkCANT_CREATE_SHX); + return S_OK; + } + + // ------------------------------------------------ + // writing the files + // ------------------------------------------------ + this->WriteShp(shpfile, cBack); + this->WriteShx(shxfile, cBack); + + fclose(shpfile); + fclose(shxfile); + + // ------------------------------------------------ + // saving dbf table + // ------------------------------------------------ + _table->Dump(sa_dbffileName.AllocSysString(), cBack, retval); + if (*retval == FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + return S_OK; + } + + // saving projection in new format + VARIANT_BOOL vbretval; + const CStringW prjfileName = sa_shpfileName.Left(sa_shpfileName.GetLength() - 3) + L"prj"; + const CComBSTR bstr(prjfileName); + _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); + + *retval = VARIANT_TRUE; + } + + // restoring callback + if (callbackIsNull) + { + _globalCallback = nullptr; + } + + return S_OK; +} + +// ********************************************************** +// SaveAs() +// ********************************************************** +// Saves shapefile to the new or the same location. Doesn't stop editing mode. +STDMETHODIMP CShapefile::SaveAs(BSTR ShapefileName, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + const bool callbackIsNull = _globalCallback == nullptr; + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if (_table == nullptr || _sourceType == sstUninitialized) + { + ErrorMessage(tkSHAPEFILE_UNINITIALIZED); + return S_OK; + } + + // in case someone else is writing, we leave + if (_writing) + { + ErrorMessage(tkSHP_WRITE_VIOLATION); + return S_OK; + } + + if (!this->ValidateOutput(this, "SaveAs", "Shapefile", false)) + return S_OK; + + USES_CONVERSION; + CStringW newShpName = OLE2W(ShapefileName); + + if (newShpName.GetLength() <= 3) + { + ErrorMessage(tkINVALID_FILENAME); + } + else if (!Utility::EndsWith(newShpName, L".shp")) + { + ErrorMessage(tkINVALID_FILE_EXTENSION); + } + else + { + const CStringW newShxName = newShpName.Left(newShpName.GetLength() - 3) + L"shx"; + const CStringW newDbfName = newShpName.Left(newShpName.GetLength() - 3) + L"dbf"; + + // ----------------------------------------------- + // it's not allowed to rewrite the existing files + // ----------------------------------------------- + if (Utility::FileExistsW(newShpName)) + { + ErrorMessage(tkSHP_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExistsW(newShxName)) + { + ErrorMessage(tkSHX_FILE_EXISTS); + return S_OK; + } + if (Utility::FileExistsW(newDbfName)) + { + ErrorMessage(tkDBF_FILE_EXISTS); + return S_OK; + } + + // ----------------------------------------------- + // checking in-memory shapes + // ----------------------------------------------- + if (_isEditingShapes) + { + if (VerifyMemShapes(cBack) == FALSE) + { + // error Code is set in function + return S_OK; + } + + // refresh extents + VARIANT_BOOL retVal; + RefreshExtents(&retVal); + } + + // ----------------------------------------------- + // opening files + // ----------------------------------------------- + FILE* shpfile = _wfopen(newShpName, L"wb+"); + if (shpfile == nullptr) + { + ErrorMessage(tkCANT_CREATE_SHP); + return S_OK; + } + + //shx + FILE* shxfile = _wfopen(newShxName, L"wb+"); + if (shxfile == nullptr) + { + fclose(shpfile); + ErrorMessage(tkCANT_CREATE_SHX); + return S_OK; + } + + // ------------------------------------------------ + // writing the files + // ------------------------------------------------ + WriteShp(shpfile, cBack); + WriteShx(shxfile, cBack); + + fclose(shpfile); + fclose(shxfile); + + // ------------------------------------------------ + // saving dbf table + // ------------------------------------------------ + const CComBSTR bstrDbf(newDbfName); + _table->SaveAs(bstrDbf, cBack, retval); + + if (*retval != VARIANT_TRUE) + { + _table->get_LastErrorCode(&_lastErrorCode); + _wunlink(newShpName); + _wunlink(newShxName); + return S_OK; + } + + // ------------------------------------------------- + // switching to the new files + // ------------------------------------------------- + shpfile = _wfopen(newShpName, L"rb"); + shxfile = _wfopen(newShxName, L"rb"); + + if (_shpfile != nullptr) fclose(_shpfile); + _shpfile = shpfile; + + if (_shxfile != nullptr) fclose(_shxfile); + _shxfile = shxfile; + + // update all filenames: + _shpfileName = newShpName; // saving of shp filename should be done before writing the projection; + _shxfileName = newShxName; // otherwise projection string will be written to the memory + _dbffileName = newDbfName; + _prjfileName = newShpName.Left(newShpName.GetLength() - 3) + L"prj"; + + _sourceType = sstDiskBased; + + // saving projection in new format + VARIANT_BOOL vbretval, isEmpty; + _geoProjection->get_IsEmpty(&isEmpty); + if (!isEmpty) + { + const CComBSTR bstr(_prjfileName); + _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); + } + + if (_useQTree) + GenerateQTree(); + + *retval = VARIANT_TRUE; + } + + // restoring callback + if (callbackIsNull) + { + _globalCallback = nullptr; + } + + return S_OK; +} + +// ************************************************************** +// Save() +// ************************************************************** +// saving without exiting edit mode +STDMETHODIMP CShapefile::Save(ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + // no edits were made; it doesn't make sense to save it + if (_isEditingShapes == FALSE) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + return S_OK; + } + + if (VerifyMemShapes(_globalCallback) == FALSE) + { + // error Code is set in function + return S_OK; + } + + if (!this->ValidateOutput(this, "Save", "Shapefile", false)) + return S_OK; + + // compute the extents + VARIANT_BOOL res; + RefreshExtents(&res); + + // ------------------------------------------------- + // Reopen the files in the write mode + // ------------------------------------------------- + if (_shpfile && _shxfile) + { + _shpfile = _wfreopen(_shpfileName, L"wb+", _shpfile); + _shxfile = _wfreopen(_shxfileName, L"wb+", _shxfile); + } + else + { + _shpfile = _wfopen(_shpfileName, L"wb+"); + _shxfile = _wfopen(_shxfileName, L"wb+"); + } + + if (_shpfile == nullptr || _shxfile == nullptr) + { + if (_shxfile != nullptr) + { + fclose(_shxfile); + _shxfile = nullptr; + _lastErrorCode = tkCANT_OPEN_SHX; + } + if (_shpfile != nullptr) + { + fclose(_shpfile); + _shpfile = nullptr; + _lastErrorCode = tkCANT_OPEN_SHP; + } + *retval = FALSE; + + ErrorMessage(_lastErrorCode); + } + else + { + _writing = true; + + // ------------------------------------------------- + // Writing the files + // ------------------------------------------------- + WriteShp(_shpfile, cBack); + WriteShx(_shxfile, cBack); + + if (_useQTree) + GenerateQTree(); + + // ------------------------------------------------- + // Reopen the updated files + // ------------------------------------------------- + _shpfile = _wfreopen(_shpfileName, L"rb+", _shpfile); + _shxfile = _wfreopen(_shxfileName, L"rb+", _shxfile); + + if (_shpfile == nullptr || _shxfile == nullptr) + { + if (_shxfile != nullptr) + { + fclose(_shxfile); + _shxfile = nullptr; + _lastErrorCode = tkCANT_OPEN_SHX; + } + if (_shpfile != nullptr) + { + fclose(_shpfile); + _shpfile = nullptr; + _lastErrorCode = tkCANT_OPEN_SHP; + } + *retval = FALSE; + + ErrorMessage(_lastErrorCode); + } + else + { + //Save the table file + _table->Save(cBack, retval); + + _sourceType = sstDiskBased; + + // saving projection in new format + VARIANT_BOOL vbretval, isEmpty; + _geoProjection->get_IsEmpty(&isEmpty); + if (!isEmpty) + { + const CComBSTR bstr(_prjfileName); + _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); + } + + *retval = VARIANT_TRUE; + } + } + + _writing = false; + return S_OK; +} + +// ************************************************************ +// Resource() +// ************************************************************ +STDMETHODIMP CShapefile::Resource(BSTR newShpPath, VARIANT_BOOL* retval) +{ + USES_CONVERSION; + Close(retval); + Open(newShpPath, nullptr, retval); + return S_OK; +} +#pragma endregion + +// *********************************************************************** +// Clone() +// *********************************************************************** +// Creates new shapefile with the same type and fields as existing one +STDMETHODIMP CShapefile::Clone(IShapefile** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + ShapefileHelper::CloneCore(this, retVal, _shpfiletype); + return S_OK; +} + +// ************************************************************ +// get_Extents() +// ************************************************************ +STDMETHODIMP CShapefile::get_Extents(IExtents** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + IExtents* bBox = nullptr; + ComHelper::CreateExtents(&bBox); + + // Extents could change because of the moving of points of a single shape + // It's difficult to track such changes, so we still need to recalculate them + // here to enforce proper drawing; _fastMode mode - for those who want + // to call refresh extents theirselfs + if (!_fastMode) + { + VARIANT_BOOL vbretval; + this->RefreshExtents(&vbretval); + } + + bBox->SetBounds(_minX, _minY, _minZ, _maxX, _maxY, _maxZ); + bBox->SetMeasureBounds(_minM, _maxM); + *pVal = bBox; + + return S_OK; +} + +#pragma region AttributeTable +// **************************************************************** +// EditInsertField() +// **************************************************************** +STDMETHODIMP CShapefile::EditInsertField(IField* NewField, long* FieldIndex, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (cBack == nullptr && _globalCallback != nullptr) + cBack = _globalCallback; + + if (_table != nullptr) + { + _table->EditInsertField(NewField, FieldIndex, cBack, retval); + } + else + { + *retval = VARIANT_FALSE; + _lastErrorCode = tkFILE_NOT_OPEN; + ErrorMessage(_lastErrorCode, cBack); + return S_OK; + } + + if (*retval == VARIANT_FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + *retval = VARIANT_FALSE; + } + + return S_OK; +} + +// **************************************************************** +// EditDeleteField() +// **************************************************************** +STDMETHODIMP CShapefile::EditDeleteField(long FieldIndex, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if (_table != nullptr) + { + _table->EditDeleteField(FieldIndex, cBack, retval); + } + else + { + *retval = VARIANT_FALSE; + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + if (*retval == VARIANT_FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + *retval = VARIANT_FALSE; + } + + return S_OK; +} + +// **************************************************************** +// EditCellValue() +// **************************************************************** +STDMETHODIMP CShapefile::EditCellValue(long FieldIndex, long ShapeIndex, VARIANT NewVal, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_table != nullptr) + { + _table->EditCellValue(FieldIndex, ShapeIndex, NewVal, retval); + } + else + { + *retval = VARIANT_FALSE; + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + if (*retval == VARIANT_FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + } + + return S_OK; +} + +// **************************************************************** +// StartEditingTable() +// **************************************************************** +STDMETHODIMP CShapefile::StartEditingTable(ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_appendMode) + { + ErrorMessage(tkDBF_NO_EDIT_MODE_WHEN_APPENDING); + *retval = VARIANT_FALSE; + return S_OK; + } + + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if (_table != nullptr) + { + _table->StartEditingTable(cBack, retval); + } + else + { + *retval = VARIANT_FALSE; + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + if (*retval == VARIANT_FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + *retval = VARIANT_FALSE; + } + + return S_OK; +} + +// **************************************************************** +// StopEditingTable() +// **************************************************************** +STDMETHODIMP CShapefile::StopEditingTable(VARIANT_BOOL ApplyChanges, ICallback* cBack, VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_globalCallback == nullptr && cBack != nullptr) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if (_table != nullptr) + { + _table->StopEditingTable(ApplyChanges, cBack, retval); + } + else + { + *retval = VARIANT_FALSE; + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + if (*retval == FALSE) + { + _table->get_LastErrorCode(&_lastErrorCode); + *retval = VARIANT_FALSE; + } + + return S_OK; +} + +// ***************************************************************** +// get_Field() +// ***************************************************************** +STDMETHODIMP CShapefile::get_Field(long FieldIndex, IField** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_table != nullptr) + { + _table->get_Field(FieldIndex, pVal); + if (*pVal != nullptr) + { + // we need to report error from field class, and will use callback from this class for it + ICallback* cBack = nullptr; + if ((*pVal)->get_GlobalCallback(&cBack) == NULL && this->_globalCallback != nullptr) + (*pVal)->put_GlobalCallback(_globalCallback); + + if (cBack != nullptr) + cBack->Release(); // we put a reference in field class so must release it here + } + } + else + { + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + return S_OK; +} + +// ***************************************************************** +// get_FieldByName() +// ***************************************************************** +STDMETHODIMP CShapefile::get_FieldByName(BSTR Fieldname, IField** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + long max; + + CString strFieldname; + IField* testVal; + + _table->get_NumFields(&max); + if (_table != nullptr) + { + if (_tcslen(OLE2CA(Fieldname)) > 0) + { + strFieldname = OLE2A(Fieldname); + } + else + { + ErrorMessage(tkZERO_LENGTH_STRING); + } + + for (int fld = 0; fld < max; fld++) + { + _table->get_Field(fld, &testVal); + CComBSTR Testname; + testVal->get_Name(&Testname); + CString strTestname = OLE2A(Testname); + if (strTestname.CompareNoCase(strFieldname) == 0) + { + *pVal = testVal; + return S_OK; + } + testVal->Release(); + } + } + else + { + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + // we did not have a file error, but we also didn't match the name + pVal = nullptr; + return S_OK; +} + +// ***************************************************************** +// get_CellValue() +// ***************************************************************** +STDMETHODIMP CShapefile::get_CellValue(long FieldIndex, long ShapeIndex, VARIANT* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + if (_table != nullptr) + { + _table->get_CellValue(FieldIndex, ShapeIndex, pVal); + } + else + { + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + return S_OK; +} + +// ***************************************************************** +// get_EditingTable() +// ***************************************************************** +STDMETHODIMP CShapefile::get_EditingTable(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_table != nullptr) + { + _table->get_EditingTable(pVal); + } + else + { + *pVal = VARIANT_FALSE; + ErrorMessage(tkFILE_NOT_OPEN); + return S_OK; + } + + return S_OK; +} + +// ************************************************************* +// get_Table() +// ************************************************************* +STDMETHODIMP CShapefile::get_Table(ITable** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retVal = _table; + if (_table) + { + _table->AddRef(); + } + return S_OK; +} +#pragma endregion + +#pragma region DrawingOptions + +// ************************************************************* +// get_ShapeRotation() +// ************************************************************* +STDMETHODIMP CShapefile::get_ShapeRotation(long ShapeIndex, double* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + *pVal = -1; + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + *pVal = _shapeData[ShapeIndex]->rotation; + return S_OK; +} + +STDMETHODIMP CShapefile::put_ShapeRotation(long ShapeIndex, double newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + _shapeData[ShapeIndex]->rotation = static_cast(newVal); + + return S_OK; +} + +// ************************************************************* +// get_ShapeVisible() +// ************************************************************* +STDMETHODIMP CShapefile::get_ShapeVisible(long ShapeIndex, VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = VARIANT_FALSE; + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + // this particular shape was not hidden explicitly or via visibility expression + if (!_shapeData[ShapeIndex]->hidden() && _shapeData[ShapeIndex]->isVisible()) + { + long ctIndex = -1; + get_ShapeCategory(ShapeIndex, &ctIndex); + if (ctIndex == -1) + { + // no category, check default options + _defaultDrawOpt->get_Visible(pVal); + } + else + { + // there is category, check whether it is visible + CComPtr ct = nullptr; + get_ShapeCategory3(ShapeIndex, &ct); + if (ct) + { + CComPtr options = nullptr; + ct->get_DrawingOptions(&options); + if (options) + { + options->get_Visible(pVal); + } + } + } + } + } + return S_OK; +} + +// ************************************************************* +// ShapeIsHidden() +// ************************************************************* +STDMETHODIMP CShapefile::get_ShapeIsHidden(LONG shapeIndex, VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) + { + *pVal = VARIANT_FALSE; + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + *pVal = _shapeData[shapeIndex]->hidden() ? VARIANT_TRUE : VARIANT_FALSE; + } + return S_OK; +} + +STDMETHODIMP CShapefile::put_ShapeIsHidden(LONG shapeIndex, VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + _shapeData[shapeIndex]->hidden(newVal != 0); + + return S_OK; +} + +// ************************************************************* +// get_ShapeModified() +// ************************************************************* +STDMETHODIMP CShapefile::get_ShapeModified(long ShapeIndex, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + *retVal = -1; + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + *retVal = _shapeData[ShapeIndex]->modified() ? VARIANT_TRUE : VARIANT_FALSE; + } + + return S_OK; +} + +STDMETHODIMP CShapefile::put_ShapeModified(long ShapeIndex, VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + _shapeData[ShapeIndex]->modified(newVal != 0); + } + + return S_OK; +} + + +// ************************************************************* +// get_ShapeCategory() +// ************************************************************* +STDMETHODIMP CShapefile::get_ShapeCategory(long ShapeIndex, long* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) //_numShapes) + { + *pVal = -1; + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + *pVal = _shapeData[ShapeIndex]->category; + return S_OK; +} + +STDMETHODIMP CShapefile::put_ShapeCategory(long ShapeIndex, long newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) //_numShapes ) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + _shapeData[ShapeIndex]->category = (int)newVal; + + return S_OK; +} + +// ************************************************************* +// get_ShapeCategory2() +// ************************************************************* +STDMETHODIMP CShapefile::put_ShapeCategory2(long ShapeIndex, BSTR categoryName) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + int index; + _categories->get_CategoryIndexByName(categoryName, &index); + if (index == -1) + { + ErrorMessage(tkCATEGORY_WASNT_FOUND); + } + else + { + _shapeData[ShapeIndex]->category = (int)index; + } + } + return S_OK; +} + +STDMETHODIMP CShapefile::get_ShapeCategory2(long ShapeIndex, BSTR* categoryName) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + const int index = _shapeData[ShapeIndex]->category; + long count; + _categories->get_Count(&count); + if (index >= 0 && index < count) + { + IShapefileCategory* ct; + _categories->get_Item(index, &ct); + ct->get_Name(categoryName); + ct->Release(); + return S_OK; + } + ErrorMessage(tkCATEGORY_WASNT_FOUND); + } + *categoryName = SysAllocString(L""); + return S_OK; +} + +// ************************************************************* +// put_ShapeCategory3() +// ************************************************************* +STDMETHODIMP CShapefile::put_ShapeCategory3(long ShapeIndex, IShapefileCategory* category) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + int index; + _categories->get_CategoryIndex(category, &index); + if (index == -1) + { + ErrorMessage(tkCATEGORY_WASNT_FOUND); + } + else + { + _shapeData[ShapeIndex]->category = (int)index; + } + } + return S_OK; +} + +STDMETHODIMP CShapefile::get_ShapeCategory3(long ShapeIndex, IShapefileCategory** category) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *category = nullptr; + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + const int index = _shapeData[ShapeIndex]->category; + long count; + _categories->get_Count(&count); + if (index >= 0 && index < count) + { + IShapefileCategory* ct; + _categories->get_Item(index, &ct); + *category = ct; // ref was added in the get_Item + } + else + { + ErrorMessage(tkCATEGORY_WASNT_FOUND); + } + } + return S_OK; +} + +// ******************************************************************* +// SelectionDrawingOptions() +// ******************************************************************* +// Returns and sets parameters used to draw selection for the shapefile. +STDMETHODIMP CShapefile::get_SelectionDrawingOptions(IShapeDrawingOptions** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _selectDrawOpt; + if (_selectDrawOpt) + _selectDrawOpt->AddRef(); + return S_OK; +} + +STDMETHODIMP CShapefile::put_SelectionDrawingOptions(IShapeDrawingOptions* newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (!newVal) + { + ErrorMessage(tkINVALID_PARAMETER_VALUE); + } + else + { + ComHelper::SetRef(newVal, (IDispatch**)&_selectDrawOpt, false); + } + return S_OK; +} + +// ******************************************************************* +// DeafultDrawingOptions() +// ******************************************************************* +// Returns and sets parameters used to draw shapefile by default. +STDMETHODIMP CShapefile::get_DefaultDrawingOptions(IShapeDrawingOptions** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _defaultDrawOpt; + if (_defaultDrawOpt) + _defaultDrawOpt->AddRef(); + return S_OK; +} + +STDMETHODIMP CShapefile::put_DefaultDrawingOptions(IShapeDrawingOptions* newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + if (!newVal) + { + ErrorMessage(tkINVALID_PARAMETER_VALUE); + } + else + { + ComHelper::SetRef(newVal, (IDispatch**)&_defaultDrawOpt); + } + return S_OK; +} + +// *********************************************************************** +// put_ReferenceToCategories +// *********************************************************************** +void CShapefile::put_ReferenceToCategories(bool bNullReference) +{ + if (_categories == nullptr) return; + auto* coCategories = dynamic_cast(_categories); + if (!bNullReference) + coCategories->put_ParentShapefile(this); + else + coCategories->put_ParentShapefile(nullptr); +}; + +// *********************************************************************** +// get/put_Categories +// *********************************************************************** +STDMETHODIMP CShapefile::get_Categories(IShapefileCategories** pVal) +{ + *pVal = _categories; + if (_categories != nullptr) + _categories->AddRef(); + return S_OK; +} + +STDMETHODIMP CShapefile::put_Categories(IShapefileCategories* newVal) +{ + if (ComHelper::SetRef((IDispatch*)newVal, (IDispatch**)&_categories, false)) + { + ((CShapefileCategories*)_categories)->put_ParentShapefile(this); + } + return S_OK; +} +#pragma endregion + +// ******************************************************************** +// get_SelectionColor +// ******************************************************************** +STDMETHODIMP CShapefile::get_SelectionColor(OLE_COLOR* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = _selectionColor; + return S_OK; +} + +STDMETHODIMP CShapefile::put_SelectionColor(OLE_COLOR newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _selectionColor = newVal; + return S_OK; +} + +// ******************************************************************** +// get_SelectionTransparency +// ******************************************************************** +STDMETHODIMP CShapefile::get_SelectionTransparency(BYTE* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = _selectionTransparency; + return S_OK; +} + +STDMETHODIMP CShapefile::put_SelectionTransparency(BYTE newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (newVal > 255) newVal = 255; + _selectionTransparency = newVal; + return S_OK; +} + +// ******************************************************************** +// get_SelectionAppearance +// ******************************************************************** +STDMETHODIMP CShapefile::get_SelectionAppearance(tkSelectionAppearance* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = _selectionAppearance; + return S_OK; +} + +STDMETHODIMP CShapefile::put_SelectionAppearance(tkSelectionAppearance newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _selectionAppearance = newVal; + return S_OK; +} + +// ******************************************************************** +// get_PointCollisionMode +// ******************************************************************** +STDMETHODIMP CShapefile::get_CollisionMode(tkCollisionMode* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = _collisionMode; + return S_OK; +} + +STDMETHODIMP CShapefile::put_CollisionMode(tkCollisionMode newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _collisionMode = newVal; + return S_OK; +} + +#pragma region "Seialization" +// ******************************************************** +// Serialize() +// ******************************************************** +STDMETHODIMP CShapefile::Serialize(VARIANT_BOOL SaveSelection, BSTR* retVal) +{ + return Serialize2(SaveSelection, VARIANT_FALSE, retVal); +} + +STDMETHODIMP CShapefile::Serialize2(VARIANT_BOOL SaveSelection, VARIANT_BOOL SerializeCategories, BSTR* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + CPLXMLNode* psTree = this->SerializeCore(VARIANT_TRUE, "ShapefileClass", SerializeCategories != 0); + Utility::SerializeAndDestroyXmlTree(psTree, retVal); + return S_OK; +} + +// ******************************************************** +// SerializeCore() +// ******************************************************** +CPLXMLNode* CShapefile::SerializeCore(VARIANT_BOOL SaveSelection, CString ElementName, bool serializeCategories) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + CPLXMLNode* psTree = CPLCreateXMLNode(nullptr, CXT_Element, ElementName); + + if (psTree) + { + CString s = OLE2CA(_expression); + if (s != "") + Utility::CPLCreateXMLAttributeAndValue(psTree, "VisibilityExpression", s); + + + if (_useQTree != FALSE) + Utility::CPLCreateXMLAttributeAndValue(psTree, "UseQTree", CPLString().Printf("%d", (int)_useQTree)); + + if (_collisionMode != LocalList) + Utility::CPLCreateXMLAttributeAndValue(psTree, "CollisionMode", + CPLString().Printf("%d", (int)_collisionMode)); + + if (_selectionAppearance != saSelectionColor) + Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionAppearance", + CPLString().Printf("%d", (int)_selectionAppearance)); + + if (_selectionColor != RGB(255, 255, 0)) + Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionColor", + CPLString().Printf("%d", (int)_selectionColor)); + + if (_selectionTransparency != 180) + Utility::CPLCreateXMLAttributeAndValue(psTree, "SelectionTransparency", + CPLString().Printf("%d", (int)_selectionTransparency)); + + if (_minDrawingSize != 1) + Utility::CPLCreateXMLAttributeAndValue(psTree, "MinDrawingSize", CPLString().Printf("%d", _minDrawingSize)); + + // for in-memory shapefiles only + if (_sourceType == sstInMemory) + Utility::CPLCreateXMLAttributeAndValue(psTree, "ShpType", + CPLString().Printf("%d", (int)this->_shpfiletype)); + + s = OLE2CA(_sortField); + if (s != "") + Utility::CPLCreateXMLAttributeAndValue(psTree, "SortField", s); + + if (_sortAscending != VARIANT_FALSE) + Utility::CPLCreateXMLAttributeAndValue(psTree, "SortAscending", + CPLString().Printf("%d", (int)_sortAscending)); + + // drawing options + CPLXMLNode* node = ((CShapeDrawingOptions*)_defaultDrawOpt)->SerializeCore("DefaultDrawingOptions"); + if (node) + { + CPLAddXMLChild(psTree, node); + } + + if (_selectionAppearance == saDrawingOptions) + { + node = ((CShapeDrawingOptions*)_selectDrawOpt)->SerializeCore("SelectionDrawingOptions"); + if (node) + { + CPLAddXMLChild(psTree, node); + } + } + + // categories + node = ((CShapefileCategories*)_categories)->SerializeCore("ShapefileCategoriesClass"); + if (node) + { + CPLAddXMLChild(psTree, node); + } + + // labels + CPLXMLNode* psLabels = ((CLabels*)_labels)->SerializeCore("LabelsClass"); + if (psLabels) + { + CPLAddXMLChild(psTree, psLabels); + } + + // charts + CPLXMLNode* psCharts = ((CCharts*)_charts)->SerializeCore("ChartsClass"); + if (psCharts) + { + CPLAddXMLChild(psTree, psCharts); + } + + // ---------------------------------------------------- + // selection + // ---------------------------------------------------- + long numSelected; + this->get_NumSelected(&numSelected); + + if (numSelected > 0 && SaveSelection) + { + auto* selection = new char[_shapeData.size() + 1]; + selection[_shapeData.size()] = '\0'; + for (unsigned int i = 0; i < _shapeData.size(); i++) + { + selection[i] = _shapeData[i]->selected() ? '1' : '0'; + } + + CPLXMLNode* nodeSelection = CPLCreateXMLElementAndValue(psTree, "Selection", selection); + if (nodeSelection) + { + Utility::CPLCreateXMLAttributeAndValue(nodeSelection, "TotalCount", + CPLString().Printf("%d", _shapeData.size())); + Utility::CPLCreateXMLAttributeAndValue(nodeSelection, "SelectedCount", + CPLString().Printf("%d", numSelected)); + } + delete[] selection; + } + + // ---------------------------------------------------- + // serialization of category indices + // ---------------------------------------------------- + // Paul Meems TODO: This variable comes in as a parameter as well. + // Is this correct? + bool serializeCategories = false; + + for (auto& i : _shapeData) + { + if (i->category != -1) + { + serializeCategories = true; + } + } + + if (serializeCategories) + { + s = ""; + // doing it with CString is ugly of course, better to allocate a buffer + CString temp; + for (auto& i : _shapeData) + { + temp.Format("%d,", i->category); + s += temp; + } + + // when there are no indices assigned, write an empty node with Count = 0; + // to signal, that categories must not be applied automatically (behavior for older versions) + CPLXMLNode* nodeCats = CPLCreateXMLElementAndValue(psTree, "CategoryIndices", s.GetBuffer()); + if (nodeCats) + { + Utility::CPLCreateXMLAttributeAndValue(nodeCats, "Count", + CPLString().Printf( + "%d", serializeCategories ? _shapeData.size() : 0)); + } + } + + // ---------------------------------------------------- + // table + // ---------------------------------------------------- + if (_table) + { + CPLXMLNode* psTable = ((CTableClass*)_table)->SerializeCore("TableClass"); + if (psTable) + { + CPLAddXMLChild(psTree, psTable); + } + } + } + return psTree; +} + +// ******************************************************** +// Deserialize() +// ******************************************************** +STDMETHODIMP CShapefile::Deserialize(VARIANT_BOOL LoadSelection, BSTR newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + CString s = OLE2CA(newVal); + CPLXMLNode* node = CPLParseXMLString(s.GetString()); + if (node) + { + CPLXMLNode* nodeSf = CPLGetXMLNode(node, "=ShapefileClass"); + if (nodeSf) + { + this->DeserializeCore(VARIANT_TRUE, nodeSf); + } + CPLDestroyXMLNode(node); + } + return S_OK; +} + +// ******************************************************** +// DeserializeCore() +// ******************************************************** +bool CShapefile::DeserializeCore(VARIANT_BOOL LoadSelection, CPLXMLNode* node) +{ + USES_CONVERSION; + + if (!node) + return false; + + CString s = CPLGetXMLValue(node, "VisibilityExpression", nullptr); + SysFreeString(_expression); + _expression = A2BSTR(s); + + s = CPLGetXMLValue(node, "UseQTree", nullptr); + _useQTree = s != "" ? (BOOL)atoi(s.GetString()) : FALSE; + + s = CPLGetXMLValue(node, "CollisionMode", nullptr); + _collisionMode = s != "" ? (tkCollisionMode)atoi(s.GetString()) : LocalList; + + s = CPLGetXMLValue(node, "SelectionAppearance", nullptr); + _selectionAppearance = s != "" ? (tkSelectionAppearance)atoi(s.GetString()) : saSelectionColor; + + s = CPLGetXMLValue(node, "SelectionColor", nullptr); + _selectionColor = s != "" ? (OLE_COLOR)atoi(s.GetString()) : RGB(255, 255, 0); + + s = CPLGetXMLValue(node, "SelectionTransparency", nullptr); + _selectionTransparency = s != "" ? (unsigned char)atoi(s.GetString()) : 180; + + s = CPLGetXMLValue(node, "MinDrawingSize", nullptr); + _minDrawingSize = s != "" ? atoi(s.GetString()) : 1; + + s = CPLGetXMLValue(node, "SortField", nullptr); + const CComBSTR bstrSortField = A2W(s); + this->put_SortField(bstrSortField); + + s = CPLGetXMLValue(node, "SortAscending", nullptr); + const VARIANT_BOOL sortAsc = s != "" ? (VARIANT_BOOL)atoi(s.GetString()) : VARIANT_FALSE; + this->put_SortAscending(sortAsc); + + if (_sourceType == sstInMemory) + { + s = CPLGetXMLValue(node, "ShpType", nullptr); + if (s != "") + { + _shpfiletype = (ShpfileType)atoi(s.GetString()); + } + } + + // drawing options + CPLXMLNode* psChild = CPLGetXMLNode(node, "DefaultDrawingOptions"); + if (psChild) + { + ((CShapeDrawingOptions*)_defaultDrawOpt)->DeserializeCore(psChild); + } + + if (_selectionAppearance == saDrawingOptions) + { + psChild = CPLGetXMLNode(node, "SelectionDrawingOptions"); + if (psChild) + { + ((CShapeDrawingOptions*)_selectDrawOpt)->DeserializeCore(psChild); + } + } + + // Categories + psChild = CPLGetXMLNode(node, "ShapefileCategoriesClass"); + if (psChild) + { + ((CShapefileCategories*)_categories)->DeserializeCore(psChild, false); + } + + CPLXMLNode* nodeCats = CPLGetXMLNode(node, "CategoryIndices"); + bool needsApplyExpression = true; + if (nodeCats) + { + CString indices = CPLGetXMLValue(nodeCats, "=CategoryIndices", ""); + if (indices.GetLength() > 0) + { + s = CPLGetXMLValue(nodeCats, "Count", "0"); + const long savedCount = atoi(s); + int foundCount = 0; + char* buffer = indices.GetBuffer(); + for (int i = 0; i < indices.GetLength(); i++) + { + if (buffer[i] == ',') + { + foundCount++; + } + } + + if (foundCount == savedCount && foundCount == _shapeData.size()) + { + const int size = _shapeData.size(); + int pos = 0, count = 0; + CString ct = indices.Tokenize(",", pos); + while (ct.GetLength() != 0 && count < size) + { + _shapeData[count]->category = atoi(ct); + ct = indices.Tokenize(",", pos); + count++; + }; + bool needsApplyExpression = false; + } + } + } + + // If no indices or invalid indices, re-apply: + if (needsApplyExpression) + { + ((CShapefileCategories*)_categories)->ApplyExpressions(); + } + + // Labels + psChild = CPLGetXMLNode(node, "LabelsClass"); + if (psChild) + { + ((CLabels*)_labels)->DeserializeCore(psChild); + } + + // Charts + psChild = CPLGetXMLNode(node, "ChartsClass"); + if (psChild) + { + ((CCharts*)_charts)->DeserializeCore(psChild); + } + + // selection + CPLXMLNode* nodeSelection = CPLGetXMLNode(node, "Selection"); + if (nodeSelection && LoadSelection) + { + this->SelectNone(); + + s = CPLGetXMLValue(nodeSelection, "TotalCount", "0"); + const long count = atoi(s); + s = CPLGetXMLValue(nodeSelection, "=Selection", ""); + if (s.GetLength() == count && s.GetLength() == _shapeData.size()) + { + char* selection = s.GetBuffer(); + for (unsigned int i = 0; i < _shapeData.size(); i++) + { + if (selection[i] == '1') + { + _shapeData[i]->selected(true); + } + } + } + } + + + // table + if (_table) + { + psChild = CPLGetXMLNode(node, "TableClass"); + if (psChild) + { + ((CTableClass*)_table)->DeserializeCore(psChild); + } + } + return true; +} +#pragma endregion + + +#pragma region Projection +// ***************************************************************** +// get_Projection() +// ***************************************************************** +STDMETHODIMP CShapefile::get_Projection(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + _geoProjection->ExportToProj4(pVal); + return S_OK; +} + +// ***************************************************************** +// put_Projection() +// ***************************************************************** +STDMETHODIMP CShapefile::put_Projection(BSTR proj4Projection) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + VARIANT_BOOL vbretval; + _geoProjection->ImportFromProj4(proj4Projection, &vbretval); + if (vbretval) + { + const CComBSTR bstrFilename(_prjfileName); + _geoProjection->WriteToFileEx(bstrFilename, VARIANT_TRUE, &vbretval); + } + return S_OK; +} + +// ***************************************************************** +// get_GeoProjection() +// ***************************************************************** +STDMETHODIMP CShapefile::get_GeoProjection(IGeoProjection** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (_geoProjection) + _geoProjection->AddRef(); + + *retVal = _geoProjection; + return S_OK; +} + +// ***************************************************************** +// put_GeoProjection() +// ***************************************************************** +STDMETHODIMP CShapefile::put_GeoProjection(IGeoProjection* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + ComHelper::SetRef((IDispatch*)pVal, (IDispatch**)&_geoProjection, false); + if (_prjfileName.GetLength() != 0) + { + VARIANT_BOOL vbretval; + const CComBSTR bstr(_prjfileName); + _geoProjection->WriteToFileEx(bstr, VARIANT_TRUE, &vbretval); + } + return S_OK; +} + +// **************************************************************** +// get_IsGeographicProjection +// **************************************************************** +STDMETHODIMP CShapefile::get_IsGeographicProjection(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *pVal = VARIANT_FALSE; + + if (_geoProjection) + _geoProjection->get_IsGeographic(pVal); + + return S_OK; +} + +// ***************************************************************** +// Reproject() +// ***************************************************************** +STDMETHODIMP CShapefile::Reproject(IGeoProjection* newProjection, LONG* reprojectedCount, IShapefile** retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + if (!this->ReprojectCore(newProjection, reprojectedCount, retVal, false)) + *retVal = nullptr; + return S_OK; +} + +// ***************************************************************** +// ReprojectInPlace() +// ***************************************************************** +STDMETHODIMP CShapefile::ReprojectInPlace(IGeoProjection* newProjection, LONG* reprojectedCount, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (!_isEditingShapes) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + *retVal = VARIANT_FALSE; + } + else + { + if (this->ReprojectCore(newProjection, reprojectedCount, nullptr, true)) + { + // spatial index must be deleted, as it became useful all the same + VARIANT_BOOL vb; + RemoveSpatialIndex(&vb); + + // update qtree + if (_useQTree) + GenerateQTree(); + + VARIANT_BOOL vbretval; + this->RefreshExtents(&vbretval); + *retVal = VARIANT_TRUE; + return S_OK; + } + *retVal = NULL; + } + return S_OK; +} + +// ***************************************************************** +// ReprojectCore() +// ***************************************************************** +bool CShapefile::ReprojectCore(IGeoProjection* newProjection, LONG* reprojectedCount, IShapefile** retVal, + bool reprojectInPlace) +{ + // ------------------------------------------------------ + // Validation + // ------------------------------------------------------ + if (!newProjection) + { + ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + return false; + } + + VARIANT_BOOL isEmpty1, isEmpty2; + newProjection->get_IsEmpty(&isEmpty1); + _geoProjection->get_IsEmpty(&isEmpty2); + if (isEmpty1 || isEmpty2) + { + ErrorMessage(tkPROJECTION_NOT_INITIALIZED); + return false; + } + + if (!ValidateInput(this, "Reproject/ReprojectInPlace", "this", VARIANT_FALSE)) + return false; + + m_globalSettings.gdalErrorMessage = ""; + OGRSpatialReference* projSource = ((CGeoProjection*)_geoProjection)->get_SpatialReference(); + OGRSpatialReference* projTarget = ((CGeoProjection*)newProjection)->get_SpatialReference(); + + OGRCoordinateTransformation* transf = OGRCreateCoordinateTransformation(projSource, projTarget); + if (!transf) + { + m_globalSettings.gdalErrorMessage = CPLGetLastErrorMsg(); + ErrorMessage(tkFAILED_TO_REPROJECT); + return false; + } + + // ------------------------------------------------------ + // Creating output + // ------------------------------------------------------ + if (!reprojectInPlace) + this->Clone(retVal); + + // ------------------------------------------------------ + // Processing + // ------------------------------------------------------ + CComVariant var; + const long numShapes = _shapeData.size(); + long newIndex = 0; + + long numFields, percent = 0; + this->get_NumFields(&numFields); + + VARIANT_BOOL vb = VARIANT_FALSE; + *reprojectedCount = 0; + + for (long i = 0; i < numShapes; i++) + { + CallbackHelper::Progress(_globalCallback, i, numShapes, "Reprojecting...", _key, percent); + + IShape* shp = nullptr; + this->GetValidatedShape(i, &shp); + if (!shp) continue; + + if (!reprojectInPlace) + { + IShape* shpNew = nullptr; + shp->Clone(&shpNew); + shp->Release(); + shp = shpNew; + } + + if (shp) + { + long numPoints; + shp->get_NumPoints(&numPoints); + + if (numPoints > 0) + { + auto* x = new double[numPoints]; + auto* y = new double[numPoints]; + + // extracting coordinates + for (long j = 0; j < numPoints; j++) + { + shp->get_XY(j, x + j, y + j, &vb); + } + + // will work faster after embedding to the CShape class + const BOOL res = transf->Transform(numPoints, x, y); + if (!res) + { + // save error message and continue + if (m_globalSettings.gdalErrorMessage == "") + m_globalSettings.gdalErrorMessage = CPLGetLastErrorMsg(); + } + else + { + // saving updated coordinates + for (long j = 0; j < numPoints; j++) + { + shp->put_XY(j, x[j], y[j], &vb); + } + + if (!reprojectInPlace) + { + // get next available index + (*retVal)->get_NumShapes(&newIndex); + // insert Shape into target at new index + (*retVal)->EditInsertShape(shp, &newIndex, &vb); + + // copy attributes + for (long j = 0; j < numFields; j++) + { + // get cell value at source index i + this->get_CellValue(j, i, &var); + // set cell value into target at new index + (*retVal)->EditCellValue(j, newIndex, var, &vb); + } + } + // + (*reprojectedCount)++; + } + delete[] x; + delete[] y; + } + shp->Release(); + } + } + + if (transf) + { + OGRCoordinateTransformation::DestroyCT(transf); + transf = nullptr; + } + + // function result will be based on successful projection setting + vb = VARIANT_FALSE; + // if at least some rows were reprojected... + if (*reprojectedCount > 0) + { + // setting new projection + if (reprojectInPlace) + { + // vb result will be used to determine overall success + _geoProjection->CopyFrom(newProjection, &vb); + } + else + { + IGeoProjection* proj = nullptr; + (*retVal)->get_GeoProjection(&proj); + if (proj) + { + // vb result will be used to determine overall success + proj->CopyFrom(newProjection, &vb); + proj->Release(); + } + } + } + + // inserted shapes were marked as modified, correct this + if (reprojectInPlace) + ShapefileHelper::ClearShapefileModifiedFlag(this); + else + ShapefileHelper::ClearShapefileModifiedFlag(*retVal); + + // -------------------------------------- + // Output validation + // -------------------------------------- + CallbackHelper::ProgressCompleted(_globalCallback, _key); + + if (!reprojectInPlace) + { + this->ValidateOutput(retVal, "Reproject/ReprojectInPlace", "Shapefile", false); + } + else + { + this->ValidateOutput(this, "Reproject/ReprojectInPlace", "Shapefile", false); + } + + // it's critical to set correct projection, so false will be returned if it wasn't done + return vb != 0; +} +#pragma endregion + +// ***************************************************************** +// FixUpShapes() +// ***************************************************************** +STDMETHODIMP CShapefile::FixUpShapes(IShapefile** retVal, VARIANT_BOOL* fixed) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + // MWGIS-90: default to all shapes: + FixUpShapes2(VARIANT_FALSE, retVal, fixed); + + return S_OK; +} + +// ********************************************************* +// FixUpShapes2() +// ********************************************************* +STDMETHODIMP CShapefile::FixUpShapes2(VARIANT_BOOL SelectedOnly, IShapefile** result, VARIANT_BOOL* fixed) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *fixed = VARIANT_FALSE; + + if (*result == nullptr) + { + Clone(result); + } + + *fixed = FixupShapesCore(SelectedOnly, *result); + + return S_OK; +} + +// ********************************************************* +// FixupShapesCore() +// ********************************************************* +VARIANT_BOOL CShapefile::FixupShapesCore(VARIANT_BOOL selectedOnly, IShapefile* result) +{ + if (!result) return VARIANT_FALSE; + + tkUnitsOfMeasure units; + _geoProjection->get_LinearUnits(&units); + + long numFields; + this->get_NumFields(&numFields); + + long percent = 0; + const int numShapes = _shapeData.size(); + // VARIANT_BOOL fixed = VARIANT_TRUE; + + for (int i = 0; i < numShapes; i++) + { + CallbackHelper::Progress(_globalCallback, i, numShapes, "Fixing...", _key, percent); + + if (!ShapeAvailable(i, selectedOnly)) + continue; + + IShape* shp = nullptr; + get_Shape(i, &shp); + if (!shp) + { + continue; + } + + IShape* shpNew = nullptr; + shp->FixUp2(units, &shpNew); + shp->Release(); + + // failed to fix the shape? skip it. + if (!shpNew) + { + CString s; + s.Format("Failed to fix shape: %d", i); + CallbackHelper::ErrorMsg("Shapefile", nullptr, "", s); + continue; + } + + long shapeIndex = 0; + result->get_NumShapes(&shapeIndex); + + VARIANT_BOOL vbretval = VARIANT_FALSE; + result->EditInsertShape(shpNew, &shapeIndex, &vbretval); + shpNew->Release(); + + if (vbretval) + { + // TODO: extract, it's definitely used in other methods as well + CComVariant var; + for (int iFld = 0; iFld < numFields; iFld++) + { + get_CellValue(iFld, i, &var); + result->EditCellValue(iFld, shapeIndex, var, &vbretval); + } + } + } + + CallbackHelper::ProgressCompleted(_globalCallback, _key); + + return VARIANT_TRUE; +} + +// ********************************************************* +// GetRelatedShapes() +// ********************************************************* +STDMETHODIMP CShapefile::GetRelatedShapes(long referenceIndex, tkSpatialRelation relation, VARIANT* resultArray, + VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = VARIANT_FALSE; + if (referenceIndex < 0 || referenceIndex > (long)_shapeData.size()) + { + this->ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + return S_OK; + } + + IShape* shp = nullptr; + this->get_Shape(referenceIndex, &shp); + if (shp) + { + this->GetRelatedShapeCore(shp, referenceIndex, relation, resultArray, retval); + shp->Release(); + } + return S_OK; +} + +// ********************************************************* +// GetRelatedShapes2() +// ********************************************************* +STDMETHODIMP CShapefile::GetRelatedShapes2(IShape* referenceShape, tkSpatialRelation relation, VARIANT* resultArray, + VARIANT_BOOL* retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retval = VARIANT_FALSE; + if (!referenceShape) + { + this->ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + return S_OK; + } + + this->GetRelatedShapeCore(referenceShape, -1, relation, resultArray, retval); + return S_OK; +} + +// ********************************************************* +// GetRelatedShapeCore() +// ********************************************************* +void CShapefile::GetRelatedShapeCore(IShape* referenceShape, long referenceIndex, tkSpatialRelation relation, + VARIANT* resultArray, VARIANT_BOOL* retval) +{ + if (relation == srDisjoint) + { + // TODO: implement + ErrorMessage(tkMETHOD_NOT_IMPLEMENTED); + return; + } + + // rather than generate geometries for all shapes, + // only generate for those within qtree extent (see below) + //this->ReadGeosGeometries(VARIANT_FALSE); + + // turns on the quad tree + VARIANT_BOOL useQTree = VARIANT_FALSE; + this->get_UseQTree(&useQTree); + if (!useQTree) this->put_UseQTree(VARIANT_TRUE); + + double xMin, xMax, yMin, yMax; + if (((CShape*)referenceShape)->get_ExtentsXY(xMin, yMin, xMax, yMax)) + { + const QTreeExtent query(xMin, xMax, yMax, yMin); + std::vector shapes = this->_qtree->GetNodes(query); + std::vector arr; + + // generate GEOS geometries only for shapes within qtree extent + for (size_t i = 0; i < shapes.size(); i++) + // minimize work by 'select'ing necessary shapes + this->put_ShapeSelected(shapes[i], VARIANT_TRUE); + // now generate only for 'select'ed shapes + this->ReadGeosGeometries(VARIANT_TRUE); + // don't leave shapes 'select'ed + for (size_t i = 0; i < shapes.size(); i++) + this->put_ShapeSelected(shapes[i], VARIANT_FALSE); + + GEOSGeom geomBase; + if (referenceIndex > 0) + { + geomBase = _shapeData[referenceIndex]->geosGeom; + } + else + { + geomBase = GeosConverter::ShapeToGeom(referenceShape); + } + + if (geomBase) + { + for (size_t i = 0; i < shapes.size(); i++) + { + if (i == referenceIndex) + continue; // it doesn't make sense to compare the shape with itself + + // ReSharper disable once CppLocalVariableMayBeConst + GEOSGeom geom = _shapeData[shapes[i]]->geosGeom; + if (geom != nullptr) + { + char res = 0; + switch (relation) + { + case srContains: res = GeosHelper::Contains(geomBase, geom); + break; + case srCrosses: res = GeosHelper::Crosses(geomBase, geom); + break; + case srEquals: res = GeosHelper::Equals(geomBase, geom); + break; + case srIntersects: res = GeosHelper::Intersects(geomBase, geom); + break; + case srOverlaps: res = GeosHelper::Overlaps(geomBase, geom); + break; + case srTouches: res = GeosHelper::Touches(geomBase, geom); + break; + case srWithin: res = GeosHelper::Within(geomBase, geom); + break; + case srDisjoint: break; + default: ; + } + if (res) + { + arr.push_back(shapes[i]); + } + } + } + + if (referenceIndex == -1) + GeosHelper::DestroyGeometry(geomBase); + // the geometry was created in this function so it must be destroyed + } + + *retval = Templates::Vector2SafeArray(&arr, VT_I4, resultArray); + } + + // Don't clear the list here as function may be called in a loop + //this->ClearCachedGeometries(); +} + +// *************************************************** +// get_Identifiable +// *************************************************** +STDMETHODIMP CShapefile::get_Identifiable(VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retVal = _hotTracking; + return S_OK; +} + +STDMETHODIMP CShapefile::put_Identifiable(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _hotTracking = newVal; + return S_OK; +} + +// ***************************************************************** +// EditAddField() +// ***************************************************************** +STDMETHODIMP CShapefile::EditAddField(BSTR name, FieldType type, int precision, int width, long* fieldIndex) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (!this->_table) + { + this->ErrorMessage(tkDBF_FILE_DOES_NOT_EXIST); + } + else + { + _table->EditAddField(name, type, precision, width, fieldIndex); + } + return S_OK; +} + +// ***************************************************************** +// EditAddShape() +// ***************************************************************** +STDMETHODIMP CShapefile::EditAddShape(IShape* shape, long* shapeIndex) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + VARIANT_BOOL retval; + *shapeIndex = _shapeData.size(); + + EditInsertShape(shape, shapeIndex, &retval); + + if (retval == VARIANT_FALSE) + *shapeIndex = -1; + + return S_OK; +} + +// ***************************************************************** +// GetClosestVertex() +// ***************************************************************** +STDMETHODIMP CShapefile::GetClosestVertex(double x, double y, double maxDistance, + long* shapeIndex, long* pointIndex, double* distance, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *retVal = VARIANT_FALSE; + *shapeIndex = -1; + *pointIndex = -1; + + bool result = false; + if (maxDistance <= 0.0) + { + // search through all shapefile + std::vector ids; + for (size_t i = 0; i < _shapeData.size(); i++) + { + ids.push_back(i); + } + result = ShapefileHelper::GetClosestPoint(this, x, y, maxDistance, ids, shapeIndex, pointIndex, *distance); + } + else + { + std::vector ids; + Extent box(x - maxDistance, x + maxDistance, y - maxDistance, y + maxDistance); + if (this->SelectShapesCore(box, 0.0, SelectMode::INTERSECTION, ids, false)) + { + result = ShapefileHelper::GetClosestPoint(this, x, y, maxDistance, ids, shapeIndex, pointIndex, *distance); + } + } + *retVal = result ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; +} + +// ***************************************************************** +// GetClosestSnapPosition() +// ***************************************************************** +STDMETHODIMP CShapefile::GetClosestSnapPosition(double x, double y, double maxDistance, + long* shapeIndex, double* fx, double* fy, double* distance, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *retVal = VARIANT_FALSE; + *shapeIndex = -1; + + bool result = false; + if (maxDistance <= 0.0) + { + // search through all shapefile + std::vector ids; + for (size_t i = 0; i < _shapeData.size(); i++) + { + ids.push_back(i); + } + result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance); + } + else + { + std::vector ids; + Extent box(x - maxDistance, x + maxDistance, y - maxDistance, y + maxDistance); + if (this->SelectShapesCore(box, 0.0, SelectMode::INTERSECTION, ids, false)) + { + result = ShapefileHelper::GetClosestSnapPosition(this, x, y, maxDistance, ids, shapeIndex, *fx, *fy, *distance); + } + } + *retVal = result ? VARIANT_TRUE : VARIANT_FALSE; + return S_OK; +} + +// ***************************************************************** +// HasInvalidShapes() +// ***************************************************************** +STDMETHODIMP CShapefile::HasInvalidShapes(VARIANT_BOOL* result) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *result = VARIANT_FALSE; + const int numShapes = _shapeData.size(); + + for (int i = 0; i < numShapes; i++) + { + IShape* shp = nullptr; + this->get_Shape(i, &shp); + + if (!shp) + { + *result = VARIANT_TRUE; + break; + } + + VARIANT_BOOL retval = VARIANT_TRUE; + shp->get_IsValid(&retval); + shp->Release(); + if (retval == VARIANT_FALSE) + { + *result = VARIANT_TRUE; + break; + } + } + return S_OK; +} + +// ***************************************************************** +// get_UndoList() +// ***************************************************************** +STDMETHODIMP CShapefile::get_UndoList(IUndoList** pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (_undoList) + _undoList->AddRef(); + *pVal = _undoList; + return S_OK; +} + +// ***************************************************************** +// Snappable() +// ***************************************************************** +STDMETHODIMP CShapefile::get_Snappable(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _snappable; + return S_OK; +} + +STDMETHODIMP CShapefile::put_Snappable(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _snappable = newVal; + return S_OK; +} + +// ***************************************************************** +// ShapefileType2D() +// ***************************************************************** +STDMETHODIMP CShapefile::get_ShapefileType2D(ShpfileType* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = ShapeUtility::Convert2D(_shpfiletype); + return S_OK; +} + +// ***************************************************************** +// FieldIndexByName() +// ***************************************************************** +STDMETHODIMP CShapefile::get_FieldIndexByName(BSTR FieldName, LONG* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _table->get_FieldIndexByName(FieldName, pVal); + return S_OK; +} + +// *************************************************** +// get_Selectable +// *************************************************** +STDMETHODIMP CShapefile::get_Selectable(VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retVal = _selectable; + return S_OK; +} + +STDMETHODIMP CShapefile::put_Selectable(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + _selectable = newVal; + return S_OK; +} + +// ***************************************************************** +// Move() +// ***************************************************************** +STDMETHODIMP CShapefile::Move(DOUBLE xProjOffset, DOUBLE yProjOffset, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retVal = VARIANT_FALSE; + if (_sourceType != sstInMemory) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + return S_OK; + } + long numShapes; + get_NumShapes(&numShapes); + for (long i = 0; i < numShapes; i++) + { + CComPtr shp = nullptr; + get_Shape(i, &shp); + if (shp) + { + shp->Move(xProjOffset, yProjOffset); + } + } + *retVal = VARIANT_TRUE; + return S_OK; +} + +// ***************************************************************** +// get_ShapeRendered() +// ***************************************************************** +STDMETHODIMP CShapefile::get_ShapeRendered(LONG ShapeIndex, VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *pVal = VARIANT_FALSE; + if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + *pVal = _shapeData[ShapeIndex]->wasRendered() ? VARIANT_TRUE : VARIANT_FALSE; + } + return S_OK; +} + +// ***************************************************************** +// MarkUndrawn() +// ***************************************************************** +void CShapefile::MarkUndrawn() +{ + for (auto& i : _shapeData) + { + i->wasRendered(false); + } +} + +// ************************************************************* +// SortField() +// ************************************************************* +STDMETHODIMP CShapefile::get_SortField(BSTR* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + USES_CONVERSION; + *pVal = OLE2BSTR(_sortField); + + return S_OK; +} + +STDMETHODIMP CShapefile::put_SortField(BSTR newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + SysFreeString(_sortField); + USES_CONVERSION; + _sortField = OLE2BSTR(newVal); + + _sortingChanged = true; + + if (_labels) + { + _labels->UpdateSizeField(); + } + + return S_OK; +} + +// ************************************************************* +// SortAscending() +// ************************************************************* +STDMETHODIMP CShapefile::get_SortAscending(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *pVal = _sortAscending; + + return S_OK; +} + +STDMETHODIMP CShapefile::put_SortAscending(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + _sortAscending = newVal; + _sortingChanged = true; + + return S_OK; +} + +// ************************************************************* +// UpdateSorting() +// ************************************************************* +STDMETHODIMP CShapefile::UpdateSortField() +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + // this will trigger rereading of the table on next redraw + _sortingChanged = true; + + return S_OK; +} + +// ************************************************************* +// GetSorting() +// ************************************************************* +bool CShapefile::GetSorting(vector** indices) +{ + *indices = nullptr; + + if (!_sortingChanged) + { + *indices = &_sorting; + return true; + } + + long fieldIndex; + get_FieldIndexByName(_sortField, &fieldIndex); + + if (fieldIndex == -1) + { + return false; + } + + if (!_table) + { + return false; + } + + _sortingChanged = false; + + if (((CTableClass*)_table)->GetSorting(fieldIndex, _sorting)) + { + if (!_sortAscending) + { + std::reverse(_sorting.begin(), _sorting.end()); + } + + *indices = &_sorting; + return true; + } + CallbackHelper::ErrorMsg("Failed to sort labels"); + + return false; +} diff --git a/src/COM classes/Shapefile.h b/src/COM classes/Shapefile.h index 6cab7240..46f1acb6 100644 --- a/src/COM classes/Shapefile.h +++ b/src/COM classes/Shapefile.h @@ -487,7 +487,6 @@ class ATL_NO_VTABLE CShapefile : bool GetSorting(vector** indices); public: - ::CCriticalSection ShapefileLock; // geoprocessing methods VARIANT_BOOL FixupShapesCore(VARIANT_BOOL selectedOnly, IShapefile* result); VARIANT_BOOL BufferByDistanceCore(double Distance, LONG nSegments, VARIANT_BOOL SelectedOnly, VARIANT_BOOL MergeResults, IShapefile* result); diff --git a/src/COM classes/Shapefile_Edit.cpp b/src/COM classes/Shapefile_Edit.cpp index a6e91826..9b992e4d 100644 --- a/src/COM classes/Shapefile_Edit.cpp +++ b/src/COM classes/Shapefile_Edit.cpp @@ -1,1177 +1,1172 @@ -//******************************************************************************************************** -//File name: Shapefile.cpp -//Description: Implementation of the CShapefile (see other cpp files as well) -//******************************************************************************************************** -//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); -//you may not use this file except in compliance with the License. You may obtain a copy of the License at -//http://www.mozilla.org/MPL/ -//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF -//ANY KIND, either express or implied. See the License for the specific language governing rights and -//limitations under the License. -// -//The Original Code is MapWindow Open Source. -// -//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by -//Utah State University and the Idaho National Engineering and Environmental Lab that were released as -//public domain in March 2004. -// -//Contributor(s): (Open source contributors should list themselves and their modifications here). -// ------------------------------------------------------------------------------------------------------- -// lsu 3-02-2011: split the initial Shapefile.cpp file to make entities of the reasonable size -#pragma once -#include "stdafx.h" -#include "Shapefile.h" -#include "TableClass.h" -#include "Charts.h" -#include "Shape.h" -#include "ShapeHelper.h" - -#pragma region StartEditing - -// ************************************************************ -// StartEditingShapes() -// ************************************************************ -STDMETHODIMP CShapefile::StartEditingShapes(VARIANT_BOOL StartEditTable, ICallback *cBack, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - if (_appendMode) { - StopAppendMode(); - } - - bool callbackIsNull = (_globalCallback == NULL); - if(cBack != NULL && _globalCallback == NULL) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - if( _table == NULL || _sourceType == sstUninitialized) - { - ErrorMessage(tkSHAPEFILE_UNINITIALIZED); - return S_OK; - } - else if( _isEditingShapes ) - { - *retval = VARIANT_TRUE; - return S_OK; - } - else if (_writing) - { - ErrorMessage(tkSHP_READ_VIOLATION); - return S_OK; - } - - double xMin, xMax, yMin, yMax, zMin, zMax; - this->ClearQTree(&xMin, &xMax, &yMin, &yMax, &zMin, &zMax); - - // reading shapes into memory - IShape * shp = NULL; - _lastErrorCode = tkNO_ERROR; - long percent = 0, newpercent = 0; - - int size = (int)_shapeData.size(); - for( int i = 0; i < size; i++) - { - get_Shape(i, &shp); - - if( _lastErrorCode != tkNO_ERROR ) - { - ErrorMessage(_lastErrorCode); - ReleaseMemoryShapes(); - return S_OK; - } - - _shapeData[i]->shape = shp; - _shapeData[i]->originalIndex = i; - - if(_useQTree) - { - QuickExtentsCore(i, &xMin, &yMin, &xMax, &yMax); - - QTreeNode node; - node.Extent.left = xMin; - node.Extent.right= xMax; - node.Extent.top = yMax; - node.Extent.bottom = yMin; - node.index = i; - _qtree->AddNode(node); - } - - CallbackHelper::Progress(_globalCallback, i, size, "Reading shapes into memory", _key, percent); - } - CallbackHelper::ProgressCompleted(_globalCallback); - - *retval = VARIANT_TRUE; - - // it's used in the disk based mode only - ReleaseRenderingCache(); - - // ------------------------------------------ - // reading table into memory - // ------------------------------------------ - if(StartEditTable != VARIANT_FALSE) - { - StartEditingTable(_globalCallback, retval); - } - - if (*retval == VARIANT_FALSE) - { - ErrorMessage(_table->get_LastErrorCode(&_lastErrorCode)); - ReleaseMemoryShapes(); - } - else - { - _isEditingShapes = TRUE; - } - - if (callbackIsNull) { - _globalCallback = NULL; - } - return S_OK; -} - -#pragma endregion - -#pragma region StopEditing - -// ******************************************************** -// StopEditingShapes() -// ******************************************************** -STDMETHODIMP CShapefile::StopEditingShapes(VARIANT_BOOL ApplyChanges, VARIANT_BOOL StopEditTable, ICallback *cBack, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - if (!_globalCallback && cBack) - put_GlobalCallback(cBack); - - if( _table == NULL || _sourceType == sstUninitialized) - return S_OK; // don't report anything as StopEditingShapes will be called from Close for any InMemoryShapefile - - if( _isEditingShapes == FALSE ) - { - *retval = VARIANT_TRUE; - return S_OK; - } - - if ( _writing ) - { - ErrorMessage(tkSHP_WRITE_VIOLATION, cBack); - return S_OK; - } - - if ( _sourceType == sstInMemory ) - { - // shapefile wasn't saved before - if(_shpfileName.GetLength() > 0) - { - Save(cBack, retval); - - if (*retval) - { - _isEditingShapes = VARIANT_FALSE; - - if (StopEditTable) - { - StopEditingTable(ApplyChanges, cBack, retval); - } - } - } - *retval = VARIANT_TRUE; - return S_OK; - } - - USES_CONVERSION; - - if( ApplyChanges ) - { - _writing = true; - - // verify Shapefile Integrity - if( VerifyMemShapes(cBack) == FALSE ) - { - // error Code is set in function - } - else - { - _shpfile = _wfreopen(_shpfileName, L"wb+", _shpfile); - _shxfile = _wfreopen(_shxfileName, L"wb+",_shxfile); - - if( _shpfile == NULL || _shxfile == NULL ) - { - if( _shxfile != NULL ) - { - fclose( _shxfile ); - _shxfile = NULL; - - } - if( _shpfile != NULL ) - { - fclose( _shpfile ); - _shpfile = NULL; - ErrorMessage(tkCANT_OPEN_SHP, cBack); - } - } - else - { - // force computation of Extents - VARIANT_BOOL vbretval; - this->RefreshExtents(&vbretval); - - WriteShp(_shpfile,cBack); - WriteShx(_shxfile,cBack); - - _shpfile = _wfreopen(_shpfileName,L"rb+", _shpfile); - _shxfile = _wfreopen(_shxfileName,L"rb+",_shxfile); - - if( _shpfile == NULL || _shxfile == NULL ) - { - if( _shxfile != NULL ) - { - fclose( _shxfile ); - _shxfile = NULL; - ErrorMessage(tkCANT_OPEN_SHX, cBack); - } - if( _shpfile != NULL ) - { - fclose( _shpfile ); - _shpfile = NULL; - ErrorMessage(tkCANT_OPEN_SHP, cBack); - } - } - else - { - _isEditingShapes = FALSE; - ReleaseMemoryShapes(); - *retval = VARIANT_TRUE; - - if(StopEditTable != VARIANT_FALSE) - StopEditingTable(ApplyChanges,cBack,retval); - - // remove disk-based index, it's no longer valid - VARIANT_BOOL spatialIndex; - get_HasSpatialIndex(&spatialIndex); - - if (spatialIndex) { - VARIANT_BOOL vb; - RemoveSpatialIndex(&vb); - - CComBSTR bstr(_shpfileName); - CreateSpatialIndex(bstr, &vb); - } - } - } - } - _writing = false; - } - else - { - // discard the changes - _isEditingShapes = FALSE; - ReleaseMemoryShapes(); - - // reload the shx file - this->ReadShx(); - - if(StopEditTable != VARIANT_FALSE) - { - StopEditingTable(ApplyChanges,cBack,retval); - } - - RestoreShapeRecordsMapping(); - - *retval = VARIANT_TRUE; - } - - return S_OK; -} - -// *********************************************************** -// RestoreShapeRecordsMapping() -// *********************************************************** -void CShapefile::RestoreShapeRecordsMapping() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // if in memory records still match the disk ones - bool clearRecords = _shpOffsets.size() != _shapeData.size(); - for (size_t i = 0; i < _shapeData.size(); i++) - { - if (_shapeData[i]->originalIndex != i) { - clearRecords = true; - break; - } - } - - // clear in-memory shape records as mapping between disk shapefile and in-memory one is lost - if (clearRecords) - { - for (unsigned int i = 0; i < _shapeData.size(); i++) - delete _shapeData[i]; // all the releasing done in the destructor - _shapeData.clear(); - _shapeData.reserve(_shpOffsets.size()); - for (size_t i = 0; i < _shpOffsets.size(); i++) - { - _shapeData.push_back(new ShapeRecord()); - } - - // reapply categories - long categoriesCount; - _categories->get_Count(&categoriesCount); - if (categoriesCount > 0) { - _categories->ApplyExpressions(); - } - } -} - -#pragma endregion - -#pragma region Operations - -// *********************************************************** -// RegisterNewShape() -// *********************************************************** -// Must be called after inserting or swapping shape in shape vector -void CShapefile::RegisterNewShape(IShape* Shape, long ShapeIndex) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // shape must have correct underlying data structure - if ((_fastMode ? true : false) != ((CShape*)Shape)->get_fastMode()) - { - ((CShape*)Shape)->put_FastMode(_fastMode ? true : false); - } - - // updating labels and charts - if (_table) - { - double x = 0.0, y = 0.0, rotation = 0.0; - VARIANT_BOOL vbretval; - - VARIANT_BOOL bSynchronized; - _labels->get_Synchronized(&bSynchronized); - - bool chartsExist = ((CCharts*)_charts)->GetChartsExist(); - if (bSynchronized || chartsExist) - { - // position - tkLabelPositioning positioning; - _labels->get_Positioning(&positioning); - - tkLineLabelOrientation orientation; - _labels->get_LineOrientation(&orientation); - - ((CShape*)Shape)->get_LabelPosition(positioning, x, y, rotation, orientation); - } - - if (bSynchronized) - { - // it doesn't make sense to recalculate expression as DBF cells are empty all the same - CComBSTR bstrText(""); - _labels->InsertLabel(ShapeIndex, bstrText, x, y, rotation, -1, &vbretval); - } - - if (chartsExist) - { - if (!_shapeData[ShapeIndex]->chart) - { - _shapeData[ShapeIndex]->chart = new CChartInfo(); - _shapeData[ShapeIndex]->chart->x = x; - _shapeData[ShapeIndex]->chart->y = y; - } - } - } - - _sortingChanged = true; - - // extending the bounds of the shapefile we don't care if the bounds became less - // it's necessary to call RefreshExtents in this case, for zoom to layer working right - if (!ShapeHelper::IsEmpty(Shape)) - { - CComPtr box = NULL; - Shape->get_Extents(&box); - double xm, ym, zm, xM, yM, zM; - box->GetBounds(&xm, &ym, &zm, &xM, &yM, &zM); - - if (_shapeData.size() == 1) - { - _minX = xm; - _maxX = xM; - _minY = ym; - _maxY = yM; - _minZ = zm; - _maxZ = zM; - } - else - { - if (xm < _minX) _minX = xm; - if (xM > _maxX) _maxX = xM; - if (ym < _minY) _minY = ym; - if (yM > _maxY) _maxY = yM; - if (zm < _minZ) _minZ = zm; - if (zM > _maxZ) _maxZ = zM; - } - - if (_useQTree) - { - QTreeNode node; - node.index = ShapeIndex; - node.Extent.left = xm; - node.Extent.right = xM; - node.Extent.top = yM; - node.Extent.bottom = ym; - _qtree->AddNode(node); - } - } -} - -// *********************************************************** -// EditUpdateShape() -// *********************************************************** -// Substitutes one shape with another without formal remove/add call, -// so that attribute table will be intact -STDMETHODIMP CShapefile::EditUpdateShape(long shapeIndex, IShape* shpNew, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - if (!_isEditingShapes) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - return S_OK; - } - - if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - return S_OK; - } - - ShpfileType shpType; - shpNew->get_ShapeType2D(&shpType); - if (shpType != ShapeUtility::Convert2D(_shpfiletype) && shpType != SHP_NULLSHAPE) - { - ErrorMessage(tkINCOMPATIBLE_SHAPE_TYPE); - return S_OK; - } - - ComHelper::SetRef(shpNew, (IDispatch**)&_shapeData[shapeIndex]->shape, false); - ReregisterShape(shapeIndex); - _shapeData[shapeIndex]->modified(true); - - *retval = VARIANT_TRUE; - return S_OK; - -} - -// *********************************************************** -// UpdateShapeCore() -// *********************************************************** -// should be called when geometry of shape changed -void CShapefile::ReregisterShape(int shapeIndex) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!_isEditingShapes) return; - - if (shapeIndex < 0 || shapeIndex >= (int)_shapeData.size()) - return; - - IShape* shp = _shapeData[shapeIndex]->shape; - - bool fastMode = _fastMode ? true : false; - if (fastMode != ((CShape*)shp)->get_fastMode()) - { - ((CShape*)shp)->put_FastMode(fastMode); - } - - IExtents * box; - shp->get_Extents(&box); - double xm,ym,zm,xM,yM,zM; - box->GetBounds(&xm,&ym,&zm,&xM,&yM,&zM); - box->Release(); - - if (_shapeData.size() == 1) - { - _minX = xm; - _maxX = xM; - _minY = ym; - _maxY = yM; - _minZ = zm; - _maxZ = zM; - } - else - { - if (xm < _minX) _minX = xm; - if (xM > _maxX) _maxX = xM; - if (ym < _minY) _minY = ym; - if (yM > _maxY) _maxY = yM; - if (zm < _minZ) _minZ = zm; - if (zM > _maxZ) _maxZ = zM; - } - - if(_useQTree) - { - _qtree->RemoveNode(shapeIndex); - - QTreeNode node; - node.index = shapeIndex; - node.Extent.left = xm; - node.Extent.right = xM; - node.Extent.top = yM; - node.Extent.bottom = ym; - _qtree->AddNode(node); - } -} - -// *********************************************************** -// EditInsertShape() -// *********************************************************** -STDMETHODIMP CShapefile::EditInsertShape(IShape *Shape, long *ShapeIndex, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - if( _table == NULL || _sourceType == sstUninitialized ) - { - ErrorMessage(tkSHAPEFILE_UNINITIALIZED); - return S_OK; - } - - bool canAppend = _appendMode && (*ShapeIndex) >= (long)_shapeData.size(); - - if (!_isEditingShapes && !canAppend) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - return S_OK; - } - - VARIANT_BOOL isEditingTable; - _table->get_EditingTable(&isEditingTable); - - if (!isEditingTable && !canAppend) - { - ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); - return S_OK; - } - - if (Shape == NULL) - { - ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); - return S_OK; - } - - ShpfileType shapetype; - Shape->get_ShapeType(&shapetype); - - // MWGIS-91 - bool areEqualTypes = shapetype == _shpfiletype; - if (!areEqualTypes){ - areEqualTypes = ShapeUtility::Convert2D(shapetype) == ShapeUtility::Convert2D(_shpfiletype); - } - - // if( shapetype != SHP_NULLSHAPE && shapetype != _shpfiletype) - if (shapetype != SHP_NULLSHAPE && !areEqualTypes) - { - ErrorMessage(tkINCOMPATIBLE_SHAPEFILE_TYPE); - return S_OK; - } - - if (_appendMode) { - WriteAppendedShape(); - } - - // wrong index will be corrected - if( *ShapeIndex < 0 ) - { - *ShapeIndex = 0; - } - else if( *ShapeIndex > (int)_shapeData.size() ) - { - *ShapeIndex = _shapeData.size(); - } - - _table->EditInsertRow( ShapeIndex, retval ); - - if( *retval == VARIANT_FALSE ) - { - _table->get_LastErrorCode(&_lastErrorCode); - ErrorMessage(_lastErrorCode); - } - else - { - ShapeRecord* data = new ShapeRecord(); - Shape->AddRef(); - data->shape = Shape; - data->modified(true); - _shapeData.insert(_shapeData.begin() + *ShapeIndex, data); - - if (_useQTree && !_qtree) - GenerateQTree(); - - RegisterNewShape(Shape, *ShapeIndex); - - *retval = VARIANT_TRUE; - } - - ((CTableClass*)_table)->set_IndexValue(*ShapeIndex); - - return S_OK; -} - -// ********************************************************************* -// WriteAppendedShape() -// ********************************************************************* -bool CShapefile::WriteAppendedShape() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!_appendMode || _shapeData.size() == 0) return false; - - if (_shapeData.size() == _appendStartShapeCount) return false; // no shapes were added - - ShapeRecord* record = _shapeData[_shapeData.size() - 1]; - if (!record->shape) return false; - - IShapeWrapper* wrapper = ((CShape*)record->shape)->get_ShapeWrapper(); - if (!wrapper) return false; - - // TODO: calculate based on previous values instead - fseek(_shpfile, 0, SEEK_END); - int offset = ftell(_shpfile); - - // update SHX file - AppendToShx(_shxfile, record->shape, offset); - - // update SHP file - AppendToShpFile(_shpfile, wrapper); - - // update DBF file - ((CTableClass*)_table)->WriteAppendedRow(); - - record->ReleaseShape(); - - return true; -} - -// ********************************************************************* -// EditDeleteShape() -// ********************************************************************* -STDMETHODIMP CShapefile::EditDeleteShape(long ShapeIndex, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; - - if( _table == NULL || _sourceType == sstUninitialized ) - { - ErrorMessage(tkSHAPEFILE_UNINITIALIZED); - } - else if(!_isEditingShapes) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - } - else - { - VARIANT_BOOL isEditingTable; - _table->get_EditingTable(&isEditingTable); - - if(!isEditingTable) - { - ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); - } - else if( ShapeIndex < 0 || ShapeIndex >= (int)_shapeData.size() ) - { - ErrorMessage(tkINDEX_OUT_OF_BOUNDS); - } - else - { - VARIANT_BOOL vbretval; - _table->EditDeleteRow( ShapeIndex, &vbretval); - - if(!vbretval) - { - _table->get_LastErrorCode(&_lastErrorCode); - ErrorMessage(_lastErrorCode); - } - else - { - VARIANT_BOOL bSynchronized; - _labels->get_Synchronized(&bSynchronized); - if (bSynchronized) - _labels->RemoveLabel(ShapeIndex, &vbretval); - - delete _shapeData[ShapeIndex]; - _shapeData.erase( _shapeData.begin() + ShapeIndex ); - - _sortingChanged = true; - - // TODO: why haven't we updated QTree? - *retval = VARIANT_TRUE; - } - } - } - return S_OK; -} - -// *********************************************************** -// EditClear() -// *********************************************************** -STDMETHODIMP CShapefile::EditClear(VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); - - *retval = VARIANT_FALSE; - - if (_table == NULL || _sourceType == sstUninitialized) - { - return S_OK; - } - - if( _isEditingShapes == FALSE ) - { - ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); - return S_OK; - } - - VARIANT_BOOL isEditingTable; - _table->get_EditingTable(&isEditingTable); - - if( isEditingTable == FALSE ) - { - ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); - } - else - { - // deleting the labels - VARIANT_BOOL bSynchronized; - _labels->get_Synchronized(&bSynchronized); - if (bSynchronized) - { - _labels->Clear(); - } - - _table->EditClear(retval); - if( *retval == VARIANT_FALSE ) - { - _table->get_LastErrorCode(&_lastErrorCode); - ErrorMessage(_lastErrorCode); - } - - for (unsigned int i = 0; i < _shapeData.size(); i++) - { - delete _shapeData[i]; // all the releasing done in the destructor - } - _shapeData.clear(); - - if (_useQTree) - { - this->GenerateQTree(); // will clear it - } - - _sortingChanged = true; - - *retval = VARIANT_TRUE; - } - - return S_OK; -} -#pragma endregion - -#pragma region CacheExtents -// **************************************************************** -// get_CacheExtents() -// **************************************************************** -STDMETHODIMP CShapefile::get_CacheExtents(VARIANT_BOOL * pVal) -{ // The property no longer used AFX_MANAGE_STATE(AfxGetStaticModuleState()); - *pVal = VARIANT_FALSE; - return S_OK; -} - -// **************************************************************** -// put_CacheExtents() -// **************************************************************** -STDMETHODIMP CShapefile::put_CacheExtents(VARIANT_BOOL newVal) +//******************************************************************************************************** +//File name: Shapefile.cpp +//Description: Implementation of the CShapefile (see other cpp files as well) +//******************************************************************************************************** +//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); +//you may not use this file except in compliance with the License. You may obtain a copy of the License at +//http://www.mozilla.org/MPL/ +//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF +//ANY KIND, either express or implied. See the License for the specific language governing rights and +//limitations under the License. +// +//The Original Code is MapWindow Open Source. +// +//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by +//Utah State University and the Idaho National Engineering and Environmental Lab that were released as +//public domain in March 2004. +// +//Contributor(s): (Open source contributors should list themselves and their modifications here). +// ------------------------------------------------------------------------------------------------------- +// lsu 3-02-2011: split the initial Shapefile.cpp file to make entities of the reasonable size +#pragma once +#include "stdafx.h" +#include "Shapefile.h" +#include "TableClass.h" +#include "Charts.h" +#include "Shape.h" +#include "ShapeHelper.h" + +#pragma region StartEditing + +// ************************************************************ +// StartEditingShapes() +// ************************************************************ +STDMETHODIMP CShapefile::StartEditingShapes(VARIANT_BOOL StartEditTable, ICallback *cBack, VARIANT_BOOL *retval) { - // The property no longer used - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - return S_OK; -} - -// ******************************************************************** -// RefreshExtents() -// ******************************************************************** -STDMETHODIMP CShapefile::RefreshExtents(VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); - - *retval = VARIANT_TRUE; - if (!_isEditingShapes) return S_OK; - - IExtents * box=NULL; - double Xmin, Ymin, Zmin, Mmin, Xmax, Ymax, Zmax, Mmax; - - _minX = 0.0, _maxX = 0.0; - _minY = 0.0, _maxY = 0.0; - _minZ = 0.0, _maxZ = 0.0; - _minM = 0.0, _maxM = 0.0; - - bool first = true; - for( int i = 0; i < (int)_shapeData.size(); i++ ) - { - if (ShapeHelper::IsEmpty(_shapeData[i]->shape)) - continue; - - CShape* shp = ((CShape*)_shapeData[i]->shape); - shp->get_ExtentsXYZM(Xmin, Ymin, Xmax, Ymax, Zmin, Zmax, Mmin, Mmax); - - // refresh shapefile extents - if (first) - { - _minX = Xmin, _maxX = Xmax; - _minY = Ymin, _maxY = Ymax; - _minZ = Zmin, _maxZ = Zmax; - _minM = Mmin, _maxM = Mmax; - first = false; - } - else - { if( Xmin < _minX ) _minX = Xmin; - if( Xmax > _maxX ) _maxX = Xmax; - if( Ymin < _minY ) _minY = Ymin; - if( Ymax > _maxY ) _maxY = Ymax; - if( Zmin < _minZ ) _minZ = Zmin; - if( Zmax > _maxZ ) _maxZ = Zmax; - if( Mmin < _minM ) _minM = Mmin; - if( Mmax > _maxM ) _maxM = Mmax; - } - } - return S_OK; -} - -// ******************************************************************** -// RefreshShapeExtents() -// ******************************************************************** -STDMETHODIMP CShapefile::RefreshShapeExtents(LONG ShapeId, VARIANT_BOOL *retval) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); - - // The method is no longer used - *retval = VARIANT_TRUE; - return S_OK; -} -#pragma endregion - -#pragma region Utilities -// ******************************************************************** -// ReleaseMemoryShapes() -// ******************************************************************** -BOOL CShapefile::ReleaseMemoryShapes() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - - int size = (int)_shapeData.size(); - for( int i = 0; i < size; i++ ) - { - if (_shapeData[i]->shape) - { - _shapeData[i]->shape->Release(); - _shapeData[i]->shape = NULL; - } - } - return S_OK; -} - -// **************************************************************** -// verifyMemShapes -// **************************************************************** -//Verify Shapefile Integrity -BOOL CShapefile::VerifyMemShapes(ICallback * cBack) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - ShpfileType shapetype; - long numPoints; - long numParts; - IPoint * firstPnt = NULL; - IPoint * lastPnt = NULL; - VARIANT_BOOL vbretval = VARIANT_FALSE; - - if (!_globalCallback && cBack) - { - _globalCallback = cBack; - _globalCallback->AddRef(); - } - - for( int i = 0; i < (int)_shapeData.size(); i++ ) - { - IShape* shp = _shapeData[i]->shape; - if ( !shp ) - continue; - - shp->get_ShapeType(&shapetype); - // MWGIS-91 - bool areEqualTypes = shapetype == _shpfiletype; - if (!areEqualTypes){ - areEqualTypes = ShapeUtility::Convert2D(shapetype) == ShapeUtility::Convert2D(_shpfiletype); - } - shp->get_NumPoints(&numPoints); - shp->get_NumParts(&numParts); - - if (shapetype != SHP_NULLSHAPE && !areEqualTypes) - { - - ErrorMessage(tkINCOMPATIBLE_SHAPE_TYPE); - return FALSE; - } - else if( shapetype == SHP_POINT || shapetype == SHP_POINTZ || shapetype == SHP_POINTM ) - { - if( numPoints == 0 ) - { - ShpfileType tmpshptype = SHP_NULLSHAPE; - shp->put_ShapeType(tmpshptype); - } - } - else if( shapetype == SHP_POLYLINE || shapetype == SHP_POLYLINEZ || shapetype == SHP_POLYLINEM ) - { - if( numPoints < 2 ) - { - ShpfileType tmpshptype = SHP_NULLSHAPE; - shp->put_ShapeType(tmpshptype); - } - else if( numParts == 0 ) - { - long partindex = 0; - shp->InsertPart(0,&partindex,&vbretval); - } - } - else if( shapetype == SHP_POLYGON || shapetype == SHP_POLYGONZ || shapetype == SHP_POLYGONM ) - { - if( numPoints < 3 ) - { - ShpfileType tmpshptype = SHP_NULLSHAPE; - shp->put_ShapeType(tmpshptype); - } - else - { - if( numParts == 0 ) - { - long partindex = 0; - shp->InsertPart(0,&partindex,&vbretval); - numParts = 1; - } - - //force the first and last point of a ring to be the same - long partOffset = 0; - for( int p = 0; p < numParts; p++ ) - { - long startRing; - shp->get_Part(p,&startRing); - long endRing = 0; - if( p == numParts - 1 ) - endRing = numPoints; - else - shp->get_Part(p+1,&endRing); - - if( startRing < 0 || startRing >= numPoints + partOffset ) - startRing = 0; - if( endRing < startRing || endRing >= numPoints + partOffset ) - endRing = numPoints + partOffset; - - shp->get_Point(startRing,&firstPnt); - shp->get_Point(endRing - 1,&lastPnt); - - double x1, y1, z1; - double x2, y2, z2; - - if ( firstPnt && lastPnt ) - { - firstPnt->get_X(&x1); - firstPnt->get_Y(&y1); - firstPnt->get_Z(&z1); - - lastPnt->get_X(&x2); - lastPnt->get_Y(&y2); - lastPnt->get_Z(&z2); - - // make sure first and last point are the same for each part - if( x1 != x2 || y1 != y2 || z1 != z2 ) - { - VARIANT_BOOL retval; - shp->InsertPoint(firstPnt, &endRing, &retval); - for( int t = p+1; t < numParts; t++ ) - { - shp->get_Part(t,&startRing); - shp->put_Part(t,startRing+1); - partOffset++; - } - } - } - if ( firstPnt ) - { - firstPnt->Release(); - firstPnt = NULL; - } - - if ( lastPnt ) - { - lastPnt->Release(); - lastPnt = NULL; - } - } - } - } - else if( shapetype == SHP_MULTIPOINT || shapetype == SHP_MULTIPOINTZ || shapetype == SHP_MULTIPOINTM ) - { - if( numPoints == 0 ) - { - ShpfileType tmpshptype = SHP_NULLSHAPE; - shp->put_ShapeType(tmpshptype); - } - } - } - return TRUE; -} -#pragma endregion - -// **************************************************************** -// get_InteractiveEditing -// **************************************************************** -STDMETHODIMP CShapefile::get_InteractiveEditing(VARIANT_BOOL* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _isEditingShapes && _interactiveEditing; - return S_OK; -} - -// **************************************************************** -// put_InteractiveEditing -// **************************************************************** -STDMETHODIMP CShapefile::put_InteractiveEditing(VARIANT_BOOL newVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); - if (!_isEditingShapes && newVal) - { - // start edit mode; naturally no interactive editing without it - StartEditingShapes(VARIANT_TRUE, NULL, &_interactiveEditing); - return S_OK; // error code in previous code - } - _interactiveEditing = newVal; // don't stop edit mode; only interactive mode was stopped - return S_OK; -} - -// **************************************************************** -// ReopenFiles -// **************************************************************** -bool CShapefile::ReopenFiles(bool writeMode) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (_sourceType != sstDiskBased) - { - return false; - } - - CStringW mode = writeMode ? L"rb+" : L"rb"; - - FILE* shpfile = _wfopen(_shpfileName, mode); - FILE* shxfile = _wfopen(_shxfileName, mode); - - if (!shpfile || !shxfile) - { - CallbackHelper::ErrorMsg("Failed to reopen shx/shp files."); - fclose(shpfile); - fclose(shxfile); - return false; - } - - fclose(_shpfile); - fclose(_shxfile); - - _shpfile = shpfile; - _shxfile = shxfile; - - return true; -} - -// **************************************************************** -// StartAppendMode -// **************************************************************** -STDMETHODIMP CShapefile::StartAppendMode(VARIANT_BOOL* retVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - - *retVal = VARIANT_FALSE; - - if (_sourceType != sstDiskBased) - { - ErrorMessage(tkAPPEND_MODE_NO_FILE); - return S_OK; - } - - if (!ReopenFiles(true)) - { - // error is reported in function - return S_OK; - } - - _appendStartShapeCount = _shapeData.size(); - - ((CTableClass*)_table)->StartAppendMode(); - - _appendMode = VARIANT_TRUE; - *retVal = VARIANT_TRUE; - - return S_OK; -} - -// **************************************************************** -// StopAppendMode -// **************************************************************** -STDMETHODIMP CShapefile::StopAppendMode() -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - - if (_appendMode ) - { - WriteAppendedShape(); - - // updating shx file length - fseek(_shxfile, 24, SEEK_SET); - int fileLength = HEADER_BYTES_16 + (int)_shapeData.size() * 4; // in 16 bit words - ShapeUtility::WriteBigEndian(_shxfile, fileLength); - - // bounds - fseek(_shxfile, 36, SEEK_SET); - WriteBounds(_shxfile); - fflush(_shxfile); - - // updating shp file length - fseek(_shpfile, 0, SEEK_END); - fileLength = ftell(_shpfile); - fseek(_shpfile, 24, SEEK_SET); - ShapeUtility::WriteBigEndian(_shpfile, fileLength / 2); - - // updating bounds - VARIANT_BOOL retVal; - RefreshExtents(&retVal); - - // bounds - fseek(_shpfile, 36, SEEK_SET); - WriteBounds(_shpfile); - fflush(_shpfile); - - // commit the last DBF record - ((CTableClass*)_table)->StopAppendMode(); - - _appendStartShapeCount = -1; - _appendMode = VARIANT_FALSE; - - ReopenFiles(false); - } - - return S_OK; -} - -// **************************************************************** -// get_AppendMode -// **************************************************************** -STDMETHODIMP CShapefile::get_AppendMode(VARIANT_BOOL* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - - *pVal = _appendMode; - - return S_OK; -} + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if (_appendMode) { + StopAppendMode(); + } + + bool callbackIsNull = (_globalCallback == NULL); + if(cBack != NULL && _globalCallback == NULL) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + if( _table == NULL || _sourceType == sstUninitialized) + { + ErrorMessage(tkSHAPEFILE_UNINITIALIZED); + return S_OK; + } + else if( _isEditingShapes ) + { + *retval = VARIANT_TRUE; + return S_OK; + } + else if (_writing) + { + ErrorMessage(tkSHP_READ_VIOLATION); + return S_OK; + } + + double xMin, xMax, yMin, yMax, zMin, zMax; + this->ClearQTree(&xMin, &xMax, &yMin, &yMax, &zMin, &zMax); + + // reading shapes into memory + IShape * shp = NULL; + _lastErrorCode = tkNO_ERROR; + long percent = 0, newpercent = 0; + + int size = (int)_shapeData.size(); + for( int i = 0; i < size; i++) + { + get_Shape(i, &shp); + + if( _lastErrorCode != tkNO_ERROR ) + { + ErrorMessage(_lastErrorCode); + ReleaseMemoryShapes(); + return S_OK; + } + + _shapeData[i]->shape = shp; + _shapeData[i]->originalIndex = i; + + if(_useQTree) + { + QuickExtentsCore(i, &xMin, &yMin, &xMax, &yMax); + + QTreeNode node; + node.Extent.left = xMin; + node.Extent.right= xMax; + node.Extent.top = yMax; + node.Extent.bottom = yMin; + node.index = i; + _qtree->AddNode(node); + } + + CallbackHelper::Progress(_globalCallback, i, size, "Reading shapes into memory", _key, percent); + } + CallbackHelper::ProgressCompleted(_globalCallback); + + *retval = VARIANT_TRUE; + + // it's used in the disk based mode only + ReleaseRenderingCache(); + + // ------------------------------------------ + // reading table into memory + // ------------------------------------------ + if(StartEditTable != VARIANT_FALSE) + { + StartEditingTable(_globalCallback, retval); + } + + if (*retval == VARIANT_FALSE) + { + ErrorMessage(_table->get_LastErrorCode(&_lastErrorCode)); + ReleaseMemoryShapes(); + } + else + { + _isEditingShapes = TRUE; + } + + if (callbackIsNull) { + _globalCallback = NULL; + } + return S_OK; +} + +#pragma endregion + +#pragma region StopEditing + +// ******************************************************** +// StopEditingShapes() +// ******************************************************** +STDMETHODIMP CShapefile::StopEditingShapes(VARIANT_BOOL ApplyChanges, VARIANT_BOOL StopEditTable, ICallback *cBack, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if (!_globalCallback && cBack) + put_GlobalCallback(cBack); + + if( _table == NULL || _sourceType == sstUninitialized) + return S_OK; // don't report anything as StopEditingShapes will be called from Close for any InMemoryShapefile + + if( _isEditingShapes == FALSE ) + { + *retval = VARIANT_TRUE; + return S_OK; + } + + if ( _writing ) + { + ErrorMessage(tkSHP_WRITE_VIOLATION, cBack); + return S_OK; + } + + if ( _sourceType == sstInMemory ) + { + // shapefile wasn't saved before + if(_shpfileName.GetLength() > 0) + { + Save(cBack, retval); + + if (*retval) + { + _isEditingShapes = VARIANT_FALSE; + + if (StopEditTable) + { + StopEditingTable(ApplyChanges, cBack, retval); + } + } + } + *retval = VARIANT_TRUE; + return S_OK; + } + + USES_CONVERSION; + + if( ApplyChanges ) + { + _writing = true; + + // verify Shapefile Integrity + if( VerifyMemShapes(cBack) == FALSE ) + { + // error Code is set in function + } + else + { + _shpfile = _wfreopen(_shpfileName, L"wb+", _shpfile); + _shxfile = _wfreopen(_shxfileName, L"wb+",_shxfile); + + if( _shpfile == NULL || _shxfile == NULL ) + { + if( _shxfile != NULL ) + { + fclose( _shxfile ); + _shxfile = NULL; + + } + if( _shpfile != NULL ) + { + fclose( _shpfile ); + _shpfile = NULL; + ErrorMessage(tkCANT_OPEN_SHP, cBack); + } + } + else + { + // force computation of Extents + VARIANT_BOOL vbretval; + this->RefreshExtents(&vbretval); + + WriteShp(_shpfile,cBack); + WriteShx(_shxfile,cBack); + + _shpfile = _wfreopen(_shpfileName,L"rb+", _shpfile); + _shxfile = _wfreopen(_shxfileName,L"rb+",_shxfile); + + if( _shpfile == NULL || _shxfile == NULL ) + { + if( _shxfile != NULL ) + { + fclose( _shxfile ); + _shxfile = NULL; + ErrorMessage(tkCANT_OPEN_SHX, cBack); + } + if( _shpfile != NULL ) + { + fclose( _shpfile ); + _shpfile = NULL; + ErrorMessage(tkCANT_OPEN_SHP, cBack); + } + } + else + { + _isEditingShapes = FALSE; + ReleaseMemoryShapes(); + *retval = VARIANT_TRUE; + + if(StopEditTable != VARIANT_FALSE) + StopEditingTable(ApplyChanges,cBack,retval); + + // remove disk-based index, it's no longer valid + VARIANT_BOOL spatialIndex; + get_HasSpatialIndex(&spatialIndex); + + if (spatialIndex) { + VARIANT_BOOL vb; + RemoveSpatialIndex(&vb); + + CComBSTR bstr(_shpfileName); + CreateSpatialIndex(bstr, &vb); + } + } + } + } + _writing = false; + } + else + { + // discard the changes + _isEditingShapes = FALSE; + ReleaseMemoryShapes(); + + // reload the shx file + this->ReadShx(); + + if(StopEditTable != VARIANT_FALSE) + { + StopEditingTable(ApplyChanges,cBack,retval); + } + + RestoreShapeRecordsMapping(); + + *retval = VARIANT_TRUE; + } + + return S_OK; +} + +// *********************************************************** +// RestoreShapeRecordsMapping() +// *********************************************************** +void CShapefile::RestoreShapeRecordsMapping() +{ + // if in memory records still match the disk ones + bool clearRecords = _shpOffsets.size() != _shapeData.size(); + for (size_t i = 0; i < _shapeData.size(); i++) + { + if (_shapeData[i]->originalIndex != i) { + clearRecords = true; + break; + } + } + + // clear in-memory shape records as mapping between disk shapefile and in-memory one is lost + if (clearRecords) + { + for (unsigned int i = 0; i < _shapeData.size(); i++) + delete _shapeData[i]; // all the releasing done in the destructor + _shapeData.clear(); + _shapeData.reserve(_shpOffsets.size()); + for (size_t i = 0; i < _shpOffsets.size(); i++) + { + _shapeData.push_back(new ShapeRecord()); + } + + // reapply categories + long categoriesCount; + _categories->get_Count(&categoriesCount); + if (categoriesCount > 0) { + _categories->ApplyExpressions(); + } + } +} + +#pragma endregion + +#pragma region Operations + +// *********************************************************** +// RegisterNewShape() +// *********************************************************** +// Must be called after inserting or swapping shape in shape vector +void CShapefile::RegisterNewShape(IShape* Shape, long ShapeIndex) +{ + // shape must have correct underlying data structure + if ((_fastMode ? true : false) != ((CShape*)Shape)->get_fastMode()) + { + ((CShape*)Shape)->put_FastMode(_fastMode ? true : false); + } + + // updating labels and charts + if (_table) + { + double x = 0.0, y = 0.0, rotation = 0.0; + VARIANT_BOOL vbretval; + + VARIANT_BOOL bSynchronized; + _labels->get_Synchronized(&bSynchronized); + + bool chartsExist = ((CCharts*)_charts)->GetChartsExist(); + if (bSynchronized || chartsExist) + { + // position + tkLabelPositioning positioning; + _labels->get_Positioning(&positioning); + + tkLineLabelOrientation orientation; + _labels->get_LineOrientation(&orientation); + + ((CShape*)Shape)->get_LabelPosition(positioning, x, y, rotation, orientation); + } + + if (bSynchronized) + { + // it doesn't make sense to recalculate expression as DBF cells are empty all the same + CComBSTR bstrText(""); + _labels->InsertLabel(ShapeIndex, bstrText, x, y, rotation, -1, &vbretval); + } + + if (chartsExist) + { + if (!_shapeData[ShapeIndex]->chart) + { + _shapeData[ShapeIndex]->chart = new CChartInfo(); + _shapeData[ShapeIndex]->chart->x = x; + _shapeData[ShapeIndex]->chart->y = y; + } + } + } + + _sortingChanged = true; + + // extending the bounds of the shapefile we don't care if the bounds became less + // it's necessary to call RefreshExtents in this case, for zoom to layer working right + if (!ShapeHelper::IsEmpty(Shape)) + { + CComPtr box = NULL; + Shape->get_Extents(&box); + double xm, ym, zm, xM, yM, zM; + box->GetBounds(&xm, &ym, &zm, &xM, &yM, &zM); + + if (_shapeData.size() == 1) + { + _minX = xm; + _maxX = xM; + _minY = ym; + _maxY = yM; + _minZ = zm; + _maxZ = zM; + } + else + { + if (xm < _minX) _minX = xm; + if (xM > _maxX) _maxX = xM; + if (ym < _minY) _minY = ym; + if (yM > _maxY) _maxY = yM; + if (zm < _minZ) _minZ = zm; + if (zM > _maxZ) _maxZ = zM; + } + + if (_useQTree) + { + QTreeNode node; + node.index = ShapeIndex; + node.Extent.left = xm; + node.Extent.right = xM; + node.Extent.top = yM; + node.Extent.bottom = ym; + _qtree->AddNode(node); + } + } +} + +// *********************************************************** +// EditUpdateShape() +// *********************************************************** +// Substitutes one shape with another without formal remove/add call, +// so that attribute table will be intact +STDMETHODIMP CShapefile::EditUpdateShape(long shapeIndex, IShape* shpNew, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + if (!_isEditingShapes) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + return S_OK; + } + + if (shapeIndex < 0 || shapeIndex >= (long)_shapeData.size()) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + return S_OK; + } + + ShpfileType shpType; + shpNew->get_ShapeType2D(&shpType); + if (shpType != ShapeUtility::Convert2D(_shpfiletype) && shpType != SHP_NULLSHAPE) + { + ErrorMessage(tkINCOMPATIBLE_SHAPE_TYPE); + return S_OK; + } + + ComHelper::SetRef(shpNew, (IDispatch**)&_shapeData[shapeIndex]->shape, false); + ReregisterShape(shapeIndex); + _shapeData[shapeIndex]->modified(true); + + *retval = VARIANT_TRUE; + return S_OK; + +} + +// *********************************************************** +// UpdateShapeCore() +// *********************************************************** +// should be called when geometry of shape changed +void CShapefile::ReregisterShape(int shapeIndex) +{ + if (!_isEditingShapes) return; + + if (shapeIndex < 0 || shapeIndex >= (int)_shapeData.size()) + return; + + IShape* shp = _shapeData[shapeIndex]->shape; + + bool fastMode = _fastMode ? true : false; + if (fastMode != ((CShape*)shp)->get_fastMode()) + { + ((CShape*)shp)->put_FastMode(fastMode); + } + + IExtents * box; + shp->get_Extents(&box); + double xm,ym,zm,xM,yM,zM; + box->GetBounds(&xm,&ym,&zm,&xM,&yM,&zM); + box->Release(); + + if (_shapeData.size() == 1) + { + _minX = xm; + _maxX = xM; + _minY = ym; + _maxY = yM; + _minZ = zm; + _maxZ = zM; + } + else + { + if (xm < _minX) _minX = xm; + if (xM > _maxX) _maxX = xM; + if (ym < _minY) _minY = ym; + if (yM > _maxY) _maxY = yM; + if (zm < _minZ) _minZ = zm; + if (zM > _maxZ) _maxZ = zM; + } + + if(_useQTree) + { + _qtree->RemoveNode(shapeIndex); + + QTreeNode node; + node.index = shapeIndex; + node.Extent.left = xm; + node.Extent.right = xM; + node.Extent.top = yM; + node.Extent.bottom = ym; + _qtree->AddNode(node); + } +} + +// *********************************************************** +// EditInsertShape() +// *********************************************************** +STDMETHODIMP CShapefile::EditInsertShape(IShape *Shape, long *ShapeIndex, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if( _table == NULL || _sourceType == sstUninitialized ) + { + ErrorMessage(tkSHAPEFILE_UNINITIALIZED); + return S_OK; + } + + bool canAppend = _appendMode && (*ShapeIndex) >= (long)_shapeData.size(); + + if (!_isEditingShapes && !canAppend) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + return S_OK; + } + + VARIANT_BOOL isEditingTable; + _table->get_EditingTable(&isEditingTable); + + if (!isEditingTable && !canAppend) + { + ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); + return S_OK; + } + + if (Shape == NULL) + { + ErrorMessage(tkUNEXPECTED_NULL_PARAMETER); + return S_OK; + } + + ShpfileType shapetype; + Shape->get_ShapeType(&shapetype); + + // MWGIS-91 + bool areEqualTypes = shapetype == _shpfiletype; + if (!areEqualTypes){ + areEqualTypes = ShapeUtility::Convert2D(shapetype) == ShapeUtility::Convert2D(_shpfiletype); + } + + // if( shapetype != SHP_NULLSHAPE && shapetype != _shpfiletype) + if (shapetype != SHP_NULLSHAPE && !areEqualTypes) + { + ErrorMessage(tkINCOMPATIBLE_SHAPEFILE_TYPE); + return S_OK; + } + + if (_appendMode) { + WriteAppendedShape(); + } + + // wrong index will be corrected + if( *ShapeIndex < 0 ) + { + *ShapeIndex = 0; + } + else if( *ShapeIndex > (int)_shapeData.size() ) + { + *ShapeIndex = _shapeData.size(); + } + + _table->EditInsertRow( ShapeIndex, retval ); + + if( *retval == VARIANT_FALSE ) + { + _table->get_LastErrorCode(&_lastErrorCode); + ErrorMessage(_lastErrorCode); + } + else + { + ShapeRecord* data = new ShapeRecord(); + Shape->AddRef(); + data->shape = Shape; + data->modified(true); + _shapeData.insert(_shapeData.begin() + *ShapeIndex, data); + + if (_useQTree && !_qtree) + GenerateQTree(); + + RegisterNewShape(Shape, *ShapeIndex); + + *retval = VARIANT_TRUE; + } + + ((CTableClass*)_table)->set_IndexValue(*ShapeIndex); + + return S_OK; +} + +// ********************************************************************* +// WriteAppendedShape() +// ********************************************************************* +bool CShapefile::WriteAppendedShape() +{ + if (!_appendMode || _shapeData.size() == 0) return false; + + if (_shapeData.size() == _appendStartShapeCount) return false; // no shapes were added + + ShapeRecord* record = _shapeData[_shapeData.size() - 1]; + if (!record->shape) return false; + + IShapeWrapper* wrapper = ((CShape*)record->shape)->get_ShapeWrapper(); + if (!wrapper) return false; + + // TODO: calculate based on previous values instead + fseek(_shpfile, 0, SEEK_END); + int offset = ftell(_shpfile); + + // update SHX file + AppendToShx(_shxfile, record->shape, offset); + + // update SHP file + AppendToShpFile(_shpfile, wrapper); + + // update DBF file + ((CTableClass*)_table)->WriteAppendedRow(); + + record->ReleaseShape(); + + return true; +} + +// ********************************************************************* +// EditDeleteShape() +// ********************************************************************* +STDMETHODIMP CShapefile::EditDeleteShape(long ShapeIndex, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if( _table == NULL || _sourceType == sstUninitialized ) + { + ErrorMessage(tkSHAPEFILE_UNINITIALIZED); + } + else if(!_isEditingShapes) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + } + else + { + VARIANT_BOOL isEditingTable; + _table->get_EditingTable(&isEditingTable); + + if(!isEditingTable) + { + ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); + } + else if( ShapeIndex < 0 || ShapeIndex >= (int)_shapeData.size() ) + { + ErrorMessage(tkINDEX_OUT_OF_BOUNDS); + } + else + { + VARIANT_BOOL vbretval; + _table->EditDeleteRow( ShapeIndex, &vbretval); + + if(!vbretval) + { + _table->get_LastErrorCode(&_lastErrorCode); + ErrorMessage(_lastErrorCode); + } + else + { + VARIANT_BOOL bSynchronized; + _labels->get_Synchronized(&bSynchronized); + if (bSynchronized) + _labels->RemoveLabel(ShapeIndex, &vbretval); + + delete _shapeData[ShapeIndex]; + _shapeData.erase( _shapeData.begin() + ShapeIndex ); + + _sortingChanged = true; + + // TODO: why haven't we updated QTree? + *retval = VARIANT_TRUE; + } + } + } + return S_OK; +} + +// *********************************************************** +// EditClear() +// *********************************************************** +STDMETHODIMP CShapefile::EditClear(VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *retval = VARIANT_FALSE; + + if (_table == NULL || _sourceType == sstUninitialized) + { + return S_OK; + } + + if( _isEditingShapes == FALSE ) + { + ErrorMessage(tkSHPFILE_NOT_IN_EDIT_MODE); + return S_OK; + } + + VARIANT_BOOL isEditingTable; + _table->get_EditingTable(&isEditingTable); + + if( isEditingTable == FALSE ) + { + ErrorMessage(tkDBF_NOT_IN_EDIT_MODE); + } + else + { + // deleting the labels + VARIANT_BOOL bSynchronized; + _labels->get_Synchronized(&bSynchronized); + if (bSynchronized) + { + _labels->Clear(); + } + + _table->EditClear(retval); + if( *retval == VARIANT_FALSE ) + { + _table->get_LastErrorCode(&_lastErrorCode); + ErrorMessage(_lastErrorCode); + } + + for (unsigned int i = 0; i < _shapeData.size(); i++) + { + delete _shapeData[i]; // all the releasing done in the destructor + } + _shapeData.clear(); + + if (_useQTree) + { + this->GenerateQTree(); // will clear it + } + + _sortingChanged = true; + + *retval = VARIANT_TRUE; + } + + return S_OK; +} +#pragma endregion + +#pragma region CacheExtents +// **************************************************************** +// get_CacheExtents() +// **************************************************************** +STDMETHODIMP CShapefile::get_CacheExtents(VARIANT_BOOL * pVal) +{ + // The property no longer used + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = VARIANT_FALSE; + return S_OK; +} + +// **************************************************************** +// put_CacheExtents() +// **************************************************************** +STDMETHODIMP CShapefile::put_CacheExtents(VARIANT_BOOL newVal) +{ + // The property no longer used + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + return S_OK; +} + +// ******************************************************************** +// RefreshExtents() +// ******************************************************************** +STDMETHODIMP CShapefile::RefreshExtents(VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *retval = VARIANT_TRUE; + if (!_isEditingShapes) return S_OK; + + IExtents * box=NULL; + double Xmin, Ymin, Zmin, Mmin, Xmax, Ymax, Zmax, Mmax; + + _minX = 0.0, _maxX = 0.0; + _minY = 0.0, _maxY = 0.0; + _minZ = 0.0, _maxZ = 0.0; + _minM = 0.0, _maxM = 0.0; + + bool first = true; + for( int i = 0; i < (int)_shapeData.size(); i++ ) + { + if (ShapeHelper::IsEmpty(_shapeData[i]->shape)) + continue; + + CShape* shp = ((CShape*)_shapeData[i]->shape); + shp->get_ExtentsXYZM(Xmin, Ymin, Xmax, Ymax, Zmin, Zmax, Mmin, Mmax); + + // refresh shapefile extents + if (first) + { + _minX = Xmin, _maxX = Xmax; + _minY = Ymin, _maxY = Ymax; + _minZ = Zmin, _maxZ = Zmax; + _minM = Mmin, _maxM = Mmax; + first = false; + } + else + { if( Xmin < _minX ) _minX = Xmin; + if( Xmax > _maxX ) _maxX = Xmax; + if( Ymin < _minY ) _minY = Ymin; + if( Ymax > _maxY ) _maxY = Ymax; + if( Zmin < _minZ ) _minZ = Zmin; + if( Zmax > _maxZ ) _maxZ = Zmax; + if( Mmin < _minM ) _minM = Mmin; + if( Mmax > _maxM ) _maxM = Mmax; + } + } + return S_OK; +} + +// ******************************************************************** +// RefreshShapeExtents() +// ******************************************************************** +STDMETHODIMP CShapefile::RefreshShapeExtents(LONG ShapeId, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + // The method is no longer used + *retval = VARIANT_TRUE; + return S_OK; +} +#pragma endregion + +#pragma region Utilities +// ******************************************************************** +// ReleaseMemoryShapes() +// ******************************************************************** +BOOL CShapefile::ReleaseMemoryShapes() +{ + + int size = (int)_shapeData.size(); + for( int i = 0; i < size; i++ ) + { + if (_shapeData[i]->shape) + { + _shapeData[i]->shape->Release(); + _shapeData[i]->shape = NULL; + } + } + return S_OK; +} + +// **************************************************************** +// verifyMemShapes +// **************************************************************** +//Verify Shapefile Integrity +BOOL CShapefile::VerifyMemShapes(ICallback * cBack) +{ + ShpfileType shapetype; + long numPoints; + long numParts; + IPoint * firstPnt = NULL; + IPoint * lastPnt = NULL; + VARIANT_BOOL vbretval = VARIANT_FALSE; + + if (!_globalCallback && cBack) + { + _globalCallback = cBack; + _globalCallback->AddRef(); + } + + for( int i = 0; i < (int)_shapeData.size(); i++ ) + { + IShape* shp = _shapeData[i]->shape; + if ( !shp ) + continue; + + shp->get_ShapeType(&shapetype); + // MWGIS-91 + bool areEqualTypes = shapetype == _shpfiletype; + if (!areEqualTypes){ + areEqualTypes = ShapeUtility::Convert2D(shapetype) == ShapeUtility::Convert2D(_shpfiletype); + } + shp->get_NumPoints(&numPoints); + shp->get_NumParts(&numParts); + + if (shapetype != SHP_NULLSHAPE && !areEqualTypes) + { + + ErrorMessage(tkINCOMPATIBLE_SHAPE_TYPE); + return FALSE; + } + else if( shapetype == SHP_POINT || shapetype == SHP_POINTZ || shapetype == SHP_POINTM ) + { + if( numPoints == 0 ) + { + ShpfileType tmpshptype = SHP_NULLSHAPE; + shp->put_ShapeType(tmpshptype); + } + } + else if( shapetype == SHP_POLYLINE || shapetype == SHP_POLYLINEZ || shapetype == SHP_POLYLINEM ) + { + if( numPoints < 2 ) + { + ShpfileType tmpshptype = SHP_NULLSHAPE; + shp->put_ShapeType(tmpshptype); + } + else if( numParts == 0 ) + { + long partindex = 0; + shp->InsertPart(0,&partindex,&vbretval); + } + } + else if( shapetype == SHP_POLYGON || shapetype == SHP_POLYGONZ || shapetype == SHP_POLYGONM ) + { + if( numPoints < 3 ) + { + ShpfileType tmpshptype = SHP_NULLSHAPE; + shp->put_ShapeType(tmpshptype); + } + else + { + if( numParts == 0 ) + { + long partindex = 0; + shp->InsertPart(0,&partindex,&vbretval); + numParts = 1; + } + + //force the first and last point of a ring to be the same + long partOffset = 0; + for( int p = 0; p < numParts; p++ ) + { + long startRing; + shp->get_Part(p,&startRing); + long endRing = 0; + if( p == numParts - 1 ) + endRing = numPoints; + else + shp->get_Part(p+1,&endRing); + + if( startRing < 0 || startRing >= numPoints + partOffset ) + startRing = 0; + if( endRing < startRing || endRing >= numPoints + partOffset ) + endRing = numPoints + partOffset; + + shp->get_Point(startRing,&firstPnt); + shp->get_Point(endRing - 1,&lastPnt); + + double x1, y1, z1; + double x2, y2, z2; + + if ( firstPnt && lastPnt ) + { + firstPnt->get_X(&x1); + firstPnt->get_Y(&y1); + firstPnt->get_Z(&z1); + + lastPnt->get_X(&x2); + lastPnt->get_Y(&y2); + lastPnt->get_Z(&z2); + + // make sure first and last point are the same for each part + if( x1 != x2 || y1 != y2 || z1 != z2 ) + { + VARIANT_BOOL retval; + shp->InsertPoint(firstPnt, &endRing, &retval); + for( int t = p+1; t < numParts; t++ ) + { + shp->get_Part(t,&startRing); + shp->put_Part(t,startRing+1); + partOffset++; + } + } + } + if ( firstPnt ) + { + firstPnt->Release(); + firstPnt = NULL; + } + + if ( lastPnt ) + { + lastPnt->Release(); + lastPnt = NULL; + } + } + } + } + else if( shapetype == SHP_MULTIPOINT || shapetype == SHP_MULTIPOINTZ || shapetype == SHP_MULTIPOINTM ) + { + if( numPoints == 0 ) + { + ShpfileType tmpshptype = SHP_NULLSHAPE; + shp->put_ShapeType(tmpshptype); + } + } + } + return TRUE; +} +#pragma endregion + +// **************************************************************** +// get_InteractiveEditing +// **************************************************************** +STDMETHODIMP CShapefile::get_InteractiveEditing(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = _isEditingShapes && _interactiveEditing; + return S_OK; +} + +// **************************************************************** +// put_InteractiveEditing +// **************************************************************** +STDMETHODIMP CShapefile::put_InteractiveEditing(VARIANT_BOOL newVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (!_isEditingShapes && newVal) + { + // start edit mode; naturally no interactive editing without it + StartEditingShapes(VARIANT_TRUE, NULL, &_interactiveEditing); + return S_OK; // error code in previous code + } + _interactiveEditing = newVal; // don't stop edit mode; only interactive mode was stopped + return S_OK; +} + +// **************************************************************** +// ReopenFiles +// **************************************************************** +bool CShapefile::ReopenFiles(bool writeMode) +{ + if (_sourceType != sstDiskBased) + { + return false; + } + + CStringW mode = writeMode ? L"rb+" : L"rb"; + + FILE* shpfile = _wfopen(_shpfileName, mode); + FILE* shxfile = _wfopen(_shxfileName, mode); + + if (!shpfile || !shxfile) + { + CallbackHelper::ErrorMsg("Failed to reopen shx/shp files."); + fclose(shpfile); + fclose(shxfile); + return false; + } + + fclose(_shpfile); + fclose(_shxfile); + + _shpfile = shpfile; + _shxfile = shxfile; + + return true; +} + +// **************************************************************** +// StartAppendMode +// **************************************************************** +STDMETHODIMP CShapefile::StartAppendMode(VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *retVal = VARIANT_FALSE; + + if (_sourceType != sstDiskBased) + { + ErrorMessage(tkAPPEND_MODE_NO_FILE); + return S_OK; + } + + if (!ReopenFiles(true)) + { + // error is reported in function + return S_OK; + } + + _appendStartShapeCount = _shapeData.size(); + + ((CTableClass*)_table)->StartAppendMode(); + + _appendMode = VARIANT_TRUE; + *retVal = VARIANT_TRUE; + + return S_OK; +} + +// **************************************************************** +// StopAppendMode +// **************************************************************** +STDMETHODIMP CShapefile::StopAppendMode() +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + if (_appendMode ) + { + WriteAppendedShape(); + + // updating shx file length + fseek(_shxfile, 24, SEEK_SET); + int fileLength = HEADER_BYTES_16 + (int)_shapeData.size() * 4; // in 16 bit words + ShapeUtility::WriteBigEndian(_shxfile, fileLength); + + // bounds + fseek(_shxfile, 36, SEEK_SET); + WriteBounds(_shxfile); + fflush(_shxfile); + + // updating shp file length + fseek(_shpfile, 0, SEEK_END); + fileLength = ftell(_shpfile); + fseek(_shpfile, 24, SEEK_SET); + ShapeUtility::WriteBigEndian(_shpfile, fileLength / 2); + + // updating bounds + VARIANT_BOOL retVal; + RefreshExtents(&retVal); + + // bounds + fseek(_shpfile, 36, SEEK_SET); + WriteBounds(_shpfile); + fflush(_shpfile); + + // commit the last DBF record + ((CTableClass*)_table)->StopAppendMode(); + + _appendStartShapeCount = -1; + _appendMode = VARIANT_FALSE; + + ReopenFiles(false); + } + + return S_OK; +} + +// **************************************************************** +// get_AppendMode +// **************************************************************** +STDMETHODIMP CShapefile::get_AppendMode(VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *pVal = _appendMode; + + return S_OK; +} diff --git a/src/COM classes/Shapefile_Geoprocessing.cpp b/src/COM classes/Shapefile_Geoprocessing.cpp index c730a43e..4ddde33a 100644 --- a/src/COM classes/Shapefile_Geoprocessing.cpp +++ b/src/COM classes/Shapefile_Geoprocessing.cpp @@ -80,11 +80,6 @@ void CShapefile::InsertShapesVector(IShapefile* sf, vector& vShapes, IShapefile* sfSubject, long subjectId, std::map* fieldMapSubject, IShapefile* sfClip, long clipId, std::map* fieldMapClip) { - if (!sf || !sfSubject) return; - - CSingleLock sfLock(&((CShapefile*) sf)->ShapefileLock, TRUE); - CSingleLock sfSubjectLock(&((CShapefile*) sfSubject)->ShapefileLock, TRUE); - long numFieldSubject, numFieldsClip; sfSubject->get_NumFields(&numFieldSubject); if (sfClip) @@ -183,10 +178,6 @@ void CShapefile::InsertShapesVector(IShapefile* sf, vector& vShapes, // initShapeIndex - the index of shape to copy the attribute from bool InsertGeosGeometry(IShapefile* sfTarget, GEOSGeometry* gsNew, IShapefile* sfSouce, int initShapeIndex) { - if (!sfTarget || !sfSouce) return false; - - CSingleLock sfTargetLock(&((CShapefile*)sfTarget)->ShapefileLock, TRUE); - CSingleLock sfSourceLock(&((CShapefile*)sfSouce)->ShapefileLock, TRUE); if (gsNew) { ShpfileType shpType; @@ -229,10 +220,6 @@ bool InsertGeosGeometry(IShapefile* sfTarget, GEOSGeometry* gsNew, IShapefile* s // The row index of attribute table are taken from the key property of the shape void CopyShape(IShapefile* sfSource, IShape* shp, IShapefile* sfResult) { - if (!sfSource || !sfResult) return; - - CSingleLock sfSourceLock(&((CShapefile*)sfSource)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); if (shp) { USES_CONVERSION; @@ -293,7 +280,6 @@ STDMETHODIMP CShapefile::SelectByShapefile(IShapefile* sf, tkSpatialRelation Rel { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock mySfLock(&ShapefileLock, TRUE); USES_CONVERSION; *retval = VARIANT_FALSE; @@ -309,8 +295,6 @@ STDMETHODIMP CShapefile::SelectByShapefile(IShapefile* sf, tkSpatialRelation Rel return S_OK; } - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - long _numShapes2; const long _numShapes1 = _shapeData.size(); sf->get_NumShapes(&_numShapes2); @@ -452,7 +436,6 @@ STDMETHODIMP CShapefile::SelectByShapefile(IShapefile* sf, tkSpatialRelation Rel VARIANT_BOOL CShapefile::SelectShapesAlt(IExtents* BoundBox, double Tolerance, SelectMode SelectMode, VARIANT* arr) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); double xMin, xMax, yMin, yMax, zMin, zMax; BoundBox->GetBounds(&xMin, &yMin, &zMin, &xMax, &yMax, &zMax); @@ -524,9 +507,6 @@ VARIANT_BOOL CShapefile::SelectShapesAlt(IExtents* BoundBox, double Tolerance, S STDMETHODIMP CShapefile::Dissolve(long FieldIndex, VARIANT_BOOL SelectedOnly, IShapefile** sf) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!*sf) return S_OK; - CSingleLock sfLock(&((CShapefile*)*sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); DissolveCore(FieldIndex, SelectedOnly, nullptr, sf); return S_OK; } @@ -538,9 +518,6 @@ STDMETHODIMP CShapefile::DissolveWithStats(long FieldIndex, VARIANT_BOOL Selecte IFieldStatOperations* statOperations, IShapefile** sf) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!*sf) return S_OK; - CSingleLock sfLock(&((CShapefile*)*sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); DissolveCore(FieldIndex, SelectedOnly, statOperations, sf); return S_OK; } @@ -553,9 +530,6 @@ STDMETHODIMP CShapefile::DissolveWithStats(long FieldIndex, VARIANT_BOOL Selecte void CShapefile::DissolveCore(long FieldIndex, VARIANT_BOOL SelectedOnly, IFieldStatOperations* operations, IShapefile** sf) { - if (!*sf) return; - CSingleLock sfLock(&((CShapefile*)*sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); // ---------------------------------------------- // Validation // ---------------------------------------------- @@ -646,9 +620,6 @@ char* GetStatOperationName(tkFieldStatOperation op) void CShapefile::CalculateFieldStats(map*>& fieldMap, IFieldStatOperations* ioperations, IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); // -------------------------------------------- // validating operations // -------------------------------------------- @@ -872,9 +843,6 @@ void CShapefile::CalculateFieldStats(map*>& fieldMap, IFieldSta void CShapefile::DissolveGEOS(long FieldIndex, VARIANT_BOOL SelectedOnly, IFieldStatOperations* operations, IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); map*> fieldMap; // index in output, indices in input map*> indicesMap; // value in input, indices in input map*> shapeMap; @@ -1006,9 +974,6 @@ void CShapefile::DissolveGEOS(long FieldIndex, VARIANT_BOOL SelectedOnly, IField void CShapefile::DissolveClipper(long FieldIndex, VARIANT_BOOL SelectedOnly, IFieldStatOperations* operations, IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); map*> fieldMap; // index in output, indices in input map*> indicesMap; // value in input, indices in input map shapeMap; @@ -1148,7 +1113,6 @@ STDMETHODIMP CShapefile::AggregateShapesWithStats(VARIANT_BOOL SelectedOnly, LON IFieldStatOperations* statOperations, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); AggregateShapesCore(SelectedOnly, FieldIndex, statOperations, retval); return S_OK; } @@ -1159,7 +1123,6 @@ STDMETHODIMP CShapefile::AggregateShapesWithStats(VARIANT_BOOL SelectedOnly, LON STDMETHODIMP CShapefile::AggregateShapes(VARIANT_BOOL SelectedOnly, LONG FieldIndex, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); AggregateShapesCore(SelectedOnly, FieldIndex, nullptr, retval); return S_OK; } @@ -1171,9 +1134,6 @@ STDMETHODIMP CShapefile::AggregateShapes(VARIANT_BOOL SelectedOnly, LONG FieldIn void CShapefile::AggregateShapesCore(VARIANT_BOOL SelectedOnly, LONG FieldIndex, IFieldStatOperations* operations, IShapefile** retval) { - if (!*retval) return; - CSingleLock sfLock(&((CShapefile*)*retval)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); long numFields; this->get_NumFields(&numFields); @@ -1422,10 +1382,6 @@ STDMETHODIMP CShapefile::BufferByDistance(double Distance, LONG nSegments, VARIA VARIANT_BOOL MergeResults, IShapefile** sf) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!*sf) return S_OK; - - CSingleLock sfLock(&((CShapefile*) *sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); if (MergeResults) { @@ -1464,9 +1420,6 @@ STDMETHODIMP CShapefile::BufferByDistance(double Distance, LONG nSegments, VARIA VARIANT_BOOL CShapefile::BufferByDistanceCore(double Distance, LONG nSegments, VARIANT_BOOL SelectedOnly, VARIANT_BOOL MergeResults, IShapefile* sf) { - if (!sf) return VARIANT_FALSE; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); // ------------------------------------------- // validating // ------------------------------------------- @@ -1593,7 +1546,6 @@ STDMETHODIMP CShapefile::Difference(VARIANT_BOOL SelectedOnlySubject, IShapefile VARIANT_BOOL SelectedOnlyOverlay, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); DoClipOperation(SelectedOnlySubject, sfOverlay, SelectedOnlyOverlay, retval, clDifference); return S_OK; } @@ -1605,7 +1557,6 @@ STDMETHODIMP CShapefile::Clip(VARIANT_BOOL SelectedOnlySubject, IShapefile* sfOv IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); DoClipOperation(SelectedOnlySubject, sfOverlay, SelectedOnlyOverlay, retval, clClip); // enumeration should be repaired return S_OK; @@ -1619,7 +1570,6 @@ STDMETHODIMP CShapefile::GetIntersection(VARIANT_BOOL SelectedOnlyOfThis, IShape IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); DoClipOperation(SelectedOnlyOfThis, sf, SelectedOnly, retval, clIntersection, fileType); return S_OK; } @@ -1631,7 +1581,6 @@ STDMETHODIMP CShapefile::SymmDifference(VARIANT_BOOL SelectedOnlySubject, IShape VARIANT_BOOL SelectedOnlyOverlay, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); DoClipOperation(SelectedOnlySubject, sfOverlay, SelectedOnlyOverlay, retval, clSymDifference); // enumeration should be repaired return S_OK; @@ -1644,7 +1593,6 @@ STDMETHODIMP CShapefile::Union(VARIANT_BOOL SelectedOnlySubject, IShapefile* sfO VARIANT_BOOL SelectedOnlyOverlay, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); DoClipOperation(SelectedOnlySubject, sfOverlay, SelectedOnlyOverlay, retval, clUnion); return S_OK; } @@ -1725,7 +1673,6 @@ CString GetClipOperationName(tkClipOperation operation) bool CShapefile::ValidateClippingOutputType(ShpfileType type1, ShpfileType type2, ShpfileType returnType, tkClipOperation operation) { - CSingleLock sfLock(&ShapefileLock, TRUE); switch (operation) { case clSymDifference: @@ -1823,9 +1770,6 @@ void CShapefile::DoClipOperation(VARIANT_BOOL SelectedOnlySubject, IShapefile* s return; } - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); - ShpfileType type2; const ShpfileType type1 = _shpfiletype; @@ -1996,11 +1940,6 @@ void CShapefile::DoClipOperation(VARIANT_BOOL SelectedOnlySubject, IShapefile* s void CShapefile::ClipGEOS(VARIANT_BOOL SelectedOnlySubject, IShapefile* sfOverlay, VARIANT_BOOL SelectedOnlyOverlay, IShapefile* sfResult) { - if (!sfOverlay || !sfResult) return; - - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfOverlay)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2100,11 +2039,6 @@ void CShapefile::ClipGEOS(VARIANT_BOOL SelectedOnlySubject, IShapefile* sfOverla void CShapefile::ClipClipper(VARIANT_BOOL SelectedOnlySubject, IShapefile* sfOverlay, VARIANT_BOOL SelectedOnlyOverlay, IShapefile* sfResult) { - if (!sfOverlay || !sfResult) return; - - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfOverlay)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2246,11 +2180,6 @@ void CShapefile::IntersectionGEOS(VARIANT_BOOL SelectedOnlySubject, IShapefile* std::set* subjectShapesToSkip, std::set* clippingShapesToSkip) { - if (!sfClip || !sfResult) return; - - CSingleLock sfClipLock(&((CShapefile*)sfClip)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfClip)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2331,9 +2260,6 @@ IShapefile* CShapefile::IntersectionClipperNoAttributes(VARIANT_BOOL SelectedOnl if (!sfClip) return nullptr; - CSingleLock sfLock(&((CShapefile*)sfClip)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); - IShapefile* sfResult = nullptr; this->Clone(&sfResult); @@ -2368,11 +2294,6 @@ void CShapefile::IntersectionClipper(VARIANT_BOOL SelectedOnlySubject, IShapefil std::set* subjectShapesToSkip, std::set* clippingShapesToSkip) { - if (!sfClip || !sfResult) return; - - CSingleLock sfClipLock(&((CShapefile*)sfClip)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfClip)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2569,13 +2490,6 @@ void CShapefile::DifferenceGEOS(IShapefile* sfSubject, VARIANT_BOOL SelectedOnly VARIANT_BOOL SelectedOnlyOverlay, IShapefile* sfResult, map* fieldMap, set* shapesToSkip) { - if (!sfOverlay || !sfSubject || !sfResult) return; - - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); - CSingleLock sfSubjectLock(&((CShapefile*)sfSubject)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - - CSingleLock sfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfOverlay)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2695,7 +2609,6 @@ void CShapefile::DifferenceGEOS(IShapefile* sfSubject, VARIANT_BOOL SelectedOnly #ifdef SERIALIZE_POLYGONS void SerializePolygon(ofstream& out, ClipperLib::Polygons* poly) { - CSingleLock sfLock(&ShapefileLock, TRUE); if (poly && out.good()) { out.precision(14); @@ -2730,12 +2643,6 @@ void CShapefile::DifferenceClipper(IShapefile* sfSubject, VARIANT_BOOL SelectedO VARIANT_BOOL SelectedOnlyClip, IShapefile* sfResult, map* fieldMap, set* shapesToSkip) { - if (!sfClip || !sfSubject || !sfResult) return; - - CSingleLock sfClipLock(&((CShapefile*)sfClip)->ShapefileLock, TRUE); - CSingleLock sfSubjectLock(&((CShapefile*)sfSubject)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); QTree* qTree = ((CShapefile*)sfClip)->GetTempQTree(); long numShapesSubject, numShapesClip; @@ -2903,7 +2810,6 @@ void CShapefile::DifferenceClipper(IShapefile* sfSubject, VARIANT_BOOL SelectedO STDMETHODIMP CShapefile::get_GeometryEngine(tkGeometryEngine* pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); *pVal = _geometryEngine; return S_OK; } @@ -2911,7 +2817,6 @@ STDMETHODIMP CShapefile::get_GeometryEngine(tkGeometryEngine* pVal) STDMETHODIMP CShapefile::put_GeometryEngine(tkGeometryEngine newVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); _geometryEngine = newVal; return S_OK; } @@ -2927,7 +2832,6 @@ STDMETHODIMP CShapefile::put_GeometryEngine(tkGeometryEngine newVal) STDMETHODIMP CShapefile::PointInShape(LONG ShapeIndex, DOUBLE x, DOUBLE y, VARIANT_BOOL* retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); if (ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) { @@ -3083,7 +2987,6 @@ STDMETHODIMP CShapefile::PointInShape(LONG ShapeIndex, DOUBLE x, DOUBLE y, VARIA STDMETHODIMP CShapefile::PointInShapefile(DOUBLE x, DOUBLE y, LONG* ShapeIndex) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); const int nShapeCount = _polySf.size(); for (int nShape = nShapeCount - 1; nShape >= 0; nShape--) @@ -3176,7 +3079,6 @@ STDMETHODIMP CShapefile::PointInShapefile(DOUBLE x, DOUBLE y, LONG* ShapeIndex) STDMETHODIMP CShapefile::BeginPointInShapefile(VARIANT_BOOL* retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); if (_writing) { //AfxMessageBox("Can't read"); @@ -3237,7 +3139,6 @@ STDMETHODIMP CShapefile::BeginPointInShapefile(VARIANT_BOOL* retval) STDMETHODIMP CShapefile::EndPointInShapefile() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); _polySf.clear(); @@ -3255,14 +3156,11 @@ VARIANT_BOOL CShapefile::ExplodeShapesCore(VARIANT_BOOL SelectedOnly, IShapefile // ---------------------------------------------- // Validation // ---------------------------------------------- - if (!result || !ValidateInput(this, "ExplodeShapes", "this", SelectedOnly)) + if (!ValidateInput(this, "ExplodeShapes", "this", SelectedOnly)) { return VARIANT_FALSE; } - CSingleLock sfResultLock(&((CShapefile*)result)->ShapefileLock, TRUE); - CSingleLock sfLock(&ShapefileLock, TRUE); - // ---------------------------------------------- // Processing // ---------------------------------------------- @@ -3328,7 +3226,6 @@ VARIANT_BOOL CShapefile::ExplodeShapesCore(VARIANT_BOOL SelectedOnly, IShapefile STDMETHODIMP CShapefile::ExplodeShapes(VARIANT_BOOL SelectedOnly, IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); Clone(retval); @@ -3349,14 +3246,11 @@ VARIANT_BOOL CShapefile::ExportSelectionCore(IShapefile* result) // ---------------------------------------------- // Validation // ---------------------------------------------- - if (!result || !ValidateInput(this, "Sort", "this", false)) + if (!ValidateInput(this, "Sort", "this", false)) { return VARIANT_FALSE; } - CSingleLock sfResultLock(&((CShapefile*)result)->ShapefileLock, TRUE); - CSingleLock sfLock(&ShapefileLock, TRUE); - // ---------------------------------------------- // Processing // ---------------------------------------------- @@ -3425,7 +3319,6 @@ VARIANT_BOOL CShapefile::ExportSelectionCore(IShapefile* result) STDMETHODIMP CShapefile::ExportSelection(IShapefile** retval) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); Clone(retval); @@ -3446,8 +3339,6 @@ STDMETHODIMP CShapefile::Sort(LONG FieldIndex, VARIANT_BOOL Ascending, IShapefil AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock sfLock(&ShapefileLock, TRUE); - // ---------------------------------------------- // Validation // ---------------------------------------------- @@ -3545,9 +3436,6 @@ STDMETHODIMP CShapefile::Merge(VARIANT_BOOL SelectedOnlyThis, IShapefile* sf, VA return S_OK; } - CSingleLock sfResultLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock sfLock(&ShapefileLock, TRUE); - const long numShapes1 = _shapeData.size(); long numShapes2; sf->get_NumShapes(&numShapes2); @@ -3705,8 +3593,6 @@ STDMETHODIMP CShapefile::SimplifyLines(DOUBLE Tolerance, VARIANT_BOOL SelectedOn AFX_MANAGE_STATE(AfxGetStaticModuleState()); USES_CONVERSION; - CSingleLock sfLock(&ShapefileLock, TRUE); - // ---------------------------------------------- // Validation // ---------------------------------------------- @@ -3810,7 +3696,6 @@ STDMETHODIMP CShapefile::SimplifyLines(DOUBLE Tolerance, VARIANT_BOOL SelectedOn STDMETHODIMP CShapefile::Segmentize(double metersTolerance, IShapefile** retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); // ---------------------------------------------- // Validating @@ -3969,7 +3854,6 @@ double CalcMinAngle(GEOSGeometry* geom, double& xCent, double& yCent) // ********************************************************************** Coloring::ColorGraph* CShapefile::GeneratePolygonColors() { - CSingleLock sfLock(&ShapefileLock, TRUE); GenerateTempQTree(false); QTree* tree = GetTempQTree(); ReadGeosGeometries(VARIANT_FALSE); @@ -4053,4 +3937,4 @@ Coloring::ColorGraph* CShapefile::GeneratePolygonColors() } #pragma endregion -// ReSharper restore CppUseAuto \ No newline at end of file +// ReSharper restore CppUseAuto diff --git a/src/COM classes/Shapefile_LabelsCharts.cpp b/src/COM classes/Shapefile_LabelsCharts.cpp index 0fdcbfc6..0875b409 100644 --- a/src/COM classes/Shapefile_LabelsCharts.cpp +++ b/src/COM classes/Shapefile_LabelsCharts.cpp @@ -35,8 +35,7 @@ // GetLabelValue // ************************************************************ void CShapefile::GetLabelString(long fieldIndex, long shapeIndex, BSTR* text, CString floatNumberFormat) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (fieldIndex != -1) +{ if (fieldIndex != -1) { CComVariant val; get_CellValue(fieldIndex, shapeIndex, &val); @@ -54,8 +53,7 @@ void CShapefile::GetLabelString(long fieldIndex, long shapeIndex, BSTR* text, CS // FieldIndex == -1: labels without text will be generated; // Method == lpNone: labels with (0.0,0.0) coordinates will be generated STDMETHODIMP CShapefile::GenerateLabels(long FieldIndex, tkLabelPositioning Method, VARIANT_BOOL LargestPartOnly, long* Count) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - *Count = 0; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); *Count = 0; long numFields; this->get_NumFields(&numFields); @@ -181,15 +179,13 @@ STDMETHODIMP CShapefile::GenerateLabels(long FieldIndex, tkLabelPositioning Meth // ****************************************************************** // Returns reference to Labels class STDMETHODIMP CShapefile::get_Labels(ILabels** pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _labels; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); *pVal = _labels; if (_labels) _labels->AddRef(); return S_OK; } STDMETHODIMP CShapefile::put_Labels(ILabels* newVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - if (!newVal) +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (!newVal) { ErrorMessage(tkINVALID_PARAMETER_VALUE); } @@ -205,8 +201,7 @@ STDMETHODIMP CShapefile::put_Labels(ILabels* newVal) /* put_ReferenceToLabels /***********************************************************************/ void CShapefile::put_ReferenceToLabels(bool bNullReference) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (_labels == NULL) return; +{ if (_labels == NULL) return; ((CLabels*)_labels)->put_ParentShapefile(bNullReference ? NULL : this); } #pragma endregion @@ -216,15 +211,13 @@ void CShapefile::put_ReferenceToLabels(bool bNullReference) // get/put_Charts() // ******************************************************************* STDMETHODIMP CShapefile::get_Charts (ICharts** pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _charts; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); *pVal = _charts; if ( _charts != NULL) _charts->AddRef(); return S_OK; } STDMETHODIMP CShapefile::put_Charts (ICharts* newVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - if (!newVal) +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (!newVal) { ErrorMessage(tkINVALID_PARAMETER_VALUE); } @@ -238,8 +231,7 @@ STDMETHODIMP CShapefile::put_Charts (ICharts* newVal) /* put_ReferenceToCharts /***********************************************************************/ void CShapefile::put_ReferenceToCharts(bool bNullReference) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!_charts) return; +{ if (!_charts) return; ((CCharts*)_charts)->put_ParentShapefile(bNullReference ? NULL: this); }; @@ -247,8 +239,7 @@ void CShapefile::put_ReferenceToCharts(bool bNullReference) // SetChartsPositions // ******************************************************************** void CShapefile::SetChartsPositions(tkLabelPositioning Method) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; +{ USES_CONVERSION; double x,y; ShpfileType shpType; @@ -365,8 +356,7 @@ void CShapefile::SetChartsPositions(tkLabelPositioning Method) // ClearChartFrames() // ************************************************************* void CShapefile::ClearChartFrames() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - for (unsigned int i = 0; i < _shapeData.size(); i++ ) +{ for (unsigned int i = 0; i < _shapeData.size(); i++ ) { CChartInfo* chart = _shapeData[i]->chart; if (chart) diff --git a/src/COM classes/Shapefile_Optimizations.cpp b/src/COM classes/Shapefile_Optimizations.cpp index 86de622e..5ebf4c88 100644 --- a/src/COM classes/Shapefile_Optimizations.cpp +++ b/src/COM classes/Shapefile_Optimizations.cpp @@ -30,8 +30,7 @@ // get_fastMode() // ************************************************************ STDMETHODIMP CShapefile::get_FastMode (VARIANT_BOOL* retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = _fastMode ? VARIANT_TRUE : VARIANT_FALSE; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retval = _fastMode ? VARIANT_TRUE : VARIANT_FALSE; return S_OK; } @@ -39,8 +38,7 @@ STDMETHODIMP CShapefile::get_FastMode (VARIANT_BOOL* retval) // put_FastMode() // ************************************************************ STDMETHODIMP CShapefile::put_FastMode (VARIANT_BOOL newVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) if (!_isEditingShapes) { return S_OK; } @@ -62,8 +60,7 @@ STDMETHODIMP CShapefile::put_FastMode (VARIANT_BOOL newVal) // ReleaseRenderingData() // ***************************************************************** void CShapefile::ReleaseRenderingCache() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - for (unsigned int i = 0; i < _shapeData.size(); i++) { +{ for (unsigned int i = 0; i < _shapeData.size(); i++) { _shapeData[i]->ReleaseRenderingData(); } } @@ -76,8 +73,7 @@ void CShapefile::ReleaseRenderingCache() // get_NumPoints() // ***************************************************************** STDMETHODIMP CShapefile::get_NumPoints(long ShapeIndex, long *pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) *pVal = 0; if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) @@ -150,8 +146,7 @@ STDMETHODIMP CShapefile::get_NumPoints(long ShapeIndex, long *pVal) // ***************************************************************** //This function does not extract Z or M values!!!!!!!! STDMETHODIMP CShapefile::QuickPoint(long ShapeIndex, long PointIndex, IPoint **retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) { *retval = NULL; @@ -345,9 +340,7 @@ STDMETHODIMP CShapefile::QuickPoint(long ShapeIndex, long PointIndex, IPoint **r // ***************************************************************** //This function does not extract Z or M values!!!!!!!! STDMETHODIMP CShapefile::QuickPoints(long ShapeIndex, long *NumPoints, SAFEARRAY ** retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - - *retval = NULL; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retval = NULL; *NumPoints = 0; if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) @@ -541,9 +534,7 @@ STDMETHODIMP CShapefile::QuickPoints(long ShapeIndex, long *NumPoints, SAFEARRAY // ***************************************************************** //This function does not extract Z and M values STDMETHODIMP CShapefile::QuickExtents(long ShapeIndex, IExtents **retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - - *retval = NULL; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retval = NULL; Extent ext; if (this->QuickExtentsCore(ShapeIndex, ext)) @@ -561,8 +552,7 @@ STDMETHODIMP CShapefile::QuickExtents(long ShapeIndex, IExtents **retval) // QuickExtentsCore() // ***************************************************************** bool CShapefile::QuickExtentsCore(long ShapeIndex, double* xMin, double* yMin, double* xMax, double* yMax) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - Extent ext; +{ Extent ext; if (this->QuickExtentsCore(ShapeIndex, ext)) { *xMin = ext.left; @@ -580,8 +570,7 @@ bool CShapefile::QuickExtentsCore(long ShapeIndex, double* xMin, double* yMin, d // ***************************************************************** //This function does not extract Z and M values bool CShapefile::QuickExtentsCore(long ShapeIndex, Extent& result) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) +{ if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) { ErrorMessage( tkINDEX_OUT_OF_BOUNDS ); return false; @@ -612,8 +601,7 @@ bool CShapefile::QuickExtentsCore(long ShapeIndex, Extent& result) // ReadShapeExtents() // ***************************************************************** bool CShapefile::ReadShapeExtents(long ShapeIndex, Extent& result) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - CSingleLock lock(&_readLock, TRUE); +{ CSingleLock lock(&_readLock, TRUE); //Get the Info from the disk fseek(_shpfile, _shpOffsets[ShapeIndex], SEEK_SET); diff --git a/src/COM classes/Shapefile_ReadWrite.cpp b/src/COM classes/Shapefile_ReadWrite.cpp index 6e6e210c..8803395b 100644 --- a/src/COM classes/Shapefile_ReadWrite.cpp +++ b/src/COM classes/Shapefile_ReadWrite.cpp @@ -34,7 +34,6 @@ STDMETHODIMP CShapefile::get_Shape(long ShapeIndex, IShape **pVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); VARIANT_BOOL vbretval = VARIANT_FALSE; // out of bounds? @@ -70,8 +69,7 @@ STDMETHODIMP CShapefile::get_Shape(long ShapeIndex, IShape **pVal) // ReadFastModeShape() // ************************************************************ IShape* CShapefile::ReadFastModeShape(long ShapeIndex) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - fseek(_shpfile, _shpOffsets[ShapeIndex], SEEK_SET); +{ fseek(_shpfile, _shpOffsets[ShapeIndex], SEEK_SET); // read the shp from disk int index = ShapeUtility::ReadIntBigEndian(_shpfile); @@ -114,8 +112,7 @@ IShape* CShapefile::ReadFastModeShape(long ShapeIndex) // ReadComShape() // ************************************************************ IShape* CShapefile::ReadComShape(long ShapeIndex) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // read the shp from disk +{ // read the shp from disk fseek(_shpfile, _shpOffsets[ShapeIndex], SEEK_SET); int intbuf; @@ -957,8 +954,7 @@ IShape* CShapefile::ReadComShape(long ShapeIndex) // ReadShx() // ************************************************************** BOOL CShapefile::ReadShx() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // guaranteed that .shx file is open +{ // guaranteed that .shx file is open rewind(_shxfile); _shpOffsets.clear(); @@ -1025,8 +1021,7 @@ BOOL CShapefile::ReadShx() // AppendToShx() // ************************************************************** bool CShapefile::AppendToShx(FILE* shx, IShape* shp, int offset) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!shx || !shp) return false; +{ if (!shx || !shp) return false; _shpOffsets.push_back(offset); @@ -1046,8 +1041,7 @@ bool CShapefile::AppendToShx(FILE* shx, IShape* shp, int offset) // WriteShx() // ************************************************************** BOOL CShapefile::WriteShx(FILE * shx, ICallback * cBack) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - ICallback* callback = cBack ? cBack : _globalCallback; +{ ICallback* callback = cBack ? cBack : _globalCallback; // guaranteed that .shx file is open rewind(shx); @@ -1123,8 +1117,7 @@ BOOL CShapefile::WriteShx(FILE * shx, ICallback * cBack) // GetWriteFileLength() // ************************************************************** int CShapefile::GetWriteFileLength() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - IShape * sh = NULL; +{ IShape * sh = NULL; long numPoints = 0; long numParts = 0; long part = 0; @@ -1152,8 +1145,7 @@ int CShapefile::GetWriteFileLength() // AppendToShpFile() // ************************************************************** bool CShapefile::AppendToShpFile(FILE* shp, IShapeWrapper* wrapper) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (!shp || !wrapper) return false; +{ if (!shp || !wrapper) return false; int length = wrapper->get_ContentLength(); @@ -1182,8 +1174,7 @@ bool CShapefile::AppendToShpFile(FILE* shp, IShapeWrapper* wrapper) // WriteShp() // ************************************************************** void CShapefile::WriteBounds(FILE * shp) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - double ShapefileBounds[8]; +{ double ShapefileBounds[8]; ShapefileBounds[0] = _minX; ShapefileBounds[1] = _minY; ShapefileBounds[2] = _maxX; @@ -1199,8 +1190,7 @@ void CShapefile::WriteBounds(FILE * shp) // WriteShp() // ************************************************************** BOOL CShapefile::WriteShp(FILE * shp, ICallback * cBack) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - // guaranteed that .shp file is open +{ // guaranteed that .shp file is open rewind(shp); //FILE_CODE diff --git a/src/COM classes/Shapefile_Selection.cpp b/src/COM classes/Shapefile_Selection.cpp index db8db613..5bb6160a 100644 --- a/src/COM classes/Shapefile_Selection.cpp +++ b/src/COM classes/Shapefile_Selection.cpp @@ -36,8 +36,7 @@ // ****************************************************************** CMutex selectShapesMutex(FALSE); STDMETHODIMP CShapefile::SelectShapes(IExtents *BoundBox, double Tolerance, SelectMode SelectMode, VARIANT *Result, VARIANT_BOOL *retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - *retval = VARIANT_FALSE; +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) *retval = VARIANT_FALSE; selectShapesMutex.Lock(); @@ -59,8 +58,7 @@ STDMETHODIMP CShapefile::SelectShapes(IExtents *BoundBox, double Tolerance, Sele // SelectShapesCore() // **************************************************************** bool CShapefile::SelectShapesCore(Extent& extents, double Tolerance, SelectMode SelectMode, std::vector& selectResult, bool renderedOnly) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - double b_minX = extents.left; +{ double b_minX = extents.left; double b_maxX = extents.right; double b_minY = extents.bottom; double b_maxY = extents.top; @@ -336,8 +334,7 @@ bool CShapefile::SelectShapesCore(Extent& extents, double Tolerance, SelectMode /***********************************************************************/ // Returns and sets the selection state for a shape. STDMETHODIMP CShapefile::get_ShapeSelected(long ShapeIndex, VARIANT_BOOL* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) { *pVal = VARIANT_FALSE; ErrorMessage(tkINDEX_OUT_OF_BOUNDS); @@ -349,8 +346,7 @@ STDMETHODIMP CShapefile::get_ShapeSelected(long ShapeIndex, VARIANT_BOOL* pVal) return S_OK; } STDMETHODIMP CShapefile::put_ShapeSelected(long ShapeIndex, VARIANT_BOOL newVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); if( ShapeIndex < 0 || ShapeIndex >= (long)_shapeData.size()) { ErrorMessage(tkINDEX_OUT_OF_BOUNDS); } @@ -365,8 +361,7 @@ STDMETHODIMP CShapefile::put_ShapeSelected(long ShapeIndex, VARIANT_BOOL newVal) // get_NumSelected // ************************************************************* STDMETHODIMP CShapefile::get_NumSelected(long *pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); long count = 0; for(int i =0; i < (int)_shapeData.size(); i++) { @@ -381,8 +376,7 @@ STDMETHODIMP CShapefile::get_NumSelected(long *pVal) // SelectAll() // ************************************************************* STDMETHODIMP CShapefile::SelectAll() -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); for (int i = 0; i < (int)_shapeData.size(); i++) { _shapeData[i]->selected(true); } @@ -394,8 +388,7 @@ STDMETHODIMP CShapefile::SelectAll() // SelectNone() // ************************************************************* STDMETHODIMP CShapefile::SelectNone() -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); for (int i = 0; i < (int)_shapeData.size(); i++) { _shapeData[i]->selected(false); } @@ -407,8 +400,7 @@ STDMETHODIMP CShapefile::SelectNone() // InvertSelection() // ************************************************************* STDMETHODIMP CShapefile::InvertSelection() -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - +{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); for (int i = 0; i < (int)_shapeData.size(); i++) { _shapeData[i]->selected(!_shapeData[i]->selected()); } diff --git a/src/COM classes/Shapefile_SpatialIndex.cpp b/src/COM classes/Shapefile_SpatialIndex.cpp index fcb48602..00d0b0d3 100644 --- a/src/COM classes/Shapefile_SpatialIndex.cpp +++ b/src/COM classes/Shapefile_SpatialIndex.cpp @@ -1,426 +1,434 @@ -//******************************************************************************************************** -//File name: Shapefile.cpp -//Description: Implementation of the CShapefile (see other cpp files as well) -//******************************************************************************************************** -//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); -//you may not use this file except in compliance with the License. You may obtain a copy of the License at -//http://www.mozilla.org/MPL/ -//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF -//ANY KIND, either express or implied. See the License for the specific language governing rights and -//limitations under the License. -// -//The Original Code is MapWindow Open Source. -// -//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by -//Utah State University and the Idaho National Engineering and Environmental Lab that were released as -//public domain in March 2004. -// -//Contributor(s): (Open source contributors should list themselves and their modifications here). -// ------------------------------------------------------------------------------------------------------- -// lsu 3-02-2011: split the initial Shapefile.cpp file to make entities of the reasonable size - -#include "stdafx.h" -#include "Shapefile.h" - -#pragma region SpatialIndex -// ***************************************************************** -// get_HasSpatialIndex() -// ***************************************************************** -//ajp June 2008 Property does spatial index exist -STDMETHODIMP CShapefile::get_HasSpatialIndex(VARIANT_BOOL *pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - - try - { - _hasSpatialIndex = FALSE; - CString mwdfileName = _shpfileName.Left(_shpfileName.GetLength() - 3) + "mwd"; - CString mwxfileName = _shpfileName.Left(_shpfileName.GetLength() - 3) + "mwx"; - if (Utility::FileExists(mwdfileName) && Utility::FileExists(mwxfileName)) - { - _hasSpatialIndex = TRUE; - } - } - catch (...) - { - _hasSpatialIndex = FALSE; - } - - *pVal = _hasSpatialIndex?VARIANT_TRUE:VARIANT_FALSE; - - return S_OK; -} - -// ***************************************************************** -// get_HasSpatialIndex() -// ***************************************************************** -//ajp June 2008 Property does spatial index exist -STDMETHODIMP CShapefile::put_HasSpatialIndex(VARIANT_BOOL pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - _hasSpatialIndex = pVal; // CreateSpatialIndex should be used to create it - return S_OK; -} - -bool TestIndexSearching() -{ - __try - { - IndexSearching::isValidSpatialIndex("", 0); - return true; - } - __except(1) - { - return false; - } -} - -// ***************************************************************** -// get/put_UseSpatialIndex() -// ***************************************************************** -//ajp June 2008 Property use spatial indexing -STDMETHODIMP CShapefile::get_UseSpatialIndex(VARIANT_BOOL *pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - if (_useSpatialIndex) - { - //useSpatialIndex = TestIndexSearching(); - } - *pVal = _useSpatialIndex?VARIANT_TRUE:VARIANT_FALSE; - return S_OK; -} -STDMETHODIMP CShapefile::put_UseSpatialIndex(VARIANT_BOOL pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - _useSpatialIndex = pVal; - - // Unload spatial index in case it needs to be recreated - if (!_useSpatialIndex && _spatialIndexLoaded) - { - IndexSearching::unloadSpatialIndex(_spatialIndexID); - } - return S_OK; -} - -// ***************************************************************** -// get/put_SpatialIndexMaxAreaPercent() -// ***************************************************************** -//08-24-2009 (sm) spatial index performance -STDMETHODIMP CShapefile::put_SpatialIndexMaxAreaPercent(DOUBLE newVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - _spatialIndexMaxAreaPercent = newVal; - return S_OK; -} -STDMETHODIMP CShapefile::get_SpatialIndexMaxAreaPercent(DOUBLE* pVal) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = _spatialIndexMaxAreaPercent; - return S_OK; -} - -// ***************************************************************** -// get_CanUseSpatialIndex() -// ***************************************************************** -//Check that the spatial index exists, is set to be used and should be used. -STDMETHODIMP CShapefile::get_CanUseSpatialIndex(IExtents* pArea, VARIANT_BOOL* pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = VARIANT_FALSE; - - double xm, xM, ym, yM, zm, zM; - pArea->GetBounds(&xm, &ym, &zm, &xM, &yM, &zM); - Extent extents(xm, xM, ym, yM); - - if (!_isEditingShapes && _useSpatialIndex) - { - VARIANT_BOOL spatialIndexExists; - get_HasSpatialIndex(&spatialIndexExists); - - if (spatialIndexExists) - { - double xM = min(_maxX, extents.right); - double xm = max(_minX, extents.left); - double yM = min(_maxY, extents.top); - double ym = max(_minY, extents.bottom); - - double shapeFileArea = (_maxX - _minX)*(_maxY - _minY); - double selectShapeArea = (xM - xm) * (yM - ym); - - if (selectShapeArea / shapeFileArea < _spatialIndexMaxAreaPercent) - { - //when large portions of the map are being drawn, - //the spatial index *probably* won't help, don't use it. - if (_spatialIndexLoaded) - { - *pVal = VARIANT_TRUE; - return S_OK; - } - else - { - USES_CONVERSION; - string baseName = W2A(_shpfileName.Left(_shpfileName.GetLength() - 4)); // TODO: use Unicode - if (IndexSearching::loadSpatialIndex(baseName, false, _spatialIndexNodeCapacity, _spatialIndexID)) - { - _spatialIndexLoaded = true; - *pVal = VARIANT_TRUE; - return S_OK; - } - } - } - } - } - return S_OK; -} - -// *********************************************************** -// CreateSpatialIndex() -// *********************************************************** -//ajp June 2008 Function to create an Index file -STDMETHODIMP CShapefile::CreateSpatialIndex(BSTR ShapefileName, VARIANT_BOOL *retval) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()) CSingleLock sfLock(&ShapefileLock, TRUE); - USES_CONVERSION; - - *retval = VARIANT_TRUE; - - CString tmp_shpfileName = OLE2CA(ShapefileName); - if( tmp_shpfileName.GetLength() <= 3 ) - { - *retval = VARIANT_FALSE; - ErrorMessage(tkINVALID_FILENAME); - } - else - { - string baseName; - baseName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 4); - - // 0.9 = utilization rate, 100 = Node Capacity - // Creates two files baseName.dat and baseName.idx - try - { - if (!IndexSearching::createSpatialIndex(0.9, _spatialIndexNodeCapacity, (char *)baseName.c_str())) - { - *retval = VARIANT_FALSE; - ErrorMessage(tkINVALID_FILENAME); - } - } - catch (...) - { - *retval = VARIANT_FALSE; - } - } - - return S_OK; -} - -// *********************************************************** -// IsSpatialIndexValid() -// *********************************************************** -STDMETHODIMP CShapefile::IsSpatialIndexValid(VARIANT_BOOL *retval) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - VARIANT_BOOL hasSpatialIndex; - get_HasSpatialIndex(&hasSpatialIndex); - if (!hasSpatialIndex) - *retval = VARIANT_FALSE; - else - { - USES_CONVERSION; - string baseName = W2A(_shpfileName.Left(_shpfileName.GetLength() - 4)); // TODO: use Unicode - bool bIsValid = IndexSearching::isValidSpatialIndex(baseName.c_str(), _spatialIndexNodeCapacity); - *retval = bIsValid ? VARIANT_TRUE : VARIANT_FALSE; - } - - return S_OK; -} -#pragma endregion - - -#pragma region QuadTree -// ******************************************************************** -// QuickQueryInEditMode() -// ******************************************************************** -//Neio 2009/07/21 -STDMETHODIMP CShapefile::QuickQueryInEditMode(IExtents *BoundBox, int ** Result, int* ResultCount ) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - - if(! _isEditingShapes ) - { - ErrorMessage( tkSHPFILE_NOT_IN_EDIT_MODE ); - return S_OK; - } - else if( _useQTree ) - { - double xMin, yMin, zMin, xMax, yMax, zMax; - BoundBox->GetBounds(&xMin,&yMin,&zMin,&xMax,&yMax,&zMax); - - vector r = _qtree->GetNodes(QTreeExtent(xMin,xMax,yMax,yMin)); - int size = r.size(); - *Result = new int[size]; - - memcpy( *Result, &r[0], sizeof(int) * size); - *ResultCount = size; - } - return S_OK; -} - -// ***************************************************************** -// get_UseQTree() -// ***************************************************************** -STDMETHODIMP CShapefile::get_UseQTree(VARIANT_BOOL *pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - *pVal = (_useQTree)?VARIANT_TRUE:VARIANT_FALSE; - return S_OK; -} - -// ***************************************************************** -// put_UseQTree() -// ***************************************************************** -STDMETHODIMP CShapefile::put_UseQTree(VARIANT_BOOL pVal) -{ AFX_MANAGE_STATE(AfxGetStaticModuleState()); CSingleLock sfLock(&ShapefileLock, TRUE); - if (pVal) - { - if (_qtree == NULL) - this->GenerateQTree(); - _useQTree = TRUE; - } - else - { - _useQTree = FALSE; - delete _qtree; - _qtree = NULL; - } - return S_OK; -} - -// ********************************************************** -// ClearQTree -// ********************************************************** -void CShapefile::ClearQTree(double* xMin, double* xMax, double* yMin, double* yMax, double* zMin, double* zMax) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (_qtree) - { - delete _qtree; - _qtree = NULL; - } - - _qtree = this->GenerateEmptyQTree(xMin, yMin, zMin, xMax, yMax, zMax); -} - -// ********************************************************** -// GenerateEmptyQTree -// ********************************************************** -QTree* CShapefile::GenerateEmptyQTree(double* xMin, double* xMax, double* yMin, double* yMax, double* zMin, double* zMax) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - IExtents* ext = NULL; - this->get_Extents(&ext); - if (!ext) return NULL; - ext->GetBounds(xMin, yMin, zMin, xMax, yMax, zMax); - ext->Release(); - - QTree* qtree = new QTree(QTreeExtent(*xMin, *xMax, *yMax, *yMin)); - - return qtree; -} - -// ********************************************************** -// GenerateQTree -// ********************************************************** -void CShapefile::GenerateQTree() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if(_qtree) - { - delete _qtree; - _qtree = NULL; - } - - _qtree = GenerateQTreeCore(false); -} - - - -// ********************************************************************** -// GenerateQTreeCore() -// ********************************************************************** -QTree* CShapefile::GenerateQTreeCore(bool SelectedOnly) -{ - CSingleLock sfLock(&ShapefileLock, TRUE); - double xMin, xMax, yMin, yMax, zMin, zMax; - QTree* qtree = this->GenerateEmptyQTree(&xMin, &xMax, &yMin, &yMax, &zMin, &zMax); - - if (_shapeData.size() == 0) - return qtree; - - long percent; - int numShapes = (int)_shapeData.size(); - for(int i = 0; i < numShapes; i++ ) - { - if (!ShapeAvailable(i, SelectedOnly)) - continue; - - this->QuickExtentsCore(i, &xMin,&yMin,&xMax,&yMax); - - QTreeNode node; - node.Extent.left =xMin; - node.Extent.right = xMax; - node.Extent.top = yMax; - node.Extent.bottom = yMin; - node.index = i; - qtree->AddNode(node); - - CallbackHelper::Progress(_globalCallback, i, numShapes, "Building index...", _key, percent); - } - CallbackHelper::ProgressCompleted(_globalCallback, _key); - - return qtree; -} -#pragma endregion - -// Build the tree anew for geoprocessing operations, as the original one -// probably not 100% accurate/optimal + we may need only selected shapes - -// ********************************************************************** -// GenerateTempQTree() -// ********************************************************************** -bool CShapefile::GenerateTempQTree(bool SelectedOnly) -{ CSingleLock sfLock(&ShapefileLock, TRUE); - ClearTempQTree(); - _tempTree = GenerateQTreeCore(SelectedOnly); - return _tempTree != NULL; -} - -// ********************************************************************** -// ClearTempQTree() -// ********************************************************************** -void CShapefile::ClearTempQTree() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - if (_tempTree) - { - delete _tempTree; - _tempTree = NULL; - } -} - -// ********************************************************************** -// GetTempQtree() -// ********************************************************************** -QTree* CShapefile::GetTempQTree() -{ CSingleLock sfLock(&ShapefileLock, TRUE); - return _tempTree; -} - -// ********************************************************************** -// RemoveSpatialIndex() -// ********************************************************************** -STDMETHODIMP CShapefile::RemoveSpatialIndex(VARIANT_BOOL* retVal) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); - *retVal = VARIANT_TRUE; - CStringW names[] = {L"mwd", L"mwx"}; - - for (int i = 0; i < 2; i++) - { - CString name = _shpfileName.Left(_shpfileName.GetLength() - 3) + names[i]; - if (Utility::FileExists(name)) - { - if (remove(name) != 0) { - ErrorMessage(tkCANT_DELETE_FILE); - *retVal = VARIANT_FALSE; - } - } - } - return S_OK; +//******************************************************************************************************** +//File name: Shapefile.cpp +//Description: Implementation of the CShapefile (see other cpp files as well) +//******************************************************************************************************** +//The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); +//you may not use this file except in compliance with the License. You may obtain a copy of the License at +//http://www.mozilla.org/MPL/ +//Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF +//ANY KIND, either express or implied. See the License for the specific language governing rights and +//limitations under the License. +// +//The Original Code is MapWindow Open Source. +// +//The Initial Developer of this version of the Original Code is Daniel P. Ames using portions created by +//Utah State University and the Idaho National Engineering and Environmental Lab that were released as +//public domain in March 2004. +// +//Contributor(s): (Open source contributors should list themselves and their modifications here). +// ------------------------------------------------------------------------------------------------------- +// lsu 3-02-2011: split the initial Shapefile.cpp file to make entities of the reasonable size + +#include "stdafx.h" +#include "Shapefile.h" + +#pragma region SpatialIndex +// ***************************************************************** +// get_HasSpatialIndex() +// ***************************************************************** +//ajp June 2008 Property does spatial index exist +STDMETHODIMP CShapefile::get_HasSpatialIndex(VARIANT_BOOL *pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + + try + { + _hasSpatialIndex = FALSE; + CString mwdfileName = _shpfileName.Left(_shpfileName.GetLength() - 3) + "mwd"; + CString mwxfileName = _shpfileName.Left(_shpfileName.GetLength() - 3) + "mwx"; + if (Utility::FileExists(mwdfileName) && Utility::FileExists(mwxfileName)) + { + _hasSpatialIndex = TRUE; + } + } + catch (...) + { + _hasSpatialIndex = FALSE; + } + + *pVal = _hasSpatialIndex?VARIANT_TRUE:VARIANT_FALSE; + + return S_OK; +} + +// ***************************************************************** +// get_HasSpatialIndex() +// ***************************************************************** +//ajp June 2008 Property does spatial index exist +STDMETHODIMP CShapefile::put_HasSpatialIndex(VARIANT_BOOL pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + _hasSpatialIndex = pVal; // CreateSpatialIndex should be used to create it + return S_OK; +} + +bool TestIndexSearching() +{ + __try + { + IndexSearching::isValidSpatialIndex("", 0); + return true; + } + __except(1) + { + return false; + } +} + +// ***************************************************************** +// get/put_UseSpatialIndex() +// ***************************************************************** +//ajp June 2008 Property use spatial indexing +STDMETHODIMP CShapefile::get_UseSpatialIndex(VARIANT_BOOL *pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + if (_useSpatialIndex) + { + //useSpatialIndex = TestIndexSearching(); + } + *pVal = _useSpatialIndex?VARIANT_TRUE:VARIANT_FALSE; + return S_OK; +} +STDMETHODIMP CShapefile::put_UseSpatialIndex(VARIANT_BOOL pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + _useSpatialIndex = pVal; + + // Unload spatial index in case it needs to be recreated + if (!_useSpatialIndex && _spatialIndexLoaded) + { + IndexSearching::unloadSpatialIndex(_spatialIndexID); + } + return S_OK; +} + +// ***************************************************************** +// get/put_SpatialIndexMaxAreaPercent() +// ***************************************************************** +//08-24-2009 (sm) spatial index performance +STDMETHODIMP CShapefile::put_SpatialIndexMaxAreaPercent(DOUBLE newVal) +{ + _spatialIndexMaxAreaPercent = newVal; + return S_OK; +} +STDMETHODIMP CShapefile::get_SpatialIndexMaxAreaPercent(DOUBLE* pVal) +{ + *pVal = _spatialIndexMaxAreaPercent; + return S_OK; +} + +// ***************************************************************** +// get_CanUseSpatialIndex() +// ***************************************************************** +//Check that the spatial index exists, is set to be used and should be used. +STDMETHODIMP CShapefile::get_CanUseSpatialIndex(IExtents* pArea, VARIANT_BOOL* pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + *pVal = VARIANT_FALSE; + + double xm, xM, ym, yM, zm, zM; + pArea->GetBounds(&xm, &ym, &zm, &xM, &yM, &zM); + Extent extents(xm, xM, ym, yM); + + if (!_isEditingShapes && _useSpatialIndex) + { + VARIANT_BOOL spatialIndexExists; + get_HasSpatialIndex(&spatialIndexExists); + + if (spatialIndexExists) + { + double xM = min(_maxX, extents.right); + double xm = max(_minX, extents.left); + double yM = min(_maxY, extents.top); + double ym = max(_minY, extents.bottom); + + double shapeFileArea = (_maxX - _minX)*(_maxY - _minY); + double selectShapeArea = (xM - xm) * (yM - ym); + + if (selectShapeArea / shapeFileArea < _spatialIndexMaxAreaPercent) + { + //when large portions of the map are being drawn, + //the spatial index *probably* won't help, don't use it. + if (_spatialIndexLoaded) + { + *pVal = VARIANT_TRUE; + return S_OK; + } + else + { + USES_CONVERSION; + string baseName = W2A(_shpfileName.Left(_shpfileName.GetLength() - 4)); // TODO: use Unicode + if (IndexSearching::loadSpatialIndex(baseName, false, _spatialIndexNodeCapacity, _spatialIndexID)) + { + _spatialIndexLoaded = true; + *pVal = VARIANT_TRUE; + return S_OK; + } + } + } + } + } + return S_OK; +} + +// *********************************************************** +// CreateSpatialIndex() +// *********************************************************** +//ajp June 2008 Function to create an Index file +STDMETHODIMP CShapefile::CreateSpatialIndex(BSTR ShapefileName, VARIANT_BOOL *retval) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()) + USES_CONVERSION; + + *retval = VARIANT_TRUE; + + CString tmp_shpfileName = OLE2CA(ShapefileName); + if( tmp_shpfileName.GetLength() <= 3 ) + { + *retval = VARIANT_FALSE; + ErrorMessage(tkINVALID_FILENAME); + } + else + { + string baseName; + baseName = tmp_shpfileName.Left(tmp_shpfileName.GetLength() - 4); + + // 0.9 = utilization rate, 100 = Node Capacity + // Creates two files baseName.dat and baseName.idx + try + { + if (!IndexSearching::createSpatialIndex(0.9, _spatialIndexNodeCapacity, (char *)baseName.c_str())) + { + *retval = VARIANT_FALSE; + ErrorMessage(tkINVALID_FILENAME); + } + } + catch (...) + { + *retval = VARIANT_FALSE; + } + } + + return S_OK; +} + +// *********************************************************** +// IsSpatialIndexValid() +// *********************************************************** +STDMETHODIMP CShapefile::IsSpatialIndexValid(VARIANT_BOOL *retval) +{ + VARIANT_BOOL hasSpatialIndex; + get_HasSpatialIndex(&hasSpatialIndex); + if (!hasSpatialIndex) + *retval = VARIANT_FALSE; + else + { + USES_CONVERSION; + string baseName = W2A(_shpfileName.Left(_shpfileName.GetLength() - 4)); // TODO: use Unicode + bool bIsValid = IndexSearching::isValidSpatialIndex(baseName.c_str(), _spatialIndexNodeCapacity); + *retval = bIsValid ? VARIANT_TRUE : VARIANT_FALSE; + } + + return S_OK; +} +#pragma endregion + + +#pragma region QuadTree +// ******************************************************************** +// QuickQueryInEditMode() +// ******************************************************************** +//Neio 2009/07/21 +STDMETHODIMP CShapefile::QuickQueryInEditMode(IExtents *BoundBox, int ** Result, int* ResultCount ) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + if(! _isEditingShapes ) + { + ErrorMessage( tkSHPFILE_NOT_IN_EDIT_MODE ); + return S_OK; + } + else if( _useQTree ) + { + double xMin, yMin, zMin, xMax, yMax, zMax; + BoundBox->GetBounds(&xMin,&yMin,&zMin,&xMax,&yMax,&zMax); + + vector r = _qtree->GetNodes(QTreeExtent(xMin,xMax,yMax,yMin)); + int size = r.size(); + *Result = new int[size]; + + memcpy( *Result, &r[0], sizeof(int) * size); + *ResultCount = size; + } + return S_OK; +} + +// ***************************************************************** +// get_UseQTree() +// ***************************************************************** +STDMETHODIMP CShapefile::get_UseQTree(VARIANT_BOOL *pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *pVal = (_useQTree)?VARIANT_TRUE:VARIANT_FALSE; + return S_OK; +} + +// ***************************************************************** +// put_UseQTree() +// ***************************************************************** +STDMETHODIMP CShapefile::put_UseQTree(VARIANT_BOOL pVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + if (pVal) + { + if (_qtree == NULL) + this->GenerateQTree(); + _useQTree = TRUE; + } + else + { + _useQTree = FALSE; + delete _qtree; + _qtree = NULL; + } + return S_OK; +} + +// ********************************************************** +// ClearQTree +// ********************************************************** +void CShapefile::ClearQTree(double* xMin, double* xMax, double* yMin, double* yMax, double* zMin, double* zMax) +{ + if (_qtree) + { + delete _qtree; + _qtree = NULL; + } + + _qtree = this->GenerateEmptyQTree(xMin, yMin, zMin, xMax, yMax, zMax); +} + +// ********************************************************** +// GenerateEmptyQTree +// ********************************************************** +QTree* CShapefile::GenerateEmptyQTree(double* xMin, double* xMax, double* yMin, double* yMax, double* zMin, double* zMax) +{ + IExtents* ext = NULL; + this->get_Extents(&ext); + if (!ext) return NULL; + ext->GetBounds(xMin, yMin, zMin, xMax, yMax, zMax); + ext->Release(); + + QTree* qtree = new QTree(QTreeExtent(*xMin, *xMax, *yMax, *yMin)); + + return qtree; +} + +// ********************************************************** +// GenerateQTree +// ********************************************************** +void CShapefile::GenerateQTree() +{ + if(_qtree) + { + delete _qtree; + _qtree = NULL; + } + + _qtree = GenerateQTreeCore(false); +} + + + +// ********************************************************************** +// GenerateQTreeCore() +// ********************************************************************** +QTree* CShapefile::GenerateQTreeCore(bool SelectedOnly) +{ + + double xMin, xMax, yMin, yMax, zMin, zMax; + QTree* qtree = this->GenerateEmptyQTree(&xMin, &xMax, &yMin, &yMax, &zMin, &zMax); + + if (_shapeData.size() == 0) + return qtree; + + long percent; + int numShapes = (int)_shapeData.size(); + for(int i = 0; i < numShapes; i++ ) + { + if (!ShapeAvailable(i, SelectedOnly)) + continue; + + this->QuickExtentsCore(i, &xMin,&yMin,&xMax,&yMax); + + QTreeNode node; + node.Extent.left =xMin; + node.Extent.right = xMax; + node.Extent.top = yMax; + node.Extent.bottom = yMin; + node.index = i; + qtree->AddNode(node); + + CallbackHelper::Progress(_globalCallback, i, numShapes, "Building index...", _key, percent); + } + CallbackHelper::ProgressCompleted(_globalCallback, _key); + + return qtree; +} +#pragma endregion + +// Build the tree anew for geoprocessing operations, as the original one +// probably not 100% accurate/optimal + we may need only selected shapes + +// ********************************************************************** +// GenerateTempQTree() +// ********************************************************************** +bool CShapefile::GenerateTempQTree(bool SelectedOnly) +{ + ClearTempQTree(); + _tempTree = GenerateQTreeCore(SelectedOnly); + return _tempTree != NULL; +} + +// ********************************************************************** +// ClearTempQTree() +// ********************************************************************** +void CShapefile::ClearTempQTree() +{ + if (_tempTree) + { + delete _tempTree; + _tempTree = NULL; + } +} + +// ********************************************************************** +// GetTempQtree() +// ********************************************************************** +QTree* CShapefile::GetTempQTree() +{ + return _tempTree; +} + +// ********************************************************************** +// RemoveSpatialIndex() +// ********************************************************************** +STDMETHODIMP CShapefile::RemoveSpatialIndex(VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + *retVal = VARIANT_TRUE; + CStringW names[] = {L"mwd", L"mwx"}; + + for (int i = 0; i < 2; i++) + { + CString name = _shpfileName.Left(_shpfileName.GetLength() - 3) + names[i]; + if (Utility::FileExists(name)) + { + if (remove(name) != 0) { + ErrorMessage(tkCANT_DELETE_FILE); + *retVal = VARIANT_FALSE; + } + } + } + return S_OK; } \ No newline at end of file diff --git a/src/COM classes/Shapefile_Validation.cpp b/src/COM classes/Shapefile_Validation.cpp index b8e4a369..44bd84fe 100644 --- a/src/COM classes/Shapefile_Validation.cpp +++ b/src/COM classes/Shapefile_Validation.cpp @@ -37,7 +37,6 @@ STDMETHODIMP CShapefile::Validate(tkShapeValidationMode validationMode, VARIANT_ IShapeValidationInfo** results) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); *results = nullptr; if (validationMode == NoValidation) @@ -63,7 +62,6 @@ STDMETHODIMP CShapefile::Validate(tkShapeValidationMode validationMode, VARIANT_ bool CShapefile::ValidateInput(IShapefile* isf, CString methodName, CString parameterName, VARIANT_BOOL selectedOnly, CString className /*= "Shapefile"*/) { - CSingleLock mySfLock(&ShapefileLock, TRUE); // MWGIS-132; this code, suggested by CLang for MWGIS-104 on 24 Aug 2018, // is being removed because it prevents any in-memory Shapefile from passing // validation (since in-memory shapefiles have no FILE * (_shpfile == NULL). @@ -99,10 +97,6 @@ IShapeValidationInfo* CShapefile::ValidateInputCore(IShapefile* isf, CString met tkShapeValidationMode validationMode, CString className, bool reportOnly) { - if (!isf) return nullptr; - - CSingleLock sfLock(&((CShapefile*)isf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); tkShapefileSourceType sourceType; if (isf->get_SourceType(&sourceType)) { @@ -150,9 +144,6 @@ IShapeValidationInfo* CShapefile::ValidateOutput(IShapefile** isf, CString metho { if (!*isf) return nullptr; - CSingleLock sfLock(&((CShapefile*)*isf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); - long numShapes; (*isf)->get_NumShapes(&numShapes); if (numShapes == 0 && abortIfEmpty) @@ -168,8 +159,6 @@ IShapeValidationInfo* CShapefile::ValidateOutput(IShapefile** isf, CString metho ErrorMessage(errorCode); VARIANT_BOOL vb; - // have to release lock prior to destruction - sfLock.Unlock(); (*isf)->Close(&vb); (*isf)->Release(); *isf = nullptr; @@ -198,9 +187,6 @@ IShapeValidationInfo* CShapefile::ValidateOutput(IShapefile** isf, CString metho // ************************************************************** bool CShapefile::ValidateOutput(IShapefile* sf, CString methodName, CString className, bool abortIfEmpty) { - if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CSingleLock mySfLock(&ShapefileLock, TRUE); if (!_isEditingShapes) { return true; @@ -215,7 +201,6 @@ bool CShapefile::ValidateOutput(IShapefile* sf, CString methodName, CString clas // ********************************************************* HRESULT CShapefile::GetValidatedShape(int shapeIndex, IShape** retVal) { - CSingleLock sfLock(&ShapefileLock, TRUE); IShape* shp = nullptr; get_Shape(shapeIndex, &shp); @@ -277,7 +262,6 @@ HRESULT CShapefile::GetValidatedShape(int shapeIndex, IShape** retVal) // ********************************************************* bool CShapefile::ShapeAvailable(int shapeIndex, VARIANT_BOOL selectedOnly) { - CSingleLock sfLock(&ShapefileLock, TRUE); if (shapeIndex < 0 || shapeIndex >= (int)_shapeData.size()) { return false; @@ -300,7 +284,6 @@ bool CShapefile::ShapeAvailable(int shapeIndex, VARIANT_BOOL selectedOnly) // ********************************************************* GEOSGeometry* CShapefile::GetGeosGeometry(int shapeIndex) { - CSingleLock sfLock(&ShapefileLock, TRUE); return _shapeData[shapeIndex]->geosGeom; } @@ -310,7 +293,6 @@ GEOSGeometry* CShapefile::GetGeosGeometry(int shapeIndex) STDMETHODIMP CShapefile::ClearCachedGeometries() { AFX_MANAGE_STATE(AfxGetStaticModuleState()) - CSingleLock sfLock(&ShapefileLock, TRUE); if (_geosGeometriesRead) { for (auto& i : _shapeData) @@ -331,7 +313,6 @@ STDMETHODIMP CShapefile::ClearCachedGeometries() // ********************************************************* void CShapefile::ReadGeosGeometries(VARIANT_BOOL selectedOnly) { - CSingleLock sfLock(&ShapefileLock, TRUE); if (_geosGeometriesRead) { CallbackHelper::AssertionFailed("Attempt to reread GEOS geometries while they are in memory."); @@ -368,4 +349,4 @@ void CShapefile::ReadGeosGeometries(VARIANT_BOOL selectedOnly) #pragma endregion -// ReSharper restore CppUseAuto \ No newline at end of file +// ReSharper restore CppUseAuto diff --git a/src/COM classes/Utils.cpp b/src/COM classes/Utils.cpp index 779fdc82..d1145e66 100644 --- a/src/COM classes/Utils.cpp +++ b/src/COM classes/Utils.cpp @@ -385,8 +385,6 @@ STDMETHODIMP CUtils::RemoveColinearPoints(IShapefile * Shapes, double LinearTole return S_OK; } - CSingleLock sfLock(&((CShapefile*) Shapes)->ShapefileLock, TRUE); - ICallback* callback = cBack ? cBack : _globalCallback; ShpfileType shptype; @@ -1163,8 +1161,6 @@ STDMETHODIMP CUtils::ShapeToShapeZ(IShapefile * Shapefile, IGrid *Grid, ICallbac return S_OK; } - CSingleLock sfLock(&((CShapefile*)Shapefile)->ShapefileLock, TRUE); - long ncols = 0, nrows = 0; IGridHeader * header = NULL; Grid->get_Header(&header); @@ -2744,8 +2740,6 @@ STDMETHODIMP CUtils::ShapefileToGrid(IShapefile * Shpfile, VARIANT_BOOL UseShape return S_OK; } - CSingleLock sfLock(&((CShapefile*)Shpfile)->ShapefileLock, TRUE); - if (!((CShapefile*)Shpfile)->ValidateInput(Shpfile, "ShapefileToGrid", "Shpfile", VARIANT_FALSE, "Utils")) return S_OK; @@ -3589,8 +3583,6 @@ STDMETHODIMP CUtils::ReprojectShapefile(IShapefile* sf, IGeoProjection* source, return S_OK; } - CSingleLock sfLock(&((CShapefile*) sf)->ShapefileLock, TRUE); - OGRSpatialReference* ref1 = ((CGeoProjection*)source)->get_SpatialReference(); OGRSpatialReference* ref2 = ((CGeoProjection*)target)->get_SpatialReference(); @@ -4129,8 +4121,6 @@ STDMETHODIMP CUtils::GridStatisticsToShapefile(IGrid* grid, IShapefile* sf, VARI return S_OK; } - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - ShpfileType type; sf->get_ShapefileType(&type); if (type != SHP_POLYGON && type != SHP_POLYGONM && type != SHP_POLYGONZ) { @@ -6054,4 +6044,4 @@ STDMETHODIMP CUtils::LineProjectDistanceTo(IShape* sourceLine, IShape* reference return S_OK; } -// ReSharper restore CppUseAuto \ No newline at end of file +// ReSharper restore CppUseAuto diff --git a/src/COM classes/Utils_Shapefile.cpp b/src/COM classes/Utils_Shapefile.cpp index 4e8b09ed..09a66263 100644 --- a/src/COM classes/Utils_Shapefile.cpp +++ b/src/COM classes/Utils_Shapefile.cpp @@ -8,8 +8,6 @@ // ******************************************************** VARIANT_BOOL CUtils::SaveOutputShapefile(BSTR outputFilename, IShapefile* sf, VARIANT_BOOL overwrite) { - if (!sf) return VARIANT_FALSE; - if (Utility::FileExistsW(outputFilename)) { if (!overwrite) { @@ -23,7 +21,6 @@ VARIANT_BOOL CUtils::SaveOutputShapefile(BSTR outputFilename, IShapefile* sf, VA } } - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); VARIANT_BOOL vb; sf->SaveAsEx(outputFilename, VARIANT_TRUE, VARIANT_FALSE, &vb); @@ -43,8 +40,6 @@ VARIANT_BOOL CUtils::SaveOutputShapefile(BSTR outputFilename, IShapefile* sf, VA // ******************************************************** void CUtils::CloseOutputShapefile(IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); sf->StopAppendMode(); VARIANT_BOOL vb; @@ -71,7 +66,6 @@ bool CUtils::CheckInputShapefile(IShapefile* input) IShapefile* CUtils::CloneInput(IShapefile* input, BSTR outputFilename, VARIANT_BOOL overwrite) { if (!CheckInputShapefile(input)) return S_OK; - CSingleLock sfLock(&((CShapefile*)input)->ShapefileLock, TRUE); IShapefile* result = NULL; input->Clone(&result); @@ -90,8 +84,6 @@ IShapefile* CUtils::CloneInput(IShapefile* input, BSTR outputFilename, VARIANT_B STDMETHODIMP CUtils::FixUpShapes(IShapefile* subject, VARIANT_BOOL SelectedOnly, BSTR outputFilename, VARIANT_BOOL overwrite, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!CheckInputShapefile(subject)) return S_OK; - CSingleLock sfLock(&((CShapefile*)subject)->ShapefileLock, TRUE); *retVal = VARIANT_FALSE; @@ -118,7 +110,6 @@ STDMETHODIMP CUtils::BufferByDistance(IShapefile* subject, DOUBLE Distance, LONG *retVal = VARIANT_FALSE; if (!CheckInputShapefile(subject)) return S_OK; - CSingleLock sfLock(&((CShapefile*)subject)->ShapefileLock, TRUE); IShapefile* result = NULL; @@ -158,8 +149,6 @@ STDMETHODIMP CUtils::BufferByDistance(IShapefile* subject, DOUBLE Distance, LONG STDMETHODIMP CUtils::ExplodeShapes(IShapefile* subject, VARIANT_BOOL SelectedOnly, BSTR outputFilename, VARIANT_BOOL Overwrite, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!CheckInputShapefile(subject)) return S_OK; - CSingleLock sfLock(&((CShapefile*)subject)->ShapefileLock, TRUE); *retVal = VARIANT_FALSE; @@ -182,9 +171,6 @@ STDMETHODIMP CUtils::ExportSelection(IShapefile* subject, BSTR outputFilename, V { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - if (!CheckInputShapefile(subject)) return S_OK; - CSingleLock sfLock(&((CShapefile*)subject)->ShapefileLock, TRUE); - *retVal = VARIANT_FALSE; IShapefile* result = CloneInput(subject, outputFilename, Overwrite); diff --git a/src/ComHelpers/CallbackHelper.h b/src/ComHelpers/CallbackHelper.h index e877bd09..a6f0ecf5 100644 --- a/src/ComHelpers/CallbackHelper.h +++ b/src/ComHelpers/CallbackHelper.h @@ -1,7 +1,4 @@ #pragma once - -#include "MapWinGIS_i.h" - namespace CallbackHelper { void Progress(ICallback* callback, int index, double count, const char* message, BSTR& key, long& lastPercent); diff --git a/src/ComHelpers/ChartsHelper.cpp b/src/ComHelpers/ChartsHelper.cpp index 2fb549d2..5cb5611c 100644 --- a/src/ComHelpers/ChartsHelper.cpp +++ b/src/ComHelpers/ChartsHelper.cpp @@ -1,5 +1,4 @@ #include "stdafx.h" -#include "Shapefile.h" #include "ChartsHelper.h" // ******************************************************************* @@ -9,7 +8,6 @@ bool ChartsHelper::ReadChartFields(IShapefile* sf, std::vector* values) { if (!sf) return false; - CSingleLock sfLock(&((CShapefile*) sf)->ShapefileLock, TRUE); struct FieldIndex { @@ -92,7 +90,6 @@ bool ChartsHelper::ReadChartFields(IShapefile* sf, std::vector* values) bool ChartsHelper::ReadChartField(IShapefile* sf, std::vector* values, int fieldIndex) { if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); IField* fld = NULL; sf->get_Field(fieldIndex, &fld); diff --git a/src/ComHelpers/FieldHelper.cpp b/src/ComHelpers/FieldHelper.cpp index 7bc243c4..16d2fd06 100644 --- a/src/ComHelpers/FieldHelper.cpp +++ b/src/ComHelpers/FieldHelper.cpp @@ -10,8 +10,6 @@ long FieldHelper::FindNewShapeID(IShapefile* sf, long FieldIndex) { if (!sf) return 0; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - CComPtr table = NULL; sf->get_Table(&table); if (!table) return 0; diff --git a/src/ComHelpers/LabelsHelper.cpp b/src/ComHelpers/LabelsHelper.cpp index ffe560dc..14715263 100644 --- a/src/ComHelpers/LabelsHelper.cpp +++ b/src/ComHelpers/LabelsHelper.cpp @@ -8,13 +8,9 @@ // Should be called after change of shapefile type (CreateNew, Open, Resource, Close) void LabelsHelper::UpdateLabelsPositioning(IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); ShpfileType type = ShapefileHelper::GetShapeType2D(sf); CComPtr labels = NULL; sf->get_Labels(&labels); - sfLock.Unlock(); - if (labels) { if (type == SHP_POINT || type == SHP_MULTIPOINT) diff --git a/src/Control/Map_Drawing.cpp b/src/Control/Map_Drawing.cpp index 5bdd8862..0914757d 100644 --- a/src/Control/Map_Drawing.cpp +++ b/src/Control/Map_Drawing.cpp @@ -901,12 +901,18 @@ void CMapView::DrawLayers(const CRect & rcBounds, Gdiplus::Graphics* graphics, b if (visible) { - // This is used for regular & dynamic ogr 'shapefile' layers - auto _DrawShapeFileCore = [&](CComPtr sf) { - sfDrawer.Draw(rcBounds, sf); - LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); - LayerDrawer::DrawCharts(l, chartDrawer, vpAboveParentLayer); - }; + if (l->IsDynamicOgrLayer()) + { + OgrDynamicLoader* loader = l->GetOgrLoader(); + if (loader) { + // Clear the finished tasks & send events for them: + for (auto task : loader->AwaitTasks()) { + FireBackgroundLoadingFinished(task->Id, task->LayerHandle, task->FeatureCount, task->LoadedCount); + } + } + // Try to get the data loaded so far: + l->UpdateShapefile(layerHandle); + } if (l->IsImage()) { @@ -916,18 +922,7 @@ void CMapView::DrawLayers(const CRect & rcBounds, Gdiplus::Graphics* graphics, b LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); } - else if (l->IsShapefile() || l->IsDynamicOgrLayer()) - { - CComPtr sf = NULL; - if (l->IsDynamicOgrLayer()) - { - // Try to get the data loaded so far: - l->UpdateShapefile(); - - // Get the shapefile - l->QueryShapefile(&sf); - } - else + else if (l->IsShapefile()) { // grab extents from shapefile in case they changed l->UpdateExtentsFromDatasource(); @@ -935,13 +930,15 @@ void CMapView::DrawLayers(const CRect & rcBounds, Gdiplus::Graphics* graphics, b if (!l->extents.Intersects(_extents)) continue; + CComPtr sf = NULL; // layerBuffer == true indicates we're drawing the non-Volatile layers if (l->QueryShapefile(&sf) && ShapefileHelper::IsVolatile(sf) == layerBuffer) continue; - } - // Perform the draw: - _DrawShapeFileCore(sf); + sfDrawer.Draw(rcBounds, sf); + + LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); + LayerDrawer::DrawCharts(l, chartDrawer, vpAboveParentLayer); } } } diff --git a/src/Control/Map_Shapefile.cpp b/src/Control/Map_Shapefile.cpp index fe10e73c..16a15a03 100644 --- a/src/Control/Map_Shapefile.cpp +++ b/src/Control/Map_Shapefile.cpp @@ -1086,8 +1086,6 @@ long CMapView::GetShapePointFontCharListID(long LayerHandle, long Shape) STDMETHODIMP CShapefile::SaveAsEx(BSTR newFilename, VARIANT_BOOL stopEditing, VARIANT_BOOL unboundFile, VARIANT_BOOL* retVal) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); - CSingleLock sfLock(&ShapefileLock, TRUE); - if (unboundFile) { Save(NULL, retVal); diff --git a/src/Control/Map_Snapshot.cpp b/src/Control/Map_Snapshot.cpp index 77cd5b3d..95a34c38 100644 --- a/src/Control/Map_Snapshot.cpp +++ b/src/Control/Map_Snapshot.cpp @@ -1,5 +1,5 @@ /************************************************************************************** - * File name: Map_Snamshot.cpp + * File name: Map_Snapshot.cpp * * Project: MapWindow Open Source (MapWinGis ActiveX control) * Description: implementation of the snapshot functions. diff --git a/src/Drawing/ChartDrawing.cpp b/src/Drawing/ChartDrawing.cpp index 422278f7..218ae9d3 100644 --- a/src/Drawing/ChartDrawing.cpp +++ b/src/Drawing/ChartDrawing.cpp @@ -61,7 +61,6 @@ bool CChartDrawer::PrepareValues(IShapefile* sf, ICharts* charts, ChartOptions* std::vector& arr, std::vector& values) { CShapefile* sfClass = (CShapefile*)sf; - CSingleLock sfLock(&(sfClass->ShapefileLock), TRUE); if (!ChartsHelper::ReadChartFields(sfClass, &values)) { return false; @@ -129,7 +128,6 @@ bool CChartDrawer::PrepareValues(IShapefile* sf, ICharts* charts, ChartOptions* bool CChartDrawer::NormalizeValues(ICharts* charts, IShapefile* sf, ChartOptions* options, vector values) { CShapefile* sfClass = (CShapefile*)sf; - CSingleLock sfLock(&(sfClass->ShapefileLock), TRUE); long numBars; charts->get_NumFields(&numBars); @@ -170,7 +168,6 @@ bool CChartDrawer::NormalizeValues(ICharts* charts, IShapefile* sf, ChartOptions void CChartDrawer::DrawCharts(IShapefile* sf) { if (!sf) return; - CSingleLock sfLock(&((CShapefile*) sf)->ShapefileLock, TRUE); REAL dx = _graphics->GetDpiX(); @@ -269,9 +266,6 @@ void CChartDrawer::DrawPieCharts(IShapefile* sf, ICharts* charts, ChartOptions* std::vector& arr, std::vector& brushes, std::vector& brushesDimmed, long numBars, Pen& pen, CString sFormat, CBrush& brushFrame, CPen& penFrame, Gdiplus::Font* gdiPlusFont) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - long collisionBuffer = ChartsHelper::GetCollisionBuffer(charts); REAL offsetX = static_cast(ChartsHelper::GetOffsetX(charts)); REAL offsetY = static_cast(ChartsHelper::GetOffsetY(charts)); @@ -573,9 +567,6 @@ void CChartDrawer::DrawBarCharts(IShapefile* sf, ICharts* charts, ChartOptions* long numBars, Pen& pen, CString sFormat, bool vertical, CBrush& brushFrame, CPen& penFrame, Gdiplus::Font* gdiPlusFont) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - long collisionBuffer = ChartsHelper::GetCollisionBuffer(charts); long offsetX = ChartsHelper::GetOffsetX(charts); long offsetY = ChartsHelper::GetOffsetY(charts); diff --git a/src/Drawing/ShapefileDrawing.cpp b/src/Drawing/ShapefileDrawing.cpp index 41e13df9..42051b9a 100644 --- a/src/Drawing/ShapefileDrawing.cpp +++ b/src/Drawing/ShapefileDrawing.cpp @@ -62,7 +62,6 @@ enum tkDrawingShape bool CShapefileDrawer::Draw(const CRect & rcBounds, IShapefile* sf) { if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); _shapefile = reinterpret_cast(sf); diff --git a/src/Editor/GroupOperation.cpp b/src/Editor/GroupOperation.cpp index ea4bc34c..0dacd324 100644 --- a/src/Editor/GroupOperation.cpp +++ b/src/Editor/GroupOperation.cpp @@ -17,7 +17,6 @@ bool GroupOperation::Run(tkCursorMode cursorMode, long layerHandle, IShapefile* errorCode = tkUNEXPECTED_NULL_PARAMETER; return false; } - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); vector indices; if (!SelectionHelper::SelectWithShapeBounds(sf, shp, indices)) @@ -54,8 +53,6 @@ bool GroupOperation::Run(tkCursorMode cursorMode, long layerHandle, IShapefile* // *************************************************************** bool GroupOperation::ClipByPolygon(tkCursorMode cursorMode, long layerHandle, IShapefile* sf, vector& indices, IShape*polygon, IUndoList* undoList, int& errorCode) { - if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); GEOSGeometry* gPoly = GeosConverter::ShapeToGeom(polygon); if (!gPoly) { errorCode = tkCANT_CONVERT_SHAPE_GEOS; @@ -151,8 +148,6 @@ bool GroupOperation::ClipByPolygon(tkCursorMode cursorMode, long layerHandle, IS bool GroupOperation::SplitByPolyline(long layerHandle, IShapefile* sf, vector& indices, IShape* polyline, IUndoList* undoList, int& errorCode) { - if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); vector deleteList; long mwShapeIdIndex = ShapefileHelper::GetMWShapeIdIndex(sf); diff --git a/src/MapWinGIS.idl b/src/MapWinGIS.idl index e365653f..fffad99b 100644 --- a/src/MapWinGIS.idl +++ b/src/MapWinGIS.idl @@ -6362,7 +6362,6 @@ interface IOgrLayer : IDispatch{ [propget, id(49)] HRESULT ActiveShapeType([out, retval] ShpfileType* pVal); [propput, id(49)] HRESULT ActiveShapeType([in] ShpfileType newVal); [propget, id(50)] HRESULT IsExternalDatasource([out, retval] VARIANT_BOOL* pVal); - [id(51)] HRESULT ExtendFromQuery([in]BSTR sql, [out, retval]VARIANT_BOOL* retVal); }; [ diff --git a/src/Ogr/Ogr2RawData.cpp b/src/Ogr/Ogr2RawData.cpp index 77afe745..931a87e5 100644 --- a/src/Ogr/Ogr2RawData.cpp +++ b/src/Ogr/Ogr2RawData.cpp @@ -8,7 +8,8 @@ // ************************************************************* // Layer2RawData() // ************************************************************* -bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, OgrLoadingTask* callback) +bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, + vector& categories, OgrLoadingTask* callback) { if (!layer || !extents || !loader) return false; @@ -32,9 +33,11 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad OGRFeature *poFeature; VARIANT_BOOL vb; + bool generateLabels = false; // ! Don't forget to delete the shape records if data is not used ! vector shapeData; + vector fieldNames; { // Locking the provider in this section CSingleLock lock(&loader->ProviderLock, TRUE); @@ -42,8 +45,16 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad CStringA fidColumn = layer->GetFIDColumn(); bool hasFID = fidColumn.GetLength() > 0; + map fids; OGRFeatureDefn *poFields = layer->GetLayerDefn(); + OgrLabelsHelper::LabelFields labelFields; + bool hasLabels = false; + if (m_globalSettings.saveOgrLabels) + hasLabels = OgrLabelsHelper::GetLabelFields(layer, labelFields); + + generateLabels = !hasLabels && numFeatures <= loader->GetMaxCacheCount(); + layer->ResetReading(); while ((poFeature = layer->GetNextFeature()) != NULL) { @@ -59,9 +70,15 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad ShapeRecordData* data = new ShapeRecordData(); shp->ExportToBinary(&(data->Shape), &vb); + if (generateLabels) + { + ((CShape*)shp)->get_LabelPositionAuto(loader->LabelPosition, + data->LabelX, data->LabelY, data->LabelRotation, loader->LabelOrientation); + } + shp->Release(); - FieldsToShapeRecord(poFields, poFeature, data, hasFID); + FieldsToShapeRecord(poFields, poFeature, data, hasFID, hasLabels, labelFields); shapeData.push_back(data); OGRFeature::DestroyFeature(poFeature); @@ -73,6 +90,13 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad return false; } } + + // If we need to generate labels or apply catagories, ensure we have field names: + if ((generateLabels || categories.size() > 0) && !OgrHelper::GetFieldList(layer, fieldNames)) { + Debug::WriteWithThreadId("Task cancelling.", DebugOgrLoading); + DeleteAndClearShapeData(shapeData); + return false; + } } // Check for a cancel request: @@ -85,6 +109,17 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad // Process loaded data: if (shapeData.size() > 0) { + // Generate labels + if (generateLabels) { + CStringW error; + GenerateLabels(shapeData, fieldNames, loader->LabelExpression, error, loader); + } + + // Apply categories + if (categories.size() > 0) { + ApplyCategories(shapeData, fieldNames, categories, loader); + } + // copy to the location accessible by map rendering loader->PutData(shapeData); callback->LoadedCount = shapeData.size(); @@ -111,10 +146,237 @@ void Ogr2RawData::DeleteAndClearShapeData(vector& shapeData) { shapeData.clear(); } +// ************************************************************* +// ApplyCategories() +// ************************************************************* +void Ogr2RawData::ApplyCategories(vector& data, vector& fields, vector& categories, OgrDynamicLoader* loader) +{ + for (size_t i = 0; i < categories.size(); i++) + { + if (loader->HaveWaitingTasks()) { + return; + } + + categories[i]->skip = false; + CComVariant* minVal = &categories[i]->minValue; + CComVariant* maxVal = &categories[i]->maxValue; + + if (categories[i]->classificationField == -1) + categories[i]->valueType = cvExpression; + + switch (categories[i]->valueType) + { + case cvSingleValue: + if (minVal->vt == VT_EMPTY) + categories[i]->skip = true; + break; + case cvRange: + if (minVal->vt == VT_EMPTY || maxVal->vt == VT_EMPTY) + categories[i]->skip = true; + break; + } + } + + CString format = "%g"; + USES_CONVERSION; + for (size_t i = 0; i < categories.size(); i++) + { + if (categories[i]->skip) continue; + + int fieldIndex = categories[i]->classificationField; + + CComVariant* minVal = &categories[i]->minValue; + CComVariant* maxVal = &categories[i]->maxValue; + + tkCategoryValue valueType = categories[i]->valueType; + + if (loader->HaveWaitingTasks()) { + return; + } + + CustomExpression expr; + CStringW error; + if (valueType == cvExpression) + { + expr.SetFields(fields); + if (!expr.Parse(categories[i]->expression, true, error)) + continue; + } + + for (size_t j = 0; j < data.size(); j++) + { + if (data[j]->CategoryIndex != -1) continue; + + switch (valueType) + { + case cvSingleValue: + { + // CComVar does have oveloaded == operator for VARIANT type + if (*minVal == *data[j]->Row->values[fieldIndex]) { + data[j]->CategoryIndex = i; + break; + } + } + break; + case cvRange: + // CComVar does have oveloaded == operator for VARIANT type + if (*minVal < *data[j]->Row->values[fieldIndex] && + *maxVal > *data[j]->Row->values[fieldIndex]) + { + data[j]->CategoryIndex = i; + break; + } + break; + case cvExpression: + { + if (!PopulateExpressionFields(data, i, expr)) + continue; + + // no need to delete the result + CExpressionValue* val = expr.Calculate(error); + if (val) + { + CExpressionValue* result = expr.Calculate(error); + if (result) + { + if (result->isBoolean() && result->bln()) { + data[j]->CategoryIndex = i; + } + } + } + break; + } + } + } + } +} + +// ************************************************************* +// GetLabelFieldIndex() +// ************************************************************* +int Ogr2RawData::GetLabelFieldIndex(CStringW expression, vector& fields) +{ + expression = expression.Trim(); + if (expression.Mid(0, 1) == L"[" && expression.Mid(expression.GetLength() - 1, 1) == L"]") + expression = expression.Mid(1, expression.GetLength() - 2).Trim(); + + for (size_t i = 0; i < fields.size(); i++) + { + if (expression.CompareNoCase(fields[i]) == 0) + return i; + } + return -1; +} + +// ************************************************************* +// PopulateExpressionFields() +// ************************************************************* +bool Ogr2RawData::PopulateExpressionFields(vector& data, int rowIndex, CustomExpression& expr) +{ + bool success = false; + + for (int j = 0; j < expr.get_NumFields(); j++) + { + int fieldIndex = expr.get_FieldIndex(j); + + VARIANT* var = data[rowIndex]->Row->GetValue(fieldIndex); + if (var) + { + switch (var->vt) + { + case VT_BSTR: expr.put_FieldValue(j, var->bstrVal); break; + case VT_I4: expr.put_FieldValue(j, (double)var->lVal); break; + case VT_R8: expr.put_FieldValue(j, (double)var->dblVal); break; + } + success = true; + } + } + return success; +} + // ************************************************************* // FieldsToShapeRecord() // ************************************************************* -void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid) +bool Ogr2RawData::GenerateLabels(vector& data, vector& fields, CStringW expression, CStringW& error, OgrDynamicLoader* loader ) +{ + if (expression.GetLength() == 0) return false; + + CString format = "%g"; + + // maybe it's single field expression; no need for parsing then + USES_CONVERSION; + int fieldIndex = GetLabelFieldIndex(expression, fields); + if (fieldIndex != -1) + { + for (size_t i = 0; i < data.size(); i++) + { + if (loader->HaveWaitingTasks()) { + return false; + } + + VARIANT* var = data[i]->Row->GetValue(fieldIndex); + if (var) + { + switch (var->vt) + { + case VT_BSTR: + data[i]->LabelText = OLE2W(var->bstrVal); + break; + case VT_I4: + data[i]->LabelText.Format(L"%d", var->lVal); + break; + case VT_R8: + data[i]->LabelText = Utility::FormatNumber(var->dblVal, format); + break; + } + } + } + return true; + } + + CustomExpression expr; + expr.SetFields(fields); + + CStringW err; + + if (expr.Parse(W2A(expression), true, error)) + { + for (size_t i = 0; i < data.size(); i++) + { + if (loader->HaveWaitingTasks()) return false; + + if (!PopulateExpressionFields(data, i, expr)) + continue; + + // no need to delete the result + CExpressionValue* val = expr.Calculate(err); + if (val) + { + if (val->isBoolean()) + { + data[i]->LabelText = val->bln() ? L"true" : L"false"; + } + else if (val->IsDouble()) + { + data[i]->LabelText = Utility::FormatNumber(val->dbl(), format); + + } + else if (val->isString()) + { + data[i]->LabelText = val->str(); + } + } + } + return true; + } + return false; +} + +// ************************************************************* +// FieldsToShapeRecord() +// ************************************************************* +void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid, + bool hasLabels, OgrLabelsHelper::LabelFields& fields) { if (hasFid) { @@ -148,5 +410,13 @@ void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFe var->bstrVal = A2BSTR(poFeature->GetFieldAsString(iFld)); // BSTR will be cleared by CComVariant destructor } data->Row->values.push_back(var); + + if (hasLabels) + { + if (iFld == fields.X) data->LabelX = var->dblVal; + if (iFld == fields.Y) data->LabelY = var->dblVal; + if (iFld == fields.Text) data->LabelText = OgrHelper::OgrString2Unicode(poFeature->GetFieldAsString(iFld)); + if (iFld == fields.Rotation) data->LabelRotation = var->dblVal; + } } } diff --git a/src/Ogr/Ogr2RawData.h b/src/Ogr/Ogr2RawData.h index c7941237..ab5c8b9c 100644 --- a/src/Ogr/Ogr2RawData.h +++ b/src/Ogr/Ogr2RawData.h @@ -8,9 +8,14 @@ class Ogr2RawData { public: - static bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, OgrLoadingTask* callback); + static bool Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, vector& categories, OgrLoadingTask* callback); private: - static void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid); + static void FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid, bool hasLabels, OgrLabelsHelper::LabelFields& labelFields); + static bool GenerateLabels(vector& data, vector& fields, CStringW expression, CStringW& error, OgrDynamicLoader* loader); + static void UpdateLabelsAndCategories(vector&data, OgrDynamicLoader* loader, bool hasLabels); + static int GetLabelFieldIndex(CStringW expression, vector& fields); + static void ApplyCategories(vector& data, vector& fields, vector& categories, OgrDynamicLoader* loader); + static bool PopulateExpressionFields(vector& data, int rowIndex, CustomExpression& expr); static void DeleteAndClearShapeData(vector& data); }; diff --git a/src/Ogr/Ogr2Shape.cpp b/src/Ogr/Ogr2Shape.cpp index 5c7da73f..7a5863fb 100644 --- a/src/Ogr/Ogr2Shape.cpp +++ b/src/Ogr/Ogr2Shape.cpp @@ -110,9 +110,6 @@ IShapefile* Ogr2Shape::CreateShapefile(OGRLayer* layer, ShpfileType activeShapeT // ************************************************************* void Ogr2Shape::CopyFields(OGRLayer* layer, IShapefile* sf) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - IField * fld = NULL; VARIANT_BOOL vb; @@ -170,131 +167,12 @@ void Ogr2Shape::CopyFields(OGRLayer* layer, IShapefile* sf) } } -// ************************************************************* -// ExtendShapefile() -// ************************************************************* -bool Ogr2Shape::ExtendShapefile(OGRLayer* layer, IShapefile* sf, bool loadLabels, ICallback* callback) -{ - layer->ResetReading(); - - int numFeatures = static_cast(layer->GetFeatureCount()); - - int count = 0; - long percent = 0; - USES_CONVERSION; - CComBSTR key = L""; - - OGRFeature *poFeature; - VARIANT_BOOL vbretval; - - CStringA name = layer->GetFIDColumn(); - bool hasFID = name.GetLength() > 0; - ShpfileType shpType; - sf->get_ShapefileType(&shpType); - - map fids; - - OGRFeatureDefn *poFields = layer->GetLayerDefn(); - - CComPtr labels = NULL; - sf->get_Labels(&labels); - - OgrLabelsHelper::LabelFields labelFields; - if (loadLabels) { - if (!OgrLabelsHelper::GetLabelFields(layer, labelFields)) - loadLabels = false; - } - - ShpfileType targetType = ShapefileHelper::GetShapeType(sf); - - while ((poFeature = layer->GetNextFeature()) != NULL) - { - CallbackHelper::Progress(callback, count, numFeatures, "Converting geometries...", key.m_str, percent); - count++; - - OGRGeometry *oGeom = poFeature->GetGeometryRef(); - - IShape* shp = NULL; - if (oGeom) - { - shpType = OgrConverter::GeometryType2ShapeType(oGeom->getGeometryType()); - if (shpType != targetType) - { - goto next_feature; - } - - shp = OgrConverter::GeometryToShape(oGeom, ShapeUtility::IsM(shpType)); - } - - if (!shp) - { - // insert null shape so that client can still access it - ComHelper::CreateShape(&shp); - } - - // Get number of shapes already loaded - long numShapes; - sf->get_NumShapes(&numShapes); - - // Check if this OGR_FID is already in the featureset - long replaceIndex = -1; - long index = numShapes; - if (hasFID) { - CComVariant fid_var; - fid_var.vt = VT_I4; - fid_var.lVal = static_cast(poFeature->GetFID()); - - for (int i = 0; i < numShapes; i++) { - VARIANT pVal; - sf->get_CellValue(0, i, &pVal); - long fid = 0; - lVal(pVal, fid); - if (pVal.lVal == fid_var.lVal) { - replaceIndex = i; - break; - } - } - } - - // Update index in case we are replacing: - index = replaceIndex > 0 ? replaceIndex : index; - - // Insert or replace the shape: - if (replaceIndex > 0) - sf->EditUpdateShape(index, shp, &vbretval); - else - sf->EditInsertShape(shp, &index, &vbretval); - - // No longer need this: - shp->Release(); - - // Set feature id - if (hasFID) { - CComVariant fid_var; - fid_var.vt = VT_I4; - fid_var.lVal = static_cast(poFeature->GetFID()); - sf->EditCellValue(0, index, fid_var, &vbretval); - } - - CopyValues(poFields, poFeature, sf, hasFID, index, loadLabels, labelFields); - - next_feature: - OGRFeature::DestroyFeature(poFeature); - } - CallbackHelper::ProgressCompleted(callback); - - sf->RefreshExtents(&vbretval); - ShapefileHelper::ClearShapefileModifiedFlag(sf); // inserted shapes were marked as modified, correct this - return true; -} - // ************************************************************* // FillShapefile() // ************************************************************* bool Ogr2Shape::FillShapefile(OGRLayer* layer, IShapefile* sf, int maxFeatureCount, bool loadLabels, ICallback* callback, bool& isTrimmed) { if (!sf || !layer) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); layer->ResetReading(); @@ -402,9 +280,6 @@ bool isXBaseLogicalTrue(wchar_t c) void Ogr2Shape::CopyValues(OGRFeatureDefn* poFields, OGRFeature* poFeature, IShapefile* sf, bool hasFID, long numShapes, bool loadLabels, OgrLabelsHelper::LabelFields labelFields) { - if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); - double x = 0.0, y = 0.0, rotation = 0; CStringW text; diff --git a/src/Ogr/Ogr2Shape.h b/src/Ogr/Ogr2Shape.h index b0114063..90effb6c 100644 --- a/src/Ogr/Ogr2Shape.h +++ b/src/Ogr/Ogr2Shape.h @@ -12,7 +12,6 @@ class Ogr2Shape static bool FillShapefile(OGRLayer* layer, IShapefile* sf, int maxFeatureCount, bool loadLabels, ICallback* callback, bool& isTrimmed); static void ReadGeometryTypes(OGRLayer* layer, set& types, bool readAll); static void GeometryTypesToShapeTypes(set& types, vector& result); - static bool ExtendShapefile(OGRLayer* layer, IShapefile* sf, bool loadLabels, ICallback* callback); private: static void CopyValues(OGRFeatureDefn* poFields, OGRFeature* poFeature, IShapefile* sf, bool hasFID, long numShapes, bool loadLabels, OgrLabelsHelper::LabelFields labelFields); static void CopyFields(OGRLayer* layer, IShapefile* sf); diff --git a/src/Ogr/OgrLoader.cpp b/src/Ogr/OgrLoader.cpp index 9c898a64..961ff2b9 100644 --- a/src/Ogr/OgrLoader.cpp +++ b/src/Ogr/OgrLoader.cpp @@ -73,8 +73,9 @@ void OgrDynamicLoader::CancelAllTasks() // ********************************************** // ClearFinishedTasks() // ********************************************** -void OgrDynamicLoader::ClearFinishedTasks() +vector OgrDynamicLoader::ClearFinishedTasks() { + vector tasks; CSingleLock queueLock(&QueueLock, TRUE); std::queue unfqueue; @@ -90,6 +91,7 @@ void OgrDynamicLoader::ClearFinishedTasks() if (!task->Cancelled) { // If succesful return a clone: OgrLoadingTask* infoClone = task->Clone(); + tasks.push_back(infoClone); } delete task; @@ -97,13 +99,16 @@ void OgrDynamicLoader::ClearFinishedTasks() // Replace queue with the unfinished items queue Queue.swap(unfqueue); + + return tasks; } // ********************************************** // AwaitTasks() // ********************************************** -void OgrDynamicLoader::AwaitTasks() +vector OgrDynamicLoader::AwaitTasks() { + vector tasks; CSingleLock queueLock(&QueueLock, TRUE); while (!Queue.empty()) @@ -114,13 +119,19 @@ void OgrDynamicLoader::AwaitTasks() queueLock.Unlock(); // Unlock briefly so other threads can fetch Sleep(10); queueLock.Lock(); - continue; // Try next + continue; + } + + if (!task->Cancelled) { // If succesful return a clone: + OgrLoadingTask* infoClone = task->Clone(); + tasks.push_back(infoClone); } - else - { + delete task; } - } + + return tasks; + } // ********************************************** diff --git a/src/Ogr/OgrLoader.h b/src/Ogr/OgrLoader.h index d17c4611..4e882846 100644 --- a/src/Ogr/OgrLoader.h +++ b/src/Ogr/OgrLoader.h @@ -57,6 +57,7 @@ class OgrDynamicLoader vector Data; public: + ::CCriticalSection ShapefileLock; ::CCriticalSection LoadingLock; ::CCriticalSection ProviderLock; @@ -79,8 +80,8 @@ class OgrDynamicLoader void SetMaxCacheCount(int value) { _maxCacheCount = value; } bool CanLoad(int featureCount) { return featureCount < GetMaxCacheCount(); } - void ClearFinishedTasks(); - void AwaitTasks(); + vector ClearFinishedTasks(); + vector AwaitTasks(); vector FetchData(); void PutData(vector shapeData); diff --git a/src/Ogr/Shape2Ogr.cpp b/src/Ogr/Shape2Ogr.cpp index bce76a65..84881fa0 100644 --- a/src/Ogr/Shape2Ogr.cpp +++ b/src/Ogr/Shape2Ogr.cpp @@ -13,8 +13,6 @@ // ************************************************************* bool Shape2Ogr::Shapefile2OgrLayer(IShapefile* sf, OGRLayer* poLayer, bool saveLabels, ICallback* callback /*= NULL*/) { - if (!sf) return false; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); ShapefileFieldsToOgr(sf, poLayer); if (m_globalSettings.saveOgrLabels) { @@ -400,7 +398,6 @@ int Shape2Ogr::SaveShapefileChanges(OGRLayer* layer, IShapefile* sf, long shapeC errors.clear(); if (!sf || !layer || shapeCmnIndex == -1) return 0; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); OGRFeatureDefn* fields = layer->GetLayerDefn(); int fieldCount = fields->GetFieldCount(); diff --git a/src/Processing/ClipperConverter.cpp b/src/Processing/ClipperConverter.cpp index b80fc6f3..614b6af1 100644 --- a/src/Processing/ClipperConverter.cpp +++ b/src/Processing/ClipperConverter.cpp @@ -268,7 +268,6 @@ IShape* ClipperConverter::ClipPolygon(IShape* shapeClip, IShape* shapeSubject, P void ClipperConverter::AddPolygons(IShapefile* sf, ClipperLib::Clipper& clp, ClipperLib::PolyType clipType, bool selectedOnly) { if (!sf) return; - CSingleLock sfLock(&((CShapefile*)sf)->ShapefileLock, TRUE); long numShapes; sf->get_NumShapes(&numShapes); diff --git a/src/Shapefile/GeoProcessing.cpp b/src/Shapefile/GeoProcessing.cpp index 4c77fe54..fb616e08 100644 --- a/src/Shapefile/GeoProcessing.cpp +++ b/src/Shapefile/GeoProcessing.cpp @@ -9,12 +9,6 @@ // **************************************************************** void GeoProcessing::CopyFields(IShapefile* sfSubject, IShapefile* sfOverlay, IShapefile* sfResult, map& fieldMap, bool mergeFields) { - // don't check sfOverlay, which may deliberately be null - if (!sfSubject || !sfResult) return; - - CSingleLock sfSubjectLock(&((CShapefile*)sfSubject)->ShapefileLock, TRUE); - CSingleLock sfResultLock(&((CShapefile*)sfResult)->ShapefileLock, TRUE); - // fields of the subject shapefile LONG numFields, position; VARIANT_BOOL vbretval; @@ -24,7 +18,6 @@ void GeoProcessing::CopyFields(IShapefile* sfSubject, IShapefile* sfOverlay, ISh // passing the fields of overlay shapefile if (sfOverlay) { - CSingleLock sfOverlayLock(&((CShapefile*)sfOverlay)->ShapefileLock, TRUE); LONG numFields2; sfOverlay->get_NumFields(&numFields2); diff --git a/src/Structures/Layer.cpp b/src/Structures/Layer.cpp index 4df04e22..f36f4a6a 100644 --- a/src/Structures/Layer.cpp +++ b/src/Structures/Layer.cpp @@ -380,14 +380,19 @@ UINT OgrAsyncLoadingThreadProc(LPVOID pParam) ogr->get_LabelExpression(&expr); loader->LabelExpression = OLE2W(expr); - bool success = Ogr2RawData::Layer2RawData(ds, &options->extents, loader, options->task); + bool success = Ogr2RawData::Layer2RawData(ds, &options->extents, loader, *options->categories, options->task); - // Fire event for this task: + options->task->Finished = true; + if (!success) { + options->task->Cancelled = true; OgrLoadingTask* task = options->task; - task->Finished = true; - task->Cancelled = !success; options->map->_FireBackgroundLoadingFinished(task->Id, task->LayerHandle, task->FeatureCount, 0); + } + loader->ClearFinishedTasks(); + + if (success) + options->map->_Redraw(RedrawAll, false, false); } layer->put_AsyncLoading(false); Debug::WriteWithThreadId("Releasing loading lock. \n", DebugOgrLoading); @@ -414,13 +419,32 @@ void Layer::LoadAsync(IMapViewCallback* mapView, Extent extents, long layerHandl // if larger extents were requested previously and features were loaded, skip the new request if (!bForce && extents.Within(loader->LastSuccessExtents)) return; + // get a copy of categories to apply them in the background thread + vector* data = new vector(); + + CComPtr sf = NULL; + this->QueryShapefile(&sf); + if (sf) + { + ShpfileType shpType = ShapefileHelper::GetShapeType(sf); + loader->IsMShapefile = ShapeUtility::IsM(shpType); + + IShapefileCategories* categories = NULL; + sf->get_Categories(&categories); + if (categories) + { + ((CShapefileCategories*)categories)->GetCategoryData(*data); + categories->Release(); + } + } + // Prepare a new OgrLoadingTask & queue it for execution OgrLoadingTask* task = new OgrLoadingTask(layerHandle); loader->EnqueueTask(task); // First fire the event, then start the thread. // This prevents race condition between the started & completed event. - AsyncLoadingParams* param = new AsyncLoadingParams(mapView, extents, this, task); + AsyncLoadingParams* param = new AsyncLoadingParams(mapView, extents, this, data, task); mapView->_FireBackgroundLoadingStarted(task->Id, layerHandle); CWinThread* thread = AfxBeginThread(OgrAsyncLoadingThreadProc, (LPVOID)param); } @@ -428,16 +452,76 @@ void Layer::LoadAsync(IMapViewCallback* mapView, Extent extents, long layerHandl //*********************************************************************** //* UpdateShapefile() //*********************************************************************** -void Layer::UpdateShapefile() +void Layer::UpdateShapefile(long layerHandle) { - if (!IsDynamicOgrLayer()) + // Get the OGR loader: + OgrDynamicLoader* loader = GetOgrLoader(); + if (!loader) return; + + { // Lock everything + CSingleLock ldLock(&loader->LoadingLock, TRUE); + CSingleLock prLock(&loader->ProviderLock, TRUE); + CSingleLock sfLock(&loader->ShapefileLock, TRUE); + + // Grab the loaded data: + vector data = loader->FetchData(); + if (data.size() == 0) return; + + USES_CONVERSION; + CComPtr sf = NULL; + if (!QueryShapefile(&sf)) return; - // Get the OGR layer: - IOgrLayer* layer = NULL; - if (!QueryOgrLayer(&layer)) return; + VARIANT_BOOL vb; + sf->EditClear(&vb); + + ShpfileType shpType; + sf->get_ShapefileType(&shpType); - ((COgrLayer*) layer)->UpdateShapefileFromOGRLoader(); + Debug::WriteWithThreadId(Debug::Format("Update shapefile: %d\n", data.size()), DebugOgrLoading); + + CComPtr table = NULL; + sf->get_Table(&table); + + CComPtr labels = NULL; + sf->get_Labels(&labels); + labels->Clear(); + + if (table) + { + CTableClass* tbl = TableHelper::Cast(table); + sf->StartEditingShapes(VARIANT_TRUE, NULL, &vb); + long count = 0; + for (size_t i = 0; i < data.size(); i++) + { + CComPtr shp = NULL; + ComHelper::CreateShape(&shp); + if (shp) + { + shp->Create(shpType, &vb); + shp->ImportFromBinary(data[i]->Shape, &vb); + sf->EditInsertShape(shp, &count, &vb); + sf->put_ShapeCategory(count, data[i]->CategoryIndex); + + tbl->UpdateTableRow(data[i]->Row, count); + data[i]->Row = NULL; // we no longer own it; it'll be cleared by Shapefile.EditClear + + if (data[i]->HasLabel()) { + CComBSTR bstr(data[i]->LabelText); + labels->AddLabel(bstr, data[i]->LabelX, data[i]->LabelY, data[i]->LabelRotation); + } + + count++; + } + } + ShapefileHelper::ClearShapefileModifiedFlag(sf); // inserted shapes were marked as modified, correct this + } + + // clean the data + for (size_t i = 0; i < data.size(); i++) { + delete data[i]; + } + } } //**************************************************** diff --git a/src/Structures/Layer.h b/src/Structures/Layer.h index d4707af5..08c22585 100644 --- a/src/Structures/Layer.h +++ b/src/Structures/Layer.h @@ -35,22 +35,31 @@ class Layer; // A structure to pass parameters to the background thread struct AsyncLoadingParams : CObject { - AsyncLoadingParams(IMapViewCallback* m, Extent e, Layer* l, OgrLoadingTask* cback) + AsyncLoadingParams(IMapViewCallback* m, Extent e, Layer* l, vector* ct, OgrLoadingTask* cback) { map = m; extents = e; layer = l; + categories = ct; task = cback; }; ~AsyncLoadingParams() { + if (categories) + { + for (size_t i = 0; i < categories->size(); i++) { + delete (*categories)[i]; + } + delete categories; + } } public: IMapViewCallback* map; Extent extents; Layer* layer; + vector* categories; OgrLoadingTask* task; // not owned by this object }; @@ -134,7 +143,7 @@ class Layer void GetExtentsAsNewInstance(IExtents** extents); bool UpdateExtentsFromDatasource(); void LoadAsync(IMapViewCallback * mapView, Extent extents, long layerHandle, bool bForce); - void UpdateShapefile(); + void UpdateShapefile(long layerHandle); void CloseDatasources(); bool IsEmpty(); bool IsDiskBased(); diff --git a/src/Structures/Structures.h b/src/Structures/Structures.h index f9fb538e..1b2da0d9 100644 --- a/src/Structures/Structures.h +++ b/src/Structures/Structures.h @@ -76,8 +76,15 @@ struct ShapeRecordData { VARIANT Shape; TableRow* Row; + double LabelX; + double LabelY; + double LabelRotation; + CStringW LabelText; + int CategoryIndex; - ShapeRecordData() + bool HasLabel() { return LabelX != 0 && LabelY != 0 && LabelText.GetLength() > 0;} + + ShapeRecordData() : LabelX(0.0), LabelY(0.0), LabelRotation(0.0), CategoryIndex(-1) { this->Row = new TableRow(); VariantInit(&Shape); From abe8edd29998763d6a9250f372fd54cb0d2bfefb Mon Sep 17 00:00:00 2001 From: Mathijs Dumon Date: Mon, 4 Nov 2019 14:32:54 +0100 Subject: [PATCH 07/15] Addendum to MWGIS-198 --- src/COM classes/Charts.cpp | 56 ++++--- src/COM classes/OgrLayer.cpp | 105 +++++++++++++ src/COM classes/OgrLayer.h | 2 + src/Control/Map_Drawing.cpp | 48 +++--- src/MapWinGIS.idl | 1 + src/Ogr/Ogr2RawData.cpp | 277 +---------------------------------- src/Ogr/Ogr2RawData.h | 13 +- src/Ogr/Ogr2Shape.cpp | 117 +++++++++++++++ src/Ogr/Ogr2Shape.h | 1 + src/Ogr/OgrLoader.cpp | 23 +-- src/Ogr/OgrLoader.h | 4 +- src/Structures/Layer.cpp | 103 ++----------- src/Structures/Layer.h | 13 +- src/Structures/Structures.h | 9 +- 14 files changed, 306 insertions(+), 466 deletions(-) diff --git a/src/COM classes/Charts.cpp b/src/COM classes/Charts.cpp index a06bd2b8..6db79b8e 100644 --- a/src/COM classes/Charts.cpp +++ b/src/COM classes/Charts.cpp @@ -1247,7 +1247,7 @@ STDMETHODIMP CCharts::Select(IExtents* BoundingBox, long Tolerance, SelectMode S *retval = VARIANT_FALSE; if (!BoundingBox) return S_OK; - if (!_chartsExist) + if (!_chartsExist || !_shapefile) { return S_OK; } @@ -1825,42 +1825,40 @@ STDMETHODIMP CCharts::LoadFromXML(BSTR Filename, VARIANT_BOOL* retVal) // ******************************************************** bool CCharts::DeserializeChartData(CPLXMLNode* node) { - if (node) - { - std::vector* data = ((CShapefile*)_shapefile)->get_ShapeVector(); - if (data) - { + if (!node || !_shapefile) + return false; + + std::vector* data = ((CShapefile*)_shapefile)->get_ShapeVector(); + if (!data) + return false; - this->Clear(); - ((CShapefile*)_shapefile)->SetChartsPositions(lpNone); + this->Clear(); + ((CShapefile*)_shapefile)->SetChartsPositions(lpNone); - CString s; - double x, y; - int i = 0; + CString s; + double x, y; + int i = 0; - node = CPLGetXMLNode(node, "Chart"); + node = CPLGetXMLNode(node, "Chart"); - int count = data->size(); - while (node && i < count) - { - s = CPLGetXMLValue(node, "X", "0.0"); - x = Utility::atof_custom(s); + int count = data->size(); + while (node && i < count) + { + s = CPLGetXMLValue(node, "X", "0.0"); + x = Utility::atof_custom(s); - s = CPLGetXMLValue(node, "Y", "0.0"); - y = Utility::atof_custom(s); + s = CPLGetXMLValue(node, "Y", "0.0"); + y = Utility::atof_custom(s); - CChartInfo* info = (*data)[i]->chart; - info->x = x; - info->y = y; - i++; + CChartInfo* info = (*data)[i]->chart; + info->x = x; + info->y = y; + i++; - node = node->psNext; - } - _chartsExist = true; - return true; - } + node = node->psNext; } - return false; + _chartsExist = true; + return true; } #pragma endregion \ No newline at end of file diff --git a/src/COM classes/OgrLayer.cpp b/src/COM classes/OgrLayer.cpp index f8bdd1e7..ce5ed654 100644 --- a/src/COM classes/OgrLayer.cpp +++ b/src/COM classes/OgrLayer.cpp @@ -12,6 +12,8 @@ #include "ShapefileCategories.h" #include "Templates.h" #include "ShapefileHelper.h" +#include "TableClass.h" +#include "TableHelper.h" // ************************************************************* // InjectShapefile() @@ -91,6 +93,80 @@ IShapefile* COgrLayer::LoadShapefile() return sf; } +//*********************************************************************** +//* UpdateShapefileFromOGRLoader() +//*********************************************************************** +void COgrLayer::UpdateShapefileFromOGRLoader() +{ + CSingleLock lock(&_loader.ProviderLock, TRUE); + if (!_shapefile) return; + + // Wait for tasks to finish loading: + _loader.AwaitTasks(); + + // Lock it all down: + CSingleLock ldLock(&_loader.LoadingLock, TRUE); + CSingleLock prLock(&_loader.ProviderLock, TRUE); + CSingleLock sfLock(&_loader.ShapefileLock, TRUE); + + // Grab the loaded data: + vector data = _loader.FetchData(); + if (data.size() == 0) return; + + VARIANT_BOOL vb; + _shapefile->EditClear(&vb); + + ShpfileType shpType; + _shapefile->get_ShapefileType(&shpType); + + Debug::WriteWithThreadId(Debug::Format("Update shapefile: %d\n", data.size()), DebugOgrLoading); + + CComPtr table = NULL; + _shapefile->get_Table(&table); + + CComPtr labels = NULL; + _shapefile->get_Labels(&labels); + labels->Clear(); + + if (table) + { + CTableClass* tbl = TableHelper::Cast(table); + _shapefile->StartEditingShapes(VARIANT_TRUE, NULL, &vb); + long count = 0; + for (size_t i = 0; i < data.size(); i++) + { + CComPtr shp = NULL; + ComHelper::CreateShape(&shp); + if (shp) + { + shp->Create(shpType, &vb); + shp->ImportFromBinary(data[i]->Shape, &vb); + _shapefile->EditInsertShape(shp, &count, &vb); + + tbl->UpdateTableRow(data[i]->Row, count); + data[i]->Row = NULL; // we no longer own it; it'll be cleared by Shapefile.EditClear + + count++; + } + } + // inserted shapes were marked as modified, correct this + ShapefileHelper::ClearShapefileModifiedFlag(_shapefile); + + // Stop 'fake' editing session + _shapefile->StopEditingShapes(VARIANT_TRUE, VARIANT_TRUE, NULL, &vb); + + // Without this, categories are not correctly applied in the drawing function: + IShapefileCategories* cat; + _shapefile->get_Categories(&cat); + cat->ApplyExpressions(); + } + + // clean the data + for (size_t i = 0; i < data.size(); i++) { + delete data[i]; + } +} + //*********************************************************************** //* get/put_Key() //*********************************************************************** @@ -314,6 +390,35 @@ bool COgrLayer::InjectLayer(GDALDataset* ds, int layerIndex, CStringW connection return OpenDatabaseLayerCore(ds, connection, layerIndex, forUpdate, VARIANT_TRUE); } +// ************************************************************* +// ExtendFromQuery() +// ************************************************************* +STDMETHODIMP COgrLayer::ExtendFromQuery(BSTR sql, VARIANT_BOOL* retVal) +{ + AFX_MANAGE_STATE(AfxGetStaticModuleState()); + + *retVal = VARIANT_FALSE; + + GDALDataset* ds = OpenDataset(W2BSTR(_connectionString), false); + if (!ds) { + ErrorMessage(tkOGR_QUERY_FAILED); + return S_OK; + } + + OGRLayer* layer = ds->ExecuteSQL(OgrHelper::Bstr2OgrString(sql), NULL, NULL); + if (!layer) + { + ErrorMessage(tkOGR_QUERY_FAILED); + GdalHelper::CloseSharedOgrDataset(ds); + return S_OK; + } + + Ogr2Shape::ExtendShapefile(layer, _shapefile, true, _globalCallback); + GdalHelper::CloseSharedOgrDataset(ds); + *retVal = VARIANT_TRUE; + return S_OK; +} + // ************************************************************* // OpenFromQuery() // ************************************************************* diff --git a/src/COM classes/OgrLayer.h b/src/COM classes/OgrLayer.h index 01eabad8..13cc714d 100644 --- a/src/COM classes/OgrLayer.h +++ b/src/COM classes/OgrLayer.h @@ -79,6 +79,7 @@ class ATL_NO_VTABLE COgrLayer : STDMETHOD(put_GlobalCallback)(/*[in]*/ ICallback * newVal); STDMETHOD(OpenDatabaseLayer)(BSTR connectionString, int layerIndex, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal); // not in public API STDMETHOD(OpenFromQuery)(BSTR connectionString, BSTR sql, VARIANT_BOOL* retVal); + STDMETHOD(ExtendFromQuery)(BSTR sql, VARIANT_BOOL* retVal); STDMETHOD(OpenFromDatabase)(BSTR connectionString, BSTR layerName, VARIANT_BOOL forUpdate, VARIANT_BOOL* retVal); STDMETHOD(Close)(); STDMETHOD(get_Name)(BSTR* retVal); @@ -173,6 +174,7 @@ class ATL_NO_VTABLE COgrLayer : public: void InjectShapefile(IShapefile* sfNew); + void UpdateShapefileFromOGRLoader(); OGRLayer* GetDatasource() { return _layer; } CPLXMLNode* SerializeCore(CString ElementName); bool DeserializeCore(CPLXMLNode* node); diff --git a/src/Control/Map_Drawing.cpp b/src/Control/Map_Drawing.cpp index 0914757d..6dfd7139 100644 --- a/src/Control/Map_Drawing.cpp +++ b/src/Control/Map_Drawing.cpp @@ -901,19 +901,6 @@ void CMapView::DrawLayers(const CRect & rcBounds, Gdiplus::Graphics* graphics, b if (visible) { - if (l->IsDynamicOgrLayer()) - { - OgrDynamicLoader* loader = l->GetOgrLoader(); - if (loader) { - // Clear the finished tasks & send events for them: - for (auto task : loader->AwaitTasks()) { - FireBackgroundLoadingFinished(task->Id, task->LayerHandle, task->FeatureCount, task->LoadedCount); - } - } - // Try to get the data loaded so far: - l->UpdateShapefile(layerHandle); - } - if (l->IsImage()) { if (!layerBuffer) continue; @@ -922,23 +909,38 @@ void CMapView::DrawLayers(const CRect & rcBounds, Gdiplus::Graphics* graphics, b LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); } - else if (l->IsShapefile()) + else if (l->IsShapefile() || l->IsDynamicOgrLayer()) + { + + CComPtr sf = NULL; + if (l->IsDynamicOgrLayer()) { - // grab extents from shapefile in case they changed - l->UpdateExtentsFromDatasource(); + // Try to get the data loaded so far: + l->UpdateShapefile(); + + // Get the shapefile + l->QueryShapefile(&sf); + } + else + { + // grab extents from shapefile in case they changed + l->UpdateExtentsFromDatasource(); - if (!l->extents.Intersects(_extents)) - continue; + if (!l->extents.Intersects(_extents)) + continue; - CComPtr sf = NULL; // layerBuffer == true indicates we're drawing the non-Volatile layers if (l->QueryShapefile(&sf) && ShapefileHelper::IsVolatile(sf) == layerBuffer) continue; - sfDrawer.Draw(rcBounds, sf); - - LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); - LayerDrawer::DrawCharts(l, chartDrawer, vpAboveParentLayer); + // Update labels & categories + l->UpdateShapefile(); + } + + // Perform the draw: + sfDrawer.Draw(rcBounds, sf); + LayerDrawer::DrawLabels(l, lblDrawer, vpAboveParentLayer); + LayerDrawer::DrawCharts(l, chartDrawer, vpAboveParentLayer); } } } diff --git a/src/MapWinGIS.idl b/src/MapWinGIS.idl index fffad99b..e365653f 100644 --- a/src/MapWinGIS.idl +++ b/src/MapWinGIS.idl @@ -6362,6 +6362,7 @@ interface IOgrLayer : IDispatch{ [propget, id(49)] HRESULT ActiveShapeType([out, retval] ShpfileType* pVal); [propput, id(49)] HRESULT ActiveShapeType([in] ShpfileType newVal); [propget, id(50)] HRESULT IsExternalDatasource([out, retval] VARIANT_BOOL* pVal); + [id(51)] HRESULT ExtendFromQuery([in]BSTR sql, [out, retval]VARIANT_BOOL* retVal); }; [ diff --git a/src/Ogr/Ogr2RawData.cpp b/src/Ogr/Ogr2RawData.cpp index 931a87e5..2c8ca95f 100644 --- a/src/Ogr/Ogr2RawData.cpp +++ b/src/Ogr/Ogr2RawData.cpp @@ -8,8 +8,7 @@ // ************************************************************* // Layer2RawData() // ************************************************************* -bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, - vector& categories, OgrLoadingTask* callback) +bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, OgrLoadingTask* callback) { if (!layer || !extents || !loader) return false; @@ -33,11 +32,9 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad OGRFeature *poFeature; VARIANT_BOOL vb; - bool generateLabels = false; // ! Don't forget to delete the shape records if data is not used ! vector shapeData; - vector fieldNames; { // Locking the provider in this section CSingleLock lock(&loader->ProviderLock, TRUE); @@ -45,16 +42,8 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad CStringA fidColumn = layer->GetFIDColumn(); bool hasFID = fidColumn.GetLength() > 0; - map fids; OGRFeatureDefn *poFields = layer->GetLayerDefn(); - OgrLabelsHelper::LabelFields labelFields; - bool hasLabels = false; - if (m_globalSettings.saveOgrLabels) - hasLabels = OgrLabelsHelper::GetLabelFields(layer, labelFields); - - generateLabels = !hasLabels && numFeatures <= loader->GetMaxCacheCount(); - layer->ResetReading(); while ((poFeature = layer->GetNextFeature()) != NULL) { @@ -69,16 +58,9 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad // Get shape record: ShapeRecordData* data = new ShapeRecordData(); shp->ExportToBinary(&(data->Shape), &vb); - - if (generateLabels) - { - ((CShape*)shp)->get_LabelPositionAuto(loader->LabelPosition, - data->LabelX, data->LabelY, data->LabelRotation, loader->LabelOrientation); - } - shp->Release(); - FieldsToShapeRecord(poFields, poFeature, data, hasFID, hasLabels, labelFields); + FieldsToShapeRecord(poFields, poFeature, data, hasFID); shapeData.push_back(data); OGRFeature::DestroyFeature(poFeature); @@ -90,13 +72,6 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad return false; } } - - // If we need to generate labels or apply catagories, ensure we have field names: - if ((generateLabels || categories.size() > 0) && !OgrHelper::GetFieldList(layer, fieldNames)) { - Debug::WriteWithThreadId("Task cancelling.", DebugOgrLoading); - DeleteAndClearShapeData(shapeData); - return false; - } } // Check for a cancel request: @@ -109,17 +84,6 @@ bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoad // Process loaded data: if (shapeData.size() > 0) { - // Generate labels - if (generateLabels) { - CStringW error; - GenerateLabels(shapeData, fieldNames, loader->LabelExpression, error, loader); - } - - // Apply categories - if (categories.size() > 0) { - ApplyCategories(shapeData, fieldNames, categories, loader); - } - // copy to the location accessible by map rendering loader->PutData(shapeData); callback->LoadedCount = shapeData.size(); @@ -146,237 +110,10 @@ void Ogr2RawData::DeleteAndClearShapeData(vector& shapeData) { shapeData.clear(); } -// ************************************************************* -// ApplyCategories() -// ************************************************************* -void Ogr2RawData::ApplyCategories(vector& data, vector& fields, vector& categories, OgrDynamicLoader* loader) -{ - for (size_t i = 0; i < categories.size(); i++) - { - if (loader->HaveWaitingTasks()) { - return; - } - - categories[i]->skip = false; - CComVariant* minVal = &categories[i]->minValue; - CComVariant* maxVal = &categories[i]->maxValue; - - if (categories[i]->classificationField == -1) - categories[i]->valueType = cvExpression; - - switch (categories[i]->valueType) - { - case cvSingleValue: - if (minVal->vt == VT_EMPTY) - categories[i]->skip = true; - break; - case cvRange: - if (minVal->vt == VT_EMPTY || maxVal->vt == VT_EMPTY) - categories[i]->skip = true; - break; - } - } - - CString format = "%g"; - USES_CONVERSION; - for (size_t i = 0; i < categories.size(); i++) - { - if (categories[i]->skip) continue; - - int fieldIndex = categories[i]->classificationField; - - CComVariant* minVal = &categories[i]->minValue; - CComVariant* maxVal = &categories[i]->maxValue; - - tkCategoryValue valueType = categories[i]->valueType; - - if (loader->HaveWaitingTasks()) { - return; - } - - CustomExpression expr; - CStringW error; - if (valueType == cvExpression) - { - expr.SetFields(fields); - if (!expr.Parse(categories[i]->expression, true, error)) - continue; - } - - for (size_t j = 0; j < data.size(); j++) - { - if (data[j]->CategoryIndex != -1) continue; - - switch (valueType) - { - case cvSingleValue: - { - // CComVar does have oveloaded == operator for VARIANT type - if (*minVal == *data[j]->Row->values[fieldIndex]) { - data[j]->CategoryIndex = i; - break; - } - } - break; - case cvRange: - // CComVar does have oveloaded == operator for VARIANT type - if (*minVal < *data[j]->Row->values[fieldIndex] && - *maxVal > *data[j]->Row->values[fieldIndex]) - { - data[j]->CategoryIndex = i; - break; - } - break; - case cvExpression: - { - if (!PopulateExpressionFields(data, i, expr)) - continue; - - // no need to delete the result - CExpressionValue* val = expr.Calculate(error); - if (val) - { - CExpressionValue* result = expr.Calculate(error); - if (result) - { - if (result->isBoolean() && result->bln()) { - data[j]->CategoryIndex = i; - } - } - } - break; - } - } - } - } -} - -// ************************************************************* -// GetLabelFieldIndex() -// ************************************************************* -int Ogr2RawData::GetLabelFieldIndex(CStringW expression, vector& fields) -{ - expression = expression.Trim(); - if (expression.Mid(0, 1) == L"[" && expression.Mid(expression.GetLength() - 1, 1) == L"]") - expression = expression.Mid(1, expression.GetLength() - 2).Trim(); - - for (size_t i = 0; i < fields.size(); i++) - { - if (expression.CompareNoCase(fields[i]) == 0) - return i; - } - return -1; -} - -// ************************************************************* -// PopulateExpressionFields() -// ************************************************************* -bool Ogr2RawData::PopulateExpressionFields(vector& data, int rowIndex, CustomExpression& expr) -{ - bool success = false; - - for (int j = 0; j < expr.get_NumFields(); j++) - { - int fieldIndex = expr.get_FieldIndex(j); - - VARIANT* var = data[rowIndex]->Row->GetValue(fieldIndex); - if (var) - { - switch (var->vt) - { - case VT_BSTR: expr.put_FieldValue(j, var->bstrVal); break; - case VT_I4: expr.put_FieldValue(j, (double)var->lVal); break; - case VT_R8: expr.put_FieldValue(j, (double)var->dblVal); break; - } - success = true; - } - } - return success; -} - // ************************************************************* // FieldsToShapeRecord() // ************************************************************* -bool Ogr2RawData::GenerateLabels(vector& data, vector& fields, CStringW expression, CStringW& error, OgrDynamicLoader* loader ) -{ - if (expression.GetLength() == 0) return false; - - CString format = "%g"; - - // maybe it's single field expression; no need for parsing then - USES_CONVERSION; - int fieldIndex = GetLabelFieldIndex(expression, fields); - if (fieldIndex != -1) - { - for (size_t i = 0; i < data.size(); i++) - { - if (loader->HaveWaitingTasks()) { - return false; - } - - VARIANT* var = data[i]->Row->GetValue(fieldIndex); - if (var) - { - switch (var->vt) - { - case VT_BSTR: - data[i]->LabelText = OLE2W(var->bstrVal); - break; - case VT_I4: - data[i]->LabelText.Format(L"%d", var->lVal); - break; - case VT_R8: - data[i]->LabelText = Utility::FormatNumber(var->dblVal, format); - break; - } - } - } - return true; - } - - CustomExpression expr; - expr.SetFields(fields); - - CStringW err; - - if (expr.Parse(W2A(expression), true, error)) - { - for (size_t i = 0; i < data.size(); i++) - { - if (loader->HaveWaitingTasks()) return false; - - if (!PopulateExpressionFields(data, i, expr)) - continue; - - // no need to delete the result - CExpressionValue* val = expr.Calculate(err); - if (val) - { - if (val->isBoolean()) - { - data[i]->LabelText = val->bln() ? L"true" : L"false"; - } - else if (val->IsDouble()) - { - data[i]->LabelText = Utility::FormatNumber(val->dbl(), format); - - } - else if (val->isString()) - { - data[i]->LabelText = val->str(); - } - } - } - return true; - } - return false; -} - -// ************************************************************* -// FieldsToShapeRecord() -// ************************************************************* -void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid, - bool hasLabels, OgrLabelsHelper::LabelFields& fields) +void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid) { if (hasFid) { @@ -410,13 +147,5 @@ void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFe var->bstrVal = A2BSTR(poFeature->GetFieldAsString(iFld)); // BSTR will be cleared by CComVariant destructor } data->Row->values.push_back(var); - - if (hasLabels) - { - if (iFld == fields.X) data->LabelX = var->dblVal; - if (iFld == fields.Y) data->LabelY = var->dblVal; - if (iFld == fields.Text) data->LabelText = OgrHelper::OgrString2Unicode(poFeature->GetFieldAsString(iFld)); - if (iFld == fields.Rotation) data->LabelRotation = var->dblVal; - } } } diff --git a/src/Ogr/Ogr2RawData.h b/src/Ogr/Ogr2RawData.h index ab5c8b9c..e1646ec9 100644 --- a/src/Ogr/Ogr2RawData.h +++ b/src/Ogr/Ogr2RawData.h @@ -7,15 +7,10 @@ class Ogr2RawData { -public: - static bool Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, vector& categories, OgrLoadingTask* callback); -private: - static void FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid, bool hasLabels, OgrLabelsHelper::LabelFields& labelFields); - static bool GenerateLabels(vector& data, vector& fields, CStringW expression, CStringW& error, OgrDynamicLoader* loader); - static void UpdateLabelsAndCategories(vector&data, OgrDynamicLoader* loader, bool hasLabels); - static int GetLabelFieldIndex(CStringW expression, vector& fields); - static void ApplyCategories(vector& data, vector& fields, vector& categories, OgrDynamicLoader* loader); - static bool PopulateExpressionFields(vector& data, int rowIndex, CustomExpression& expr); + public: + static bool Ogr2RawData::Layer2RawData(OGRLayer* layer, Extent* extents, OgrDynamicLoader* loader, OgrLoadingTask* callback); + private: + static void Ogr2RawData::FieldsToShapeRecord(OGRFeatureDefn* poFields, OGRFeature* poFeature, ShapeRecordData* data, bool hasFid); static void DeleteAndClearShapeData(vector& data); }; diff --git a/src/Ogr/Ogr2Shape.cpp b/src/Ogr/Ogr2Shape.cpp index 7a5863fb..4a3e306f 100644 --- a/src/Ogr/Ogr2Shape.cpp +++ b/src/Ogr/Ogr2Shape.cpp @@ -166,6 +166,123 @@ void Ogr2Shape::CopyFields(OGRLayer* layer, IShapefile* sf) tableInternal->SetFieldSourceIndex(i, i - 1); } } +// ************************************************************* +// ExtendShapefile() +// ************************************************************* +bool Ogr2Shape::ExtendShapefile(OGRLayer* layer, IShapefile* sf, bool loadLabels, ICallback* callback) +{ + layer->ResetReading(); + + int numFeatures = static_cast(layer->GetFeatureCount()); + + int count = 0; + long percent = 0; + USES_CONVERSION; + CComBSTR key = L""; + + OGRFeature *poFeature; + VARIANT_BOOL vbretval; + + CStringA name = layer->GetFIDColumn(); + bool hasFID = name.GetLength() > 0; + ShpfileType shpType; + sf->get_ShapefileType(&shpType); + + map fids; + + OGRFeatureDefn *poFields = layer->GetLayerDefn(); + + CComPtr labels = NULL; + sf->get_Labels(&labels); + + OgrLabelsHelper::LabelFields labelFields; + if (loadLabels) { + if (!OgrLabelsHelper::GetLabelFields(layer, labelFields)) + loadLabels = false; + } + + ShpfileType targetType = ShapefileHelper::GetShapeType(sf); + + while ((poFeature = layer->GetNextFeature()) != NULL) + { + CallbackHelper::Progress(callback, count, numFeatures, "Converting geometries...", key.m_str, percent); + count++; + + OGRGeometry *oGeom = poFeature->GetGeometryRef(); + + IShape* shp = NULL; + if (oGeom) + { + shpType = OgrConverter::GeometryType2ShapeType(oGeom->getGeometryType()); + if (shpType != targetType) + { + goto next_feature; + } + + shp = OgrConverter::GeometryToShape(oGeom, ShapeUtility::IsM(shpType)); + } + + if (!shp) + { + // insert null shape so that client can still access it + ComHelper::CreateShape(&shp); + } + + // Get number of shapes already loaded + long numShapes; + sf->get_NumShapes(&numShapes); + + // Check if this OGR_FID is already in the featureset + long replaceIndex = -1; + long index = numShapes; + if (hasFID) { + CComVariant fid_var; + fid_var.vt = VT_I4; + fid_var.lVal = static_cast(poFeature->GetFID()); + + for (int i = 0; i < numShapes; i++) { + VARIANT pVal; + sf->get_CellValue(0, i, &pVal); + long fid = 0; + lVal(pVal, fid); + if (pVal.lVal == fid_var.lVal) { + replaceIndex = i; + break; + } + } + } + + // Update index in case we are replacing: + index = replaceIndex > 0 ? replaceIndex : index; + + // Insert or replace the shape: + if (replaceIndex > 0) + sf->EditUpdateShape(index, shp, &vbretval); + else + sf->EditInsertShape(shp, &index, &vbretval); + + // No longer need this: + shp->Release(); + + // Set feature id + if (hasFID) { + CComVariant fid_var; + fid_var.vt = VT_I4; + fid_var.lVal = static_cast(poFeature->GetFID()); + sf->EditCellValue(0, index, fid_var, &vbretval); + } + + CopyValues(poFields, poFeature, sf, hasFID, index, loadLabels, labelFields); + + next_feature: + OGRFeature::DestroyFeature(poFeature); + } + CallbackHelper::ProgressCompleted(callback); + + sf->RefreshExtents(&vbretval); + ShapefileHelper::ClearShapefileModifiedFlag(sf); // inserted shapes were marked as modified, correct this + return true; +} // ************************************************************* // FillShapefile() diff --git a/src/Ogr/Ogr2Shape.h b/src/Ogr/Ogr2Shape.h index 90effb6c..b0114063 100644 --- a/src/Ogr/Ogr2Shape.h +++ b/src/Ogr/Ogr2Shape.h @@ -12,6 +12,7 @@ class Ogr2Shape static bool FillShapefile(OGRLayer* layer, IShapefile* sf, int maxFeatureCount, bool loadLabels, ICallback* callback, bool& isTrimmed); static void ReadGeometryTypes(OGRLayer* layer, set& types, bool readAll); static void GeometryTypesToShapeTypes(set& types, vector& result); + static bool ExtendShapefile(OGRLayer* layer, IShapefile* sf, bool loadLabels, ICallback* callback); private: static void CopyValues(OGRFeatureDefn* poFields, OGRFeature* poFeature, IShapefile* sf, bool hasFID, long numShapes, bool loadLabels, OgrLabelsHelper::LabelFields labelFields); static void CopyFields(OGRLayer* layer, IShapefile* sf); diff --git a/src/Ogr/OgrLoader.cpp b/src/Ogr/OgrLoader.cpp index 961ff2b9..cdc9518b 100644 --- a/src/Ogr/OgrLoader.cpp +++ b/src/Ogr/OgrLoader.cpp @@ -73,9 +73,8 @@ void OgrDynamicLoader::CancelAllTasks() // ********************************************** // ClearFinishedTasks() // ********************************************** -vector OgrDynamicLoader::ClearFinishedTasks() +void OgrDynamicLoader::ClearFinishedTasks() { - vector tasks; CSingleLock queueLock(&QueueLock, TRUE); std::queue unfqueue; @@ -91,7 +90,6 @@ vector OgrDynamicLoader::ClearFinishedTasks() if (!task->Cancelled) { // If succesful return a clone: OgrLoadingTask* infoClone = task->Clone(); - tasks.push_back(infoClone); } delete task; @@ -99,16 +97,13 @@ vector OgrDynamicLoader::ClearFinishedTasks() // Replace queue with the unfinished items queue Queue.swap(unfqueue); - - return tasks; } // ********************************************** // AwaitTasks() // ********************************************** -vector OgrDynamicLoader::AwaitTasks() +void OgrDynamicLoader::AwaitTasks() { - vector tasks; CSingleLock queueLock(&QueueLock, TRUE); while (!Queue.empty()) @@ -119,19 +114,13 @@ vector OgrDynamicLoader::AwaitTasks() queueLock.Unlock(); // Unlock briefly so other threads can fetch Sleep(10); queueLock.Lock(); - continue; + continue; // Try next } - - if (!task->Cancelled) { // If succesful return a clone: - OgrLoadingTask* infoClone = task->Clone(); - tasks.push_back(infoClone); - } - + else + { delete task; } - - return tasks; - + } } // ********************************************** diff --git a/src/Ogr/OgrLoader.h b/src/Ogr/OgrLoader.h index 4e882846..51fe3101 100644 --- a/src/Ogr/OgrLoader.h +++ b/src/Ogr/OgrLoader.h @@ -80,8 +80,8 @@ class OgrDynamicLoader void SetMaxCacheCount(int value) { _maxCacheCount = value; } bool CanLoad(int featureCount) { return featureCount < GetMaxCacheCount(); } - vector ClearFinishedTasks(); - vector AwaitTasks(); + void ClearFinishedTasks(); + void AwaitTasks(); vector FetchData(); void PutData(vector shapeData); diff --git a/src/Structures/Layer.cpp b/src/Structures/Layer.cpp index f36f4a6a..b6047154 100644 --- a/src/Structures/Layer.cpp +++ b/src/Structures/Layer.cpp @@ -380,19 +380,14 @@ UINT OgrAsyncLoadingThreadProc(LPVOID pParam) ogr->get_LabelExpression(&expr); loader->LabelExpression = OLE2W(expr); - bool success = Ogr2RawData::Layer2RawData(ds, &options->extents, loader, *options->categories, options->task); + bool success = Ogr2RawData::Layer2RawData(ds, &options->extents, loader, options->task); - options->task->Finished = true; - if (!success) { - options->task->Cancelled = true; + // Fire event for this task: OgrLoadingTask* task = options->task; options->map->_FireBackgroundLoadingFinished(task->Id, task->LayerHandle, task->FeatureCount, 0); - } loader->ClearFinishedTasks(); - if (success) - options->map->_Redraw(RedrawAll, false, false); } layer->put_AsyncLoading(false); Debug::WriteWithThreadId("Releasing loading lock. \n", DebugOgrLoading); @@ -419,32 +414,13 @@ void Layer::LoadAsync(IMapViewCallback* mapView, Extent extents, long layerHandl // if larger extents were requested previously and features were loaded, skip the new request if (!bForce && extents.Within(loader->LastSuccessExtents)) return; - // get a copy of categories to apply them in the background thread - vector* data = new vector(); - - CComPtr sf = NULL; - this->QueryShapefile(&sf); - if (sf) - { - ShpfileType shpType = ShapefileHelper::GetShapeType(sf); - loader->IsMShapefile = ShapeUtility::IsM(shpType); - - IShapefileCategories* categories = NULL; - sf->get_Categories(&categories); - if (categories) - { - ((CShapefileCategories*)categories)->GetCategoryData(*data); - categories->Release(); - } - } - // Prepare a new OgrLoadingTask & queue it for execution OgrLoadingTask* task = new OgrLoadingTask(layerHandle); loader->EnqueueTask(task); // First fire the event, then start the thread. // This prevents race condition between the started & completed event. - AsyncLoadingParams* param = new AsyncLoadingParams(mapView, extents, this, data, task); + AsyncLoadingParams* param = new AsyncLoadingParams(mapView, extents, this, task); mapView->_FireBackgroundLoadingStarted(task->Id, layerHandle); CWinThread* thread = AfxBeginThread(OgrAsyncLoadingThreadProc, (LPVOID)param); } @@ -452,76 +428,17 @@ void Layer::LoadAsync(IMapViewCallback* mapView, Extent extents, long layerHandl //*********************************************************************** //* UpdateShapefile() //*********************************************************************** -void Layer::UpdateShapefile(long layerHandle) +void Layer::UpdateShapefile() { - // Get the OGR loader: - OgrDynamicLoader* loader = GetOgrLoader(); - if (!loader) return; - - { // Lock everything - CSingleLock ldLock(&loader->LoadingLock, TRUE); - CSingleLock prLock(&loader->ProviderLock, TRUE); - CSingleLock sfLock(&loader->ShapefileLock, TRUE); - - // Grab the loaded data: - vector data = loader->FetchData(); - if (data.size() == 0) return; - - USES_CONVERSION; - CComPtr sf = NULL; - if (!QueryShapefile(&sf)) + if (!IsDynamicOgrLayer()) return; - VARIANT_BOOL vb; - sf->EditClear(&vb); - - ShpfileType shpType; - sf->get_ShapefileType(&shpType); - - Debug::WriteWithThreadId(Debug::Format("Update shapefile: %d\n", data.size()), DebugOgrLoading); - - CComPtr table = NULL; - sf->get_Table(&table); - - CComPtr labels = NULL; - sf->get_Labels(&labels); - labels->Clear(); - - if (table) - { - CTableClass* tbl = TableHelper::Cast(table); - sf->StartEditingShapes(VARIANT_TRUE, NULL, &vb); - long count = 0; - for (size_t i = 0; i < data.size(); i++) - { - CComPtr shp = NULL; - ComHelper::CreateShape(&shp); - if (shp) - { - shp->Create(shpType, &vb); - shp->ImportFromBinary(data[i]->Shape, &vb); - sf->EditInsertShape(shp, &count, &vb); - sf->put_ShapeCategory(count, data[i]->CategoryIndex); - - tbl->UpdateTableRow(data[i]->Row, count); - data[i]->Row = NULL; // we no longer own it; it'll be cleared by Shapefile.EditClear - - if (data[i]->HasLabel()) { - CComBSTR bstr(data[i]->LabelText); - labels->AddLabel(bstr, data[i]->LabelX, data[i]->LabelY, data[i]->LabelRotation); - } - - count++; - } - } - ShapefileHelper::ClearShapefileModifiedFlag(sf); // inserted shapes were marked as modified, correct this - } + // Get the OGR layer: + IOgrLayer* layer = NULL; + if (!QueryOgrLayer(&layer)) + return; - // clean the data - for (size_t i = 0; i < data.size(); i++) { - delete data[i]; - } - } + ((COgrLayer*)layer)->UpdateShapefileFromOGRLoader(); } //**************************************************** diff --git a/src/Structures/Layer.h b/src/Structures/Layer.h index 08c22585..d4707af5 100644 --- a/src/Structures/Layer.h +++ b/src/Structures/Layer.h @@ -35,31 +35,22 @@ class Layer; // A structure to pass parameters to the background thread struct AsyncLoadingParams : CObject { - AsyncLoadingParams(IMapViewCallback* m, Extent e, Layer* l, vector* ct, OgrLoadingTask* cback) + AsyncLoadingParams(IMapViewCallback* m, Extent e, Layer* l, OgrLoadingTask* cback) { map = m; extents = e; layer = l; - categories = ct; task = cback; }; ~AsyncLoadingParams() { - if (categories) - { - for (size_t i = 0; i < categories->size(); i++) { - delete (*categories)[i]; - } - delete categories; - } } public: IMapViewCallback* map; Extent extents; Layer* layer; - vector* categories; OgrLoadingTask* task; // not owned by this object }; @@ -143,7 +134,7 @@ class Layer void GetExtentsAsNewInstance(IExtents** extents); bool UpdateExtentsFromDatasource(); void LoadAsync(IMapViewCallback * mapView, Extent extents, long layerHandle, bool bForce); - void UpdateShapefile(long layerHandle); + void UpdateShapefile(); void CloseDatasources(); bool IsEmpty(); bool IsDiskBased(); diff --git a/src/Structures/Structures.h b/src/Structures/Structures.h index 1b2da0d9..f9fb538e 100644 --- a/src/Structures/Structures.h +++ b/src/Structures/Structures.h @@ -76,15 +76,8 @@ struct ShapeRecordData { VARIANT Shape; TableRow* Row; - double LabelX; - double LabelY; - double LabelRotation; - CStringW LabelText; - int CategoryIndex; - bool HasLabel() { return LabelX != 0 && LabelY != 0 && LabelText.GetLength() > 0;} - - ShapeRecordData() : LabelX(0.0), LabelY(0.0), LabelRotation(0.0), CategoryIndex(-1) + ShapeRecordData() { this->Row = new TableRow(); VariantInit(&Shape); From 19cbfae0bc5ecea14f8de6f51e4dc962fe941a2f Mon Sep 17 00:00:00 2001 From: nextfullstorm Date: Tue, 5 Nov 2019 12:21:13 +0300 Subject: [PATCH 08/15] Added SetLatitudeLongitude to set geoposition in one call There is a geoposition shift (at least in Delphi client) if we set position via Latitude/Longitude properties right after map control creation. It happens due to separate calls SetGeoPosition(new coord, old coord), SetGeoPosition(old coord, new coord) and some kind of coord transformation in SetGeoPosition. As a result map will be in wrong geoposition. But if we set Latitude/Longitude via single SetGeoPosition call all goes fine. --- src/Control/DispIds.h | 1 + src/Control/Map.h | 1 + src/Control/Map_DispatchMap.cpp | 1 + src/Control/Map_Scale.cpp | 13 +++++++++++++ src/InnoSetup/MapWinGIS_TLB.pas | Bin 1218056 -> 1218373 bytes 5 files changed, 16 insertions(+) diff --git a/src/Control/DispIds.h b/src/Control/DispIds.h index e5434021..8b097732 100644 --- a/src/Control/DispIds.h +++ b/src/Control/DispIds.h @@ -260,6 +260,7 @@ enum { //{{AFX_DISP_ID(CMapView) dispidGetBaseProjectionPoint = 164L, //ajp June 2010 dispidCanUseImageGrouping = 165L, // lsu dispidDrawBackBuffer = 170L, + dispidSetLatitudeLongitude = 267L, // events eventidMouseDown = 1L, diff --git a/src/Control/Map.h b/src/Control/Map.h index a859c28e..3b4c12b9 100644 --- a/src/Control/Map.h +++ b/src/Control/Map.h @@ -572,6 +572,7 @@ class CMapView : public COleControl, IMapViewCallback afx_msg float GetLatitude(); afx_msg void SetLongitude(float nNewValue); afx_msg float GetLongitude(); + afx_msg void SetLatitudeLongitude(double latitude, double longitude); afx_msg void SetCurrentZoom(int nNewValue); afx_msg int GetCurrentZoom(); afx_msg void SetTileProvider(tkTileProvider nNewValue); diff --git a/src/Control/Map_DispatchMap.cpp b/src/Control/Map_DispatchMap.cpp index 616de98a..418f35f4 100644 --- a/src/Control/Map_DispatchMap.cpp +++ b/src/Control/Map_DispatchMap.cpp @@ -249,6 +249,7 @@ BEGIN_DISPATCH_MAP(CMapView, COleControl) DISP_PROPERTY_EX_ID(CMapView, "FileManager", dispidFileManager, GetFileManager, SetNotSupported, VT_DISPATCH) DISP_PROPERTY_EX_ID(CMapView, "Latitude", dispidLatitude, GetLatitude, SetLatitude, VT_R4) DISP_PROPERTY_EX_ID(CMapView, "Longitude", dispidLongitude, GetLongitude, SetLongitude, VT_R4) + DISP_FUNCTION_ID(CMapView, "SetLatitudeLongitude", dispidSetLatitudeLongitude, SetLatitudeLongitude, VT_EMPTY, VTS_R8 VTS_R8) DISP_PROPERTY_EX_ID(CMapView, "CurrentZoom", dispidCurrentZoom, GetCurrentZoom, SetCurrentZoom, VT_I4) DISP_PROPERTY_EX_ID(CMapView, "TileProvider", dispidTileProvider, GetTileProvider, SetTileProvider, VT_I2) DISP_PROPERTY_EX_ID(CMapView, "Projection", dispidMapProjection, GetProjection, SetProjection, VT_I2) diff --git a/src/Control/Map_Scale.cpp b/src/Control/Map_Scale.cpp index a34f55d3..2f940fa5 100644 --- a/src/Control/Map_Scale.cpp +++ b/src/Control/Map_Scale.cpp @@ -1803,6 +1803,7 @@ void CMapView::SetLongitude(float longitude) } SetGeoPosition(longitude, GetLatitude()); } + float CMapView::GetLongitude() { double x, y; @@ -1811,6 +1812,18 @@ float CMapView::GetLongitude() return 0.0; } +void CMapView::SetLatitudeLongitude(double latitude, double longitude) +{ + if (abs(latitude) > 90.0 || abs(longitude) > 180.0) + { + ErrorMessage(tkINVALID_PARAMETER_VALUE); + return; + } + + SetGeoPosition(longitude, latitude); +} + + // **************************************************************** // CurrentZoom() // **************************************************************** diff --git a/src/InnoSetup/MapWinGIS_TLB.pas b/src/InnoSetup/MapWinGIS_TLB.pas index 8510093fbeaaaddfeb4ff4e3b7a63ed93dc2e391..dd4e83ba261738a5c4aeaab1b0f2287560974cbb 100644 GIT binary patch delta 355 zcmeBJ<8^eMS3?V93sVd87M2f2L7W9e`N^p%rA4URrOlYN&6sVQF?+#1TZ(L% z{_!ijOnZYM2M}`tF&7YX12NC`20`9G%+uHU^YWVcCKl+C?t$ronY?P6`1R=^JUrbn ggin0>hD$u`?Y*MBK+Ffk{6H)K#Dd#2E-fGP5aBsSTG`B!I zP!5PWftU-3xq+BxyPOd3ALi-z`1!b|AGpQC-hN7q7l`?Qm>-A*fLL(*DKVky1^^+O BB&7fV From fb20bfd5af6910d2f79cc208cc9de8de597ec394 Mon Sep 17 00:00:00 2001 From: Mathijs Dumon Date: Tue, 5 Nov 2019 21:00:17 +0100 Subject: [PATCH 09/15] Addendum 2 to MWGIS-198 --- src/COM classes/OgrLayer.cpp | 4 ++-- src/Structures/Layer.cpp | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/COM classes/OgrLayer.cpp b/src/COM classes/OgrLayer.cpp index ce5ed654..dd0a9741 100644 --- a/src/COM classes/OgrLayer.cpp +++ b/src/COM classes/OgrLayer.cpp @@ -1220,10 +1220,10 @@ bool COgrLayer::DeserializeOptions(CPLXMLNode* node) if (!_shapefile) { IShapefile * sf = LoadShapefile(); _shapefile = sf; + } bool result = ((CShapefile*)_shapefile)->DeserializeCore(VARIANT_FALSE, psChild); if (!result) success = false; - } - } + } } CString key = CPLGetXMLValue(node, "Key", ""); diff --git a/src/Structures/Layer.cpp b/src/Structures/Layer.cpp index b6047154..43a69156 100644 --- a/src/Structures/Layer.cpp +++ b/src/Structures/Layer.cpp @@ -384,6 +384,8 @@ UINT OgrAsyncLoadingThreadProc(LPVOID pParam) // Fire event for this task: OgrLoadingTask* task = options->task; + task->Finished = true; + task->Cancelled = !success; options->map->_FireBackgroundLoadingFinished(task->Id, task->LayerHandle, task->FeatureCount, 0); loader->ClearFinishedTasks(); @@ -422,7 +424,9 @@ void Layer::LoadAsync(IMapViewCallback* mapView, Extent extents, long layerHandl // This prevents race condition between the started & completed event. AsyncLoadingParams* param = new AsyncLoadingParams(mapView, extents, this, task); mapView->_FireBackgroundLoadingStarted(task->Id, layerHandle); - CWinThread* thread = AfxBeginThread(OgrAsyncLoadingThreadProc, (LPVOID)param); + OgrAsyncLoadingThreadProc(param); + + //CWinThread* thread = AfxBeginThread(OgrAsyncLoadingThreadProc, (LPVOID)param); } //*********************************************************************** From c28e7576a10a60e8a607b44aa9a6099f0a0ba660 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Tue, 5 Nov 2019 22:27:54 -0800 Subject: [PATCH 10/15] MWGIS-204; insert Parts and Points (rather than put) into new ShapeWrapper --- src/Shapefile/ShapeInterfaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Shapefile/ShapeInterfaces.cpp b/src/Shapefile/ShapeInterfaces.cpp index fdef204d..662dc79e 100644 --- a/src/Shapefile/ShapeInterfaces.cpp +++ b/src/Shapefile/ShapeInterfaces.cpp @@ -48,14 +48,14 @@ void IShapeWrapper::CopyTo(IShapeWrapper* target) for (int i = 0; i < get_PartCount(); i++) { int part = get_PartStartPoint(i); - target->put_PartStartPoint(i, part); + target->InsertPart(i, part); } double x, y, z, m; for (int i = 0; i < get_PointCount(); i++) { get_PointXY(i, x, y); - target->put_PointXY(i, x, y); + target->InsertPointXY(i, x, y); if (isM || isZ) { From 0405361b3d2bbedfaa8b115752ac102a0b2d2322 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Tue, 5 Nov 2019 22:58:52 -0800 Subject: [PATCH 11/15] Addendum to merge pull request #181; move to dispid's in numerical order, additional function headers --- src/Control/DispIds.h | 2 +- src/Control/Map_Scale.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Control/DispIds.h b/src/Control/DispIds.h index 8b097732..19466ce6 100644 --- a/src/Control/DispIds.h +++ b/src/Control/DispIds.h @@ -3,6 +3,7 @@ enum { //{{AFX_DISP_ID(CMapView) // NOTE: ClassWizard will add and remove enumeration elements here // DO NOT EDIT what you see in these blocks of generated code ! // **ClassWizard is a thing of the past... feel free to edit this code. + dispidSetLatitudeLongitude = 267L, dispidStartNewBoundShapeEx = 266L, dispidStartNewBoundShape = 265L, dispidRestartBackgroundLoading = 264L, @@ -260,7 +261,6 @@ enum { //{{AFX_DISP_ID(CMapView) dispidGetBaseProjectionPoint = 164L, //ajp June 2010 dispidCanUseImageGrouping = 165L, // lsu dispidDrawBackBuffer = 170L, - dispidSetLatitudeLongitude = 267L, // events eventidMouseDown = 1L, diff --git a/src/Control/Map_Scale.cpp b/src/Control/Map_Scale.cpp index 2f940fa5..c57a30cc 100644 --- a/src/Control/Map_Scale.cpp +++ b/src/Control/Map_Scale.cpp @@ -1772,7 +1772,7 @@ bool CMapView::SetGeoPosition(double x, double y) } // **************************************************************** -// Latitude() +// SetLatitude() // **************************************************************** void CMapView::SetLatitude(float latitude) { @@ -1793,7 +1793,7 @@ float CMapView::GetLatitude() } // **************************************************************** -// Longitude() +// SetLongitude() // **************************************************************** void CMapView::SetLongitude(float longitude) { @@ -1812,6 +1812,9 @@ float CMapView::GetLongitude() return 0.0; } +// **************************************************************** +// SetLatitudeLongitude() +// **************************************************************** void CMapView::SetLatitudeLongitude(double latitude, double longitude) { if (abs(latitude) > 90.0 || abs(longitude) > 180.0) From f49373939005e6b2e3f5c166913bf47cf3947c08 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Tue, 5 Nov 2019 23:12:35 -0800 Subject: [PATCH 12/15] Related to merge pull request #181; Add SetLatitudeLongitude method to documentation. --- docs/AxInterop.MapWinGIS/AxMap.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/AxInterop.MapWinGIS/AxMap.cs b/docs/AxInterop.MapWinGIS/AxMap.cs index 576e821c..e2a8c1c2 100644 --- a/docs/AxInterop.MapWinGIS/AxMap.cs +++ b/docs/AxInterop.MapWinGIS/AxMap.cs @@ -2319,6 +2319,18 @@ public virtual bool SetGeographicExtents(Extents pVal) /// \new491 Added in version 4.9.1 public float Longitude { get; set; } + ///

+ /// Sets the Latitude and Longitude of the center of the screen in one operation + /// + /// Requested Latitude in decimal degrees + /// Requested Longitude in decimal degrees + /// Map projection must be set in order for this method to work. + /// \new510 Added in version 5.1.0 + public void SetLatitudeLongitude(double latitude, double longitude) + { + throw new NotImplementedException(); + } + /// /// Gets or sets the current zoom level for the map. It corresponds to the zoom level of current tile provider. /// From 703837d19dd0238ec3d01af729ffb162dd95d987 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Wed, 6 Nov 2019 12:08:45 -0800 Subject: [PATCH 13/15] Related to pull merge request #181; SetLatitudeLongitude method was not being exported via the IDL --- src/MapWinGIS.idl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MapWinGIS.idl b/src/MapWinGIS.idl index e365653f..65ab9d58 100644 --- a/src/MapWinGIS.idl +++ b/src/MapWinGIS.idl @@ -6834,6 +6834,7 @@ library MapWinGIS [id(212), propget] float Latitude(); [id(213), propput] void Longitude(float nNewValue); [id(213), propget] float Longitude(); + [id(267)] void SetLatitudeLongitude(double latitude, double longitude); [id(218), propput] void KnownExtents(tkKnownExtents nNewValue); [id(218), propget] tkKnownExtents KnownExtents(); #endif From f93adc8eadc3021e3f7bc020eb4aaafcb7e216b7 Mon Sep 17 00:00:00 2001 From: Jerry Faust Date: Sat, 16 Nov 2019 20:10:47 -0800 Subject: [PATCH 14/15] Update documentation related to the Identify tool (use of ChooseLayer event rather than ActiveLayer property) --- docs/Interop.MapWinGIS/Com Classes/Identifier.cs | 9 +++++---- docs/Interop.MapWinGIS/Enumerations/Enumerations.cs | 7 ++++++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/Interop.MapWinGIS/Com Classes/Identifier.cs b/docs/Interop.MapWinGIS/Com Classes/Identifier.cs index ffd8845f..d86d5c6a 100644 --- a/docs/Interop.MapWinGIS/Com Classes/Identifier.cs +++ b/docs/Interop.MapWinGIS/Com Classes/Identifier.cs @@ -34,10 +34,11 @@ public class Identifier /// public uint OutlineColor { get; set; } - /// - /// Gets or sets the handle of active layer, which is used when Identifer.IdentifierMode set to imSingleLayer. - /// - public int ActiveLayer { get; set; } + ///// + ///// Gets or sets the handle of active layer, which is used when Identifer.IdentifierMode set to imSingleLayer. + ///// NOTE: this method has been hidden, and functionality replaced through use of the ChooseLayer event. + ///// + //public int ActiveLayer { get; set; } } #if nsp } diff --git a/docs/Interop.MapWinGIS/Enumerations/Enumerations.cs b/docs/Interop.MapWinGIS/Enumerations/Enumerations.cs index d0b95f35..efbbc11c 100644 --- a/docs/Interop.MapWinGIS/Enumerations/Enumerations.cs +++ b/docs/Interop.MapWinGIS/Enumerations/Enumerations.cs @@ -2368,9 +2368,14 @@ public enum tkIdentifierMode /// imAllLayers = 0, /// - /// Only shapefile defined by Identifier.ActiveLayer will be identified. + /// Only shapefile specified in the context of AxMap.ChooseLayer event will be analyzed. /// imSingleLayer = 1, + /// + /// All shapefile layers with Shapefile.Identifiable property set to true will be analyzed, + /// but search will stop following the first (topmost) layer for which shapes are found. + /// + imAllLayersStopOnFirst = 2, } /// From 69f4c2e169bf97082ce62a0f65452d7562518427 Mon Sep 17 00:00:00 2001 From: Paul Meems Date: Mon, 25 Nov 2019 16:24:43 +0100 Subject: [PATCH 15/15] New version numbers --- src/InnoSetup/MapWinGIS-only.iss | 7 ++++--- src/MapWinGIS.rc | 8 ++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/InnoSetup/MapWinGIS-only.iss b/src/InnoSetup/MapWinGIS-only.iss index 9fb063a6..ee4bdd76 100644 --- a/src/InnoSetup/MapWinGIS-only.iss +++ b/src/InnoSetup/MapWinGIS-only.iss @@ -2,12 +2,12 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "MapWinGIS" -#define MyAppVersion "5.1.0" +#define MyAppVersion "5.1.1" #define MyAppPublisher "MapWindow Open Source GIS Community" #define MyAppURL "http://www.mapwindow.org" #define SetupLocation "D:\dev\MapWindow\MapWinGIS\git\src\InnoSetup" #define BinLocation "D:\dev\MapWindow\MapWinGIS\git\src\bin" -;; #define x64BitVersion +;#define x64BitVersion ;; #define VsVersion = "2015" #define VsVersion = "2017" @@ -80,8 +80,9 @@ Source: "{#MySourceDir}\MapWinGIS.ocx"; DestDir: "{app}"; Flags: ignoreversion { ;; IntelliSense: Source: "{#SetupLocation}\AxInterop.MapWinGIS.XML"; DestDir: "{app}"; Flags: ignoreversion; Components: MapWinGIS_Core Source: "{#SetupLocation}\Interop.MapWinGIS.XML"; DestDir: "{app}"; Flags: ignoreversion; Components: MapWinGIS_Core -;; Delphi TAB file +;; Delphi files Source: "{#SetupLocation}\MapWinGIS_TLB.pas"; DestDir: "{app}"; Flags: ignoreversion; Components: MapWinGIS_Delphi +Source: "{#SetupLocation}\MapWinGIS.Delphi.Component.v5.1.0.zip"; DestDir: "{app}"; Flags: ignoreversion; Components: MapWinGIS_Delphi ;; Licenses Source: "{#BinLocation}\Licenses\GDALLicense.rtf"; DestDir: "{app}\Licenses\"; Flags: ignoreversion; Components: MapWinGIS_Core Source: "{#BinLocation}\Licenses\GISInternalsLicense.rtf"; DestDir: "{app}\Licenses\"; Flags: ignoreversion; Components: MapWinGIS_Core diff --git a/src/MapWinGIS.rc b/src/MapWinGIS.rc index cdf815c0..e47bbd3f 100644 --- a/src/MapWinGIS.rc +++ b/src/MapWinGIS.rc @@ -112,8 +112,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 5,1,0,0 - PRODUCTVERSION 5,1,0,0 + FILEVERSION 5,1,1,0 + PRODUCTVERSION 5,1,1,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -131,13 +131,13 @@ BEGIN VALUE "Comments", "This control includes a mapping component and objects for reading and writing shapefiles and various triangulated irregular network and grid files. It also has extensive label and chart options and includes projection routines." VALUE "CompanyName", "MapWindow OSS Team - www.mapwindow.org" VALUE "FileDescription", "MapWinGIS ActiveX Control" - VALUE "FileVersion", "5.1.0.0" + VALUE "FileVersion", "5.1.1.1" VALUE "InternalName", "MapWinGIS ActiveX Control" VALUE "LegalCopyright", "Copyright (C) 2004-2019 MapWindow OSS Team" VALUE "LegalTrademarks", "MapWindow GIS is a trademark of Daniel P. Ames, 2005-2019" VALUE "OriginalFilename", "MapWinGIS.ocx" VALUE "ProductName", "MapWinGIS ActiveX Control" - VALUE "ProductVersion", "5.1.0.0" + VALUE "ProductVersion", "5.1.1.1" END END BLOCK "VarFileInfo"

c2oqf#eE%hO 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 literal 1196273 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%0D2<)h6TBnIE&I0MDjxk}E;kwHevakKEcCp4uW zX#?9$oJ^i2z{NDnmZoeeh|9*W8cs z?UDHm%u@&l=0_25ZLA{_9P!}q`K<+!u8VQEPJrY2aP<-2ZZIdT*ttRw7Eus;2BxH? z$%fAb9DL{y^UJTp1s-OMnKZy8GO$3?&3OC?8+zP$tr{@dceC-F$XW;yZWq2RxU@sE zJ73&J@9B%>{3;$1*q<8ChkMJ>Cs>$bsa2`Pbw`U-YkIVVo*2QUcIX(28m$Qh1edCNjoCuo90tgmVNrSKm@Ic7ute%4_9x;k-||m>seqm z3slO3J7b=3oxzElyE(@TUS4mI)7idPEC^jACkew4@=y9AMOJTcvm^9-?-UFX*D$e# zV20!qq-|tFdW2)hnUkr=5GxG0e@qoDU2jl>9b%h`r3TQO^1?yY8a(H~DQHq@u!`f7 z;KV9}5T?9$5D-iSW3W9lQ1GPIpzT-9LP54LhD6%!?FfW&15DjjtdYWt>s2tG%M7jD zr3Eg7lx`&Cau7u`uP}s-$4kgTg`xq!3?eF>I_r>4m=_5x1FPto8p9*^5hZVu(9P== z*}TF~RSp}JTKyEtx=>zaSEYs~yH=D7MyPSE5|PUsN~PZ=r={x+NnK?qvqQy|k!uw} zE^{bl-WCy$eJq9yfg3Vtu@)W_A(d4ta#^_{S-3%PglV~B?};!dfEAOX&M-nD(owaI zhlW$+b+MtG`!d7~6}fW=MK!N5bi*2Drfg9tT*@k$2t}RYWgHh?BMgXYg{iTm!M+<) zv@4yG!bTxJ3~7RtA*^PR5iuMBJw3R2iO@IY(m#2Hp`Tm@UazD&C2J}&RB+`iPs<`( zR&gvtPxCRZ4;*xzxXuZ>Ww zRumPILoW19jasNR#6qE^70>**;NS{ES`B(ICd->kL=RID(jk|?>XJf|j~1T>PXM?I zrtq!VYJfU{U65*P?Zl#gZ7AE{2}TnZl@kOS zYBnzY>>CxB)=6EPZ3RUYfR_}-s7(2 zcSLV_krE`tZ7Om|hZ#Y$2TlHtInjIW-JvV6XK?%=kM692M*`YaIQe`@@;gZ#hLG@K z;?cjsST#e`@w30kH0%2IG(5i=G9s}fFr>o;ck9~TBj@PI?&Ta3cZotrPt&Wa$&zoR(kE<*yEDg9bFq<$USf0e6_h?E^Bz)_7lU(PgZKw;ii0)1Yo!y3Ur$z$yKr{-Sw(IY_l`psb(y~s z)YSzv2n>B!&AUE>WGt0;Q&SNbmOHVi(ZlTfk9VTDH9-3y;KL^$s2kcFfEM=!JmokW z#}779*t?VY@o4p7AIwHRSb1viw69P{#|n=yDD3 z_^6(_r=&nM7@bVg=~nzE4!*zM*^h3!Hm zE0+?6m3Q;Cz|sf8WK7E{Tb&RXSZi+L9f{7>5j)#jiCpGeirDp6pP=)hi{+x#ZgAcg zH?0mJM;Y!PqT?H!+{wv|Kf_7#MFe;U4n?khx5z8e>8q;oCj%&#YXDIN43s-i16*EK zf}-!zKw=RCKEHuWmg|_S42Hq+n>iT$w-jt(pyXQ&gwijrMhBDj0Adf=<(+{^1C$dm z3WtX*Rm$L*BQL;aMGUB2T>(y)FqrZN1t?X(K-LWtAZ;mw2Z5+z=vvWIav=j}{)_;c z6)|A$MF^028H1{Gdw^2~3`C;XgL43Ps~9o%w;YB8Qc=tZa*&CqQb6$33cVe#CaZNj zls)1`k?HmpWTi)BW=?I9v#V;L6f!U^pdv0Ohw-Xh)G?~mq|;hpRhBb~UFQRWEzQB{ zjG_SPcMcMd9SSIxFj!%|$HPKEsnyoelks1{Pt{C7%-nz>zZoQ7L!JgWyNJYBJ7Bd9 z%12!Xy9o}LE@7%PUo?~|U?4jHvi%0i^?D`|n43*Y%Vnw}B3PG@UQW^7P{O(07$uLJ z5t^Ve50@bql{>rPUUEbXBmq=i=#5pKH+td2ZKB9v0%X4}VZ7Lz0mPJJSZuD*vd-#k zDmf6P`qS7Y#5VaQ`gvxyf&TsIw*7xT00)mylXFv1KKK)`tgz9%jU zIHD9ZcGLOkXqwVAEOFP^i zC?4vBO!st*BQu^S8IA?$=EZWfxSX8zW)|z7Ol0UQ zPNqrJ7+A^T@E)Cw;2t~`2JK`m1RV)U+0{1np(2_Rh*gIN!p{#OQV%M!JyG_rMi+H4 zsMZsqj#jWIP>(h2Um@SlZ3b?8Y3~jal*?6I7`E5D*GqUhVcoiDrMcq}gU?)(vQ`C2 z01hsE$GaUj0XVqR(QUI#b_G!>*V-0?G8#uwC;1o9%-!JFm36&lJen8$tDsU0Y#`~4 zY$SqPJpNfWs(oW@N4Ihattd*q&T@mWc~N0Jsbm33isH45<`Rt*Y_{Pkkebr)n;&7| zbE*2$5viD5yI6dY{hkdQ`embRGK ztmjdd*yeT|OASjD#~=#UYZ#J*nb>XOkbWdA)viAMMB0~dGmfcH z5%e{&Q?y*y>QaGA9G+B~oPqOzo_!uJa8^JlAbKtF;@`i1HNSrWmvvUpzk!inLvun zi47ePo%$it8VJ&V?NQw>iwXfh-~vxQ?M~rakhN{VN9PpLP|aP6DJ3MuyTuTn?}Z13 zl5?J0P#<^3#=MsM;8$_C1|c#2EEbq8#EmZ7>Q+kD0xdBHdQV5;tEu=#86-@Ez|ez9 zPWpyHn1kj2TsKRQ{(-t=gIS24@#DEfk?pJr^&8C6fI#brYo5jH4Kk@bj{CFWVY55~ zw`y7e3)2Ak99*v}a6Fw!1z}f&gG-P3v!1Laez6x2DA#as{Am(Un`UkyZpg5~Yb4Zg-&N_p12_cHM8# z&nZY!5a$l?Yf#)~tnR2jSo*esTifs$c7ur` zs6+bkd=Usi$rmy7I%8`m|sEqStA7qm0B`_4f@MhtTutZ{kKC zNyV;a*Y*-)cd|SK=U7YQ-j2qTYo4xKMeE>d4tS?TFN-xibm8@!?DTAr zq!6Xo#E6rkD%%-7apF$tHd*4s0lnwD9nOwZL$0lEpUbqVw#{D_mu5w5Z6?hAQuJK9 ztpS+0c&P6?*&l02aHR^v`B=k(9PZe7Fh1jMP8L}Tw9^k`C3uHHV;dkTN-v08(s6?) z15}Ba7pUKxX5(jT@OBOl4AWchY`$ie1DlV`0F(>=E<_9+-Is4&$GRjEvqRfTDy73n z7Uv2#Bt7~OJBrLhc%ujmkZ6#j@ubpt3dE;F{PN!dEIJyiH>Y45r9K;kgGV|xEaD7^ z)m@aI4Z|x)2|Yf7lz!5KKZaBO ztB@vnjaWLKWjdb=K>`RD{G5f@G5+|I~RNGMRX|UOEa9BVG;h=9FEqPaEjo$GC26yEa}BW zDXg=@f$GIBOz4#U4~tj#xgH{y!OZ1sQKEk}6ZBqyo!D($GsRFy2WP4}O zXg;RE7$@6UGNo>2w7}nyzxBU0z%iv}WNOjTkIn{#7aRD(;VcyJmHl}GSR)&?#ir+xm`7N8Q|yg(-x1GVV~ zg5PG~EggzCrMPRtXCA=%r}s{=J^Gd!zm;q2Ex!GXM7$5z7a#7FrwI|e6uuifZf*uo zzGD)x;t-y+G~BaKIq;w)3P1Fq02ll4+ejeBDL#NI`#>V{oyZ}Tjwlkn06F4L%KX(0 zIn#oe-4O1?2|N`WP~2?X>v4jnKn!xaBnQH!KLst77@Ym|f)rZB@@x zsOp#CszQUzSLy(j{}x0pGH5JJ<+hzru#kpO=N&wul!F>NK?!242D^9{X0^n3qJlmB zRurtR=ou|Ys;SZXo@J}ks$Tj_D*vqzNu~rUygVDt7KSqq4lxyC1%b0YN>fRTSfc%d zOvxoR#;{ril7x>7c;Z~GDL`cJkzFzK43#vc}$X}YPbN7Jxy|{Q+Ykfth3w$d>0pLj? z-Skh0@YX~KhvVu1Agbk_6Lwj1A8pP$LoHZmwI1u>+^V%U-c&Np4LFupC^bB2XFUgF zp~`_FgozZXC;jnJ7bIjDke8uKoN9$|_$fr`w;{+E;i^Q_J|uJ*$I#L%ZhkMWM!cfo zajnm37-lI9UL(Dq07ULoVko6ca#czRKq#dWLusn+)K#e!+n>fV1krs(-ch_j_MU$g z_v3I=j%v!AGD9P-(%!7x=ZAYBf;ro)vjs+i`6eiZK8ql2+SDt|Vj6c%_=s&7&~zeI zgbgTMldFvd$KhpU9c;zksjYIy2q(pN?!=w3UG7|438mf}4C2Wkm7WA#Tjd}7;O;A-Cg6^S2Ivw)G<99; zkG6F&vQkvqBvN2TF4`THyS*xlv)fx-C4sH-xayl%Rkms0XIq9SYgEfs*BQ3ylGfcm zZmYki1z*=nANt*%on6kCF|CkGAxHo82x7}dg2DE5auJ`q6j<2DF5vBm)m*+Z9sR;s zgO|Q68F*L-ADRHy{L2Y^7m9q-Lho?CxL&+&X4kf&h5*7IEaBTz7T!0j2K1ub1%BMf zB7_=@Ih8ffXJc%RR{>scr}$=4v<$BMVg9O5XYX_hG2^ojhSVtpePebFeE%G>E|V9G z7nx9en0eP!8K!x|>!~kB)0G_vJhhti^yE=w>f&J&RaIpz)PqihOMl0Z2KgM)10(ro zOg>c@@gq2uwy=P(RNw;d?ByK3c_0q>RWtSOD=%sxz#wkdRFStMD{W~9bHT@B6H@Fe zamS{Ld-4cx&?aJ$i?~!%#of8^d$g$NMSK3vBlCcqAZUh{2NK2Ds3%`P5U+65Jsfd7 zEirh)4Ah+94PKSC41VU97pHU#VLfFI${R0JQ5UxGfHN)hj_iVwxXeSTGvm%URNlg3 ze}(sY8+<=FpNdap#8XYqBP(s;fV0Ft2U?E#lZR5}cdO>88C^}`I}(Q@2)A10`c?)% zRpsr&wrVO*1`OG}wVbZ<3CED=MHAYC|Q1mGT|j288%_>TM=3{gtZnW@M!; z&A{zB-qoH^nn$vJqOyH2?Z|qDTauM_FtRaM%S&l?tjZhJ$}7L(9*h}??EnS7VUa&* z%5yY-168J}DYuQQ7-!_vKOHTjAyca0-zChJHE8oL#g__!ldmIBzZO23HZY&8)V5BU zo4eOgc?J6ddIRbErG-L1Rr;Qh-Iy6F3+VYz0qOqG!|# z5hkZ8H|8Xj*j}sXgjPb^k|$y-q^ex&vr@}28zy=R4(&s`Aw7K}-K94lZjdhQWv_>-5|*K-Ph=Si6?qq_vKHypeLzE979K^3J4cnZP}g_=%K4!-xNJO` zNmkmz2KI!I)FdAdPpD~g`1+wX2ROqo-qsE2C*KI8`>kXUe*b|veK5J`f)irm6?y1DDhTz(X^*eAIc`#pTXBRCZmHHm_9RD ztIM`Ml@ZHYv9TJyZQ!#Sn5-0Xo1I2UFWzswa6Q|B?X+2*!g~vAFo~1oX)kytCx%pY zw*iZ+;Ne|&5q&1hgkCSX?{r~{S|l!`8=uR=EY-xNxrCRBa5klWNnQ5!Lv1=Zn_`0; z9gr>Iembx{o4|MVAYJc(M#fj|hiVcvXMS_EzQu>wZO=WE$(pL}rfhIh*`9(I3e6mt zua$N0>372Ketifp$%Fr{S;7Vqda)d@?_`&~AFp?Np*bdm8?{gDQaxifokqC$K+k`K zv#z7yDvR`f!*o#nf>1a=z&9;;hm1!DU1S`C5!ifgD5vx;CEO)C>3c+rmd1HPOPNLM8~Mr0>Rq!h?dS0;Z_Tn5HT$sIo^X`gxFWUdFUdF_X{B>l}j5 zDr0~}C4DL_$zyRrJ=*y0M{byM4kQYYmlw3LE5a=S8ou-icnUe-P^AJEHI)>UKy-D- zC=8$Vx3IK1ut=Mi7d$BFratl%xY$zWQdDp&Y)!!_ew!#9H3OThh*uOljMA$%9;JKv)$pU0udxRbfGuGoD2UfwV1U`b7mZu{8y! z&~G$6)h}T&9|J6EWGV_S@gr8@%gkYPvm)k@mvS?*;(|I2kZD3*#`H}wGsw#e4(jV% zL3&ldv~?L1R)qys5;-;vOq}pxY&FGf6?1YCWi;ICf_t1XogWEft_6Z{EUF4_uwh4U zoT#+=!Wc6t;Dkw0RWM1n8roSHC}ChK3i4r7f{_yXxH_BfnsHN#3RVhRQ*y#Q%>8s3 z1D*89C@&N~rd-(M6$KXxZ%eQC_?8;;^iicN{rW-zVczvgHs)NS2-mW%;7EdHAIrq9 zwWZ9hsNl}EH9jZ$_*)o0LZII{^-z@4r81vl{8F5v8B21isW7J-OAE?)SK0eEb>LE~ zWsX$<=3ay7mLz?et|CgRuFJv@bzu@nA&q?YF0hy1%uf|D11T#g<_6c(K-QXV@iYeZ zpaBOAE@hRcgYjfa&ToCaVeys&+c{|D+%Dtdo## ztHTr$g-!tPlm4u&?n+a|a=3^hf?JK;Azr%mAOG>UzYYHLA^!KbzagpP%Ld*y7_C-t z>l3vSQ;G24yc&!K;nRZy_=I@;6IX|IGl1vtF6ZOHdX9Jd!~c*JTw?`?1)SvJmNUFk zwi?XO2WucdZq7&7(=}AY`=s#sK;+ciEaodnWjVb~RD>4d?aqT>2>e$PG+n9%;g-k< zzH6Yy?8ra64v9;|zW9$iD!3T4%7=BH?Xth88Io&JZUR?YHb zvkdK;tOjdHADm83m!swFUlUlLf05KfjNpI55DwC~#cv){@)dpkSUyk~#t|Yv*poqx zU5GHe@m}@o(HV4C6R!BL;EU?B3%EwiB!VtJWJ{n^An$zuchs?uVW+;i4WDra1p;y5 zAyqJ}kYR)f&-`M4!<@VNgl)sxm(6rB2=6w8vG~V;w2gEL0pjgsx-A&5H&d%(-Cwcd z{I7$({iDPG0@82hSV138272h0ibz!lL28KZlq%?v(HfBQ9JXn_OK3jFl*B6odzQKw%G};snJ^zZ|CMLYvtqHfUfnuKta8hhEA! z?ekfHTw_j(3&QDbk-!GjMvY4j9M_XD4*Lnu8wQirCC0T#K^-D?|-qEE9a>li6odC!4;p*d3E!VLVg%S)H$m6v`b_Qcdup>>D1cLZ|T<^ z+72HCz?YI@?wV0ve0r(1Q*e?d=Jyw+87<*`JNR$WGcE7Lz|@5=lI%9{RXA9laQi?PFgn)k##4bGBs})>q098Y&!z0SE zf2Bb02t~VjW`T78VhnRp@PQrZJ6!5vkC--f^uz0Wp#%39)A?xqGvqpf6m;7l7v=eE zoEH!bbR|s5WK#i5UO*;9vRLiE8#V3=mJS}@+@F2Kt%uZnbv%DFAA{vJ1S9SEa@njd z=hIM?v}kJpR-Ru~A7RM23eTU1g$o{!J6fLge~}AUZoB6N`=QPfakf{qp+>E)nkjgi zzp3o?)%7&JE#@rk?yH$^8#o=poBW_;@P1%;x&Ae|2=L`{GG3@K!i}cTG&&q81hXRk z*uZ8C2XqB7^hicHI2guPzF|&+!2%u!IJ%Mw&0a4s@+`lIJ?oLwz1g}(FtzXpHT~{ApRaOH@4C#jOI$31 zvd+alq`E!BBCgiCFH%0(1D;klsjl{gJ#J%sSXx3VeZ`#++?_z&*0T)|&>dTkQBSo0 zfEm(){vNch?mK{oC*-6qx}5%bOC_rV&t*bGpbUE99}t|(VZbx2?bI%~C6wWdmd*R}G>@;s zy$(!)j!LQF6AR^JFw01rxg zuQ-tq3Oe|ZZ388|Z?q_gheB0iMzP;IBS%6AOr0-3eiWM()nSN9(A`m_fE1KMdq=Es zhf6egs{|aD@%u)UU{8gYc){L-Ge+`ikhKrAm8V+3hB4R>JRsIP1SaW8fCaO;4@m^; zL6Y1HWMOLKlNWz2senehVyt@7j^QH((dFi}d;Ciz;yc5zxnuZrK?{LjI|=*(FP70A zfi^k})Jg8wKI9mvlN@ZDe3RG4d2$^Q$ariInj%PE_d^)jt7F=pyOL_etRREA!Lm5TjQiUe~>6sSf8V^%M_`{ngnKd zzPQC3i>4=d(HEkv?t!=qrKgnaKEeYLhy>qlvABwvtN@gGtV#_*fBFf%tlr?J8F}wx zuIyO60Eh%qsT;&wp^?ei&@3t3#tKqcXh_L!BNWEJD9rIM7K67Jh4HJ#_|;(WR+07- zLF6ih&t--TZxJOKu2N*U%#e{?L9aL>lGH0=QfR0Z+l3IKDn)~S8}$6p35xN%A6R9X z^}9#vRnw%3_C56)yf6OfYoZFRKOgcai7Aw( zuTqK~S=;Uz80MwH32N>F_erdDsC{v#W+P+e=xm@udNIPrJ)X{RDf7|*N3bvZ5N%{m z%F^Q`Z7_q%Xlvh^LB5)SF?QcGb!OkN^-&7+v;?pjq()R(ff5hp#bi6#eHoPbWp;ofuHE5eX^&O?<=L4Pg#A?RhHtx zjPi%IzdomRLKy}d*(A8!p7p=B5g7EfKM49ytHaCxj~6#WfA;aq6XZQD45snL*%c&N z#hM6x)arw0bl5$=Y|9}uroZQ%;LA@)%{NLz`|VJK_%RcF9W7c9+w&RTIPO*Bm(ax+d3<*J6{O;E@K9jGja|Jc4Lc znrEAww$VZq?hEjr4%p%3Y<<0iocR6t7v4*;GM-?LR;l74 z!8uDWyP24z&D5lnZVkyd<08}8>M*LXMUB$9_?|k)hlx_ot`;#LqYRL*Y1Laz*Fb*U z+kUkRw|zUbHHT&5ZHum6+7Fv0zB1Rgfji*LrXJhYSTsEFW&-ay-e{Bv%!TpXQJ8<4 ztwvXiDO~zU*XM%L&ZnfawJUUc29epVKNR>L<9CZYvCYvoWg0$&2J5r=prEotLQTFf zhcd4fMG~U3AP290y^2Q8o93Lusv3!w1~5v*rtmGaAZ)|!-T!Y>XZ;dkoc{YkCO(oYV;zNt)r5qidm1eG)j@96F-lZ3w%2* zEi?{Dz{k9!@LYk|F%Izl3IPu>)3TLlc-uT%@cmmWMlI<{bcL4B59F;Xy@^6*0m8k7 zgL;DxFQoKPF7QUGM2jO9?%*)4$I@_X>FWK}+l$lIehY))c_5v^kdedfH_MIo+US7C zM%MQ@9&Od_u&kMZaAeE!J`h6(EI$9!uM;7FPBNtBU>BohF$=F^*GU$@y~z`1hoP0I z)4!2&tA&MHwYP*f65t{}saW{oC?kBBL@gNDR(w9hNsiQjQG^KXDH)ut!hOuR615P{ zLAy!sz=giaZnEsh8a-Gc$^RytvYds$rUtOeu_{duy!q_J#w zs`B#VtrfiqB?l{0^CnGjJ{+8%ubMU3?AcP15BK#syvz~+!4|Ir1}&t{Pc8`0jQIlu z$jR!DohFM$kFYr2eUFwE(Lgh^u=xjAYF&`fuibB*giHL+#rL#28ue2zceIG}^K!Co zfWnj>@lbQp7nF9fJo{-=x#X=Ccm%_EHwRE;{FwFBfZf)IOUNZOgoF6U=&(sPLhVF$j8wzoUH+}q{JRBs@-=XxWFrUF*{h*$J#4B_Di zcvwQt=7UfmXKN}L-57|`je>9nK34;vc{sUgrVzdP2~OGEysZJ4#*uqwA7bOt- zkS|KaNrVO8K#%g{SoNNQ;SqF=V&+8oBF6sJMgJEuP8Qdz%dotyKZM0U%6e8?^y)J2 zTu-KBc1jFEwB)~&_bI^pY0I|;t}mnI#S9py#OBom4=IO7qw{8axg6aV(uo>Le;&_C z3x`;uR0Mx21-aWBJ487=vJ>CJfi0wdbv`_`V+29YnJ~rTjkSUN@jPsOJsJ}L)$Z8d z#WWjGlz=CjWg$%f$QoVpvQ*rbcTP%rnaJxKy)eOt`2Npzu$xvxco!hB#`wkS9rhCv zCEDKM&@4B?x*qtz4tcR`fd1@kf)|wp6?88%Cl)%6{AP~t283WT{Z|CRRd?B};MLX> zS#Irmf*&;q?HFF^79}!;;&X?QbQM8I;y-4sqYW@keCYX_nb54`X#j@aG3mDkR}**z zGad*A(3|N;TOX!}HDKTI$ri}agVmHhS|vEu&Ssdfxg79wlY+5MsNBFBTSI_Dg@GnT zd=GYjXf7BM@|+dC9S~f7LWfY)%>(*v$QB6?f*z|3f}bxSSXsTnO(_KTz8~Z#6o?Q~ zZzOO+^@1gp1}kh7^fD>`DQH||u-r(#pvCGqK02ar=%83OW-nw?twBoRiJC%Y^%dNz zf+l2FQ7iFnkvIb|tX-e0UcH2j3u?%j;I$yf3Ikq5;sn8e4#cyD1V`5zPQhOvj$%cu zM<@uG!MCv=K?yYmT*3qPOelysj3MC0h6Gnt8${e2*heAzfS_go2HC_^1c@pPaF9Pu z2VZA$7()Oh0dwUhBz4tnY7xSNHzbSTg`Z;ohIc zJA{$|8SIKHTQCK{U@E_%-$lVp5K0QcBNbk*-hfm}XO8TPCv;rLa1&FtHdvJ=4S8X`u zIh?Sbq{K~WNDiXN=M{#qN%9nOP@!nRFN2up9(t|LAr!H^!qCN2mPt_*p}0~}<1#}C zdeuox6k57ok<-P7qMW(QGlbMBT2g2zkts}P$FzOAseB@=MNmv^m0^`-^p$dF)rx9X zZb;^deBRLK5Q=PGVd(0)#I8uYSvf$8zEj)6ghl}NduON6gaTNFOQ z%Jh@bwcv`Ctul=A6uk~MIj~}qR~Qy1k58ly6^cwKFz9)fovSQ#Q!(Z2DSA1op_|TD zyu+0HS^=VH7j+f#ybspNGl)Z;>nh|W8Bh8(iMFSAHz}-9VmGftN$;#o$(kEI^3{ZN z0jwHd)ESY>M6)74O&FEHic?u>Sjk}xjod6fOjtNTiicBcm}F^NXzS}-En$-vhi{g_ z=5>;l8`6^BloES{p42I6rO;5?HR(@6C)Fq_smRcfe5O(wsZ(^M&`?t8P9g{tDqQ$w zkg^0PL8D@YNWTp#t(Oz1Q6LMawlz#bp0K%a){?_JcbfspP9NH=?^Hjald(_0VJa*LVE;hWQX+MvYV;cX)1n1i(KO#;?}?)G)WS1D8_+vQ+zXJ zOrh>O+?K}>R`+#sFVN)(3<0gjd;yqxe&-gWig7Th#6}r$F4P8Tc71g?pTLKRYm-Rd zVaWOz%(|lmTvi!Pqe|piCb=dX;2s&*5U1`>-T?O?PdAHsIcgJKL-rsHE&ZQkxUV5b zrZ@c(lut14JKYVCQL_yXBSk-E#176(Z{F5XljF%z+TbA5sA;7@)}TwV+loA%Og(VZ zfJeaaqrGhlC#?bru%d%)qtl6>lHwB)x0^^%_*_@?PaiDsqt3XK5&68-8_v*xfahzTIrUKH5sVf>-U?qHkC}^}^LBd46J!@Yopv#YZ-;Tu;?6Fm9(SpA zSmx+1%gfPnjqG;m50?Yg{fE$n@0-vUt$0R}di(b|SNFI#( z8XnVV>CzlD(r)R#;CW5SKQx}GM^fx`DL7NF;H!7H&u8#33oPw$cR4HZTAM>exh$gB znY@@-zn{k?2j~A1&rCQKR84@5uj<)2`XmF+sFz$ zwi$q8n3a31SRx&K`^RACb}gP@^?HO0&ioK7GBFc-JzqS(Y0j>3=ZG`s5c>A&39hud z(vvZB)&oNJ+v|-CAhLruYQjd7ReJ39$MEFIYeHWV^|^$OQ1*t3dY;&w@Ebfcl6G6QVcmK{;(2p_wz$TD zoWN&cY2^+=Ny+}~d>+KgmQ2JwxL)54nfg559jf$A8g+*?VZWV+Cz2}YF^im>US{f` zj)yv5kmW8{vwGBUwUt3F$W^hZqdp%;XzU{&phkO0gJqRwgx{~OG zOiNY26Ls}q9A*POlG0OmvUz+oU#>|Oy`s6xPy*b*P($L|D|qp03=Xh%UCKavbT^s< zaM^!eJ};Lw50aIeIXvsOxSX6FYWGNXVLL+!TXGNOpko}u`CHW=;07}34(e=N4P;f> z>=rW9vA&?RGxfhrESGk}ou(GjTvfPk>%IcKtGu1QP{jluKzfObzXo z&IW1{x2=u)Kr}Znd@!P$hY7au(mEY=d>x^_=84Q|06QKHOYE!ueVqoC3Dib^(?R^7 z>&e*%a=&|K7nn`xnJ<=>eZnyFlt@L#tVayy5U&t<|A-K73?M9W942550)ldx+z3Mg z?$4@A+}40^l5P!dlPg+J^ISwt4>!kQ1wAQuj=j@>)5emp>%MHX&u3!`Y?{YAB3|tX zEBKz?A5g?{10%p>j%LPaz2SkA&=Z=!X6ass={{skbn{)6bURFXT zJli4|$(O66gaPU@s)tMZPtW}vAIzq=2j|C^6CDqZ zYvk%2l%6}hbpwN>8%P28vo8h98?5SXt{P#$w#b;NuG+Y=|vCx<17Kx(rD=zpT#jeS_%;MoYE1{!WJ`%9!ks$cW_A zZFf3ZJhVu67Ut;o>gut33J3Ad0>XnL;QrR=4>5w8-bRB50kA1JBxtDw>qaS-XjGe4 zZeLt1n+urbtrWIkafi&O(oo|i+N?z&7WiR;ILgI~#({xECyc*hIbNK$me7pMdZ6EC zw|SrO+bKib%~d1SY^w(V^cyPpl8b|%mVk5!5MtJa`nG|61J@6+c@CA!$%I+xth7uh z4ZMeZjSs`ewXm&ona}?0a5{n|ENpim;C(Tz3<1Gwr`0a{>(ToO7_}U?<_#o_rUBe_N#p7)R?rN3m~XZI2@J93#yzIN zqe7#b()d8NqgL9%=&&>pZ&4nT!<$)_O-98u z`B;K09lm;{K44CA+>5%{%;f2$Jhm}7-!YQ`a&Sz;%vMK7TL|dYc1?HB>#%CsJWK~G zpbt-3g%_{U>ZEB7{u))Jin36^aa>QGstz#q#vv>xgt1c)h0E#o}Hp^ z9C4($F1OkOp;s#!6ZXdV{#>8Uk$jK!z?jTXbTJB?=?Pg^G5ncMk(;cp9gAp~nAIg1 zE6$b6jefJ+u6rU8c|_`5kD)`tOKxqq8u;Rw1q$89G%y1-ruat-gfa29LZ~ZoXbq7w zaE24=3=X@*l7m%HVwFMQrM(D~31$Z4;lC${e7A&G=z>-nItD+^me2t*IRq&KFv$Lu z2*J(j4X%GnLU5(tAX2}-cUE_7F%=6D`f2bv#^BL#uOa|p2`&h6CS(}I9y4Jd!PE5? zb-A1`U#~9i{VX3Yb>`-R2q2Y)y|<|5Xt?ASNO0Z_X%g?lHc7p1?f2T~1WZGdLku;| z4yOo_jS&o?GJieFxXAO@LAtad3eghTP{)-cZV#Y)Rwh+z@MyLr%t{kWaWX7*Cp9bg zIHk<93a3JFBAAdYqf~AfMQsm>$kK&WY(OQumJU_8ET4nAO0l3znWdq#C~>9JzqQD^ z+|oeKsX0$8og=o9k}5;g+_H)`cF!v8#E?jWRoFhOv3+LP_D&-dMh=QY^q^OMVNTWJ z7_y{zG4rs}L6vC{kvw`So3KJKq(z9BBtycnot(-&J}JYm!lxp5!m^xFxyLEx*KNir zVOdV8+~b7v5)BiRF=u*9pbQP!r2Fj;b_KQghI|;Rm|VA6XM`63o0#FkW}=wg-hLpp zMv$&NHt8=P(vYj(3l%y!h#Jzo!VorhL4_PtC>rp~ARa1Dskb6Zy&@xph8kRW^ACk0 zkO5ItO^qRKF8_I>Xh0NcQ)5W$yMG>CU9X7hVnY#{Vy*{f9YA%8QUW(rbXVqA0@Ddy zsMcW>pE{7`OtudME&5z1Q$qM?S^^)!un*Bz*!;sE!XW;Z_m4t>L3i)6p(%lzc-|r* z?IJ13-Fm|~?(Eg8Z^BI=6$>e}bo2XdiVRg~68QzVaLo3ueSw~{Z%F8QkczrjZA4AC zzr1;r>J-IPWT@n~y&MZX2T%m_3PU!!MXMLQq$6@jML(}F^n>9K(*~|9Wl#GH;T%K} z&MRt!aieOz%jIwq9FLvU8lKseE41gc0^ySv%hb%u4Q+00d0R^eyFgwOG!erHhD$ap z(4*|Pu*!?24OzJ%tuIY^+OF%B)VkPEOgC3NYN<|9N=1eW9{OsxNu z!xNP&6-6$ygpykr2s!H!-;&Uz5{g60371Qgv#SnLlsO#}W6rzK*_E+@V!GHJmj}HF}sK1$G#q*Dl`vw$gi93fZj(=b&o`gUD^H6EL z`#ud7MxDdS5HN~HsWc`UxwP^u@BJhc`(D`sD@DK{3uZ7%EX9GLp)2Ab0dS!|3l-jl zLdbX*O{LM=ydP-)3FUAPozwt`0qP9;oJkcc#b_6F?;sFx*+PSd*y=nogG_^`!)qGC zJ4or?WW@B?WziPHL#xBdJzhl0-3!1ZJw4?$B?peN+t_Id&ufTrQ+T8SB%>#0fk&{2 z$_0{Hr|iOvU(V?(S~Tzu$g5^{fyqVs`f^4Cp5mE6Mg@Kwx(XBG4%O=YRcF%r$uGZp zx*RTNsL(8?A8};19_^+Hf=arAgq^bwKTlSTqkrxA*m?9t>{{2sMT&#-ifY^WkasCa zw!Na2!IvtW*PYRdJ^8j7t-Lo+GA^_)I2pRfeTDL=PeDB_9ULQd^XH zU3H@2R%IZ%5n_}EmtY4k%rJLBPu_i_2vHD!Nw3S#2|LI0VBF|)k6{tI9h1cZXi7*+ zIX`gKMlFtV5;J6|v-W402z)r7^5Tj)uT)hRHY8G}OQ%}%USOsOHMDQM9p zl7Qu|o#9S{ca!0Nt}%1i+-3kW?!rMC{y`5-OE@`=oE&fwfD5X$;63!wWajovz45!t z`Dz8pyp9lcB-qn=9!)poL@OoUnA#98r0Op=#5$f|pIvU+8JGe%N$>7t zqgd}ix;s5u@(mI*J9g)ApXlc0^_1UkGXU|`X__jlgXOqc`ny$Soq#=v8?N8G^Tn;o7!KDvdn$iS)DFrU`LA%%g%8(+RT3LW#Ej&q46psI@^xCM>-ve< z|Mao{*^PYx2fGSy9L^s6kwS$(Qs^N=*mZEh0jpqiwet2K%n>rX&(>fC9t%i$0V@jk z=kz{A{mNSKZk&x4N9$WmVqJd-tanF?tpP6mru=_H5q`3Fy=-1h;2+hUdLU&U^h@;( z!!KBr577+a9Y?rU{Yzp3CL$I5Dh2R30*W2BZacS*;10`r=N9dbDO_ZU8n}o*S@p;c z?6X#he3a~Nbe3lP)8X}Og5HSr2e_uTULBmjhI7L8vZ-l0EzcklIo6#48)?NZ^t@E6soQ^s3anK1B|~!uoZ;C-S~^WOe%X&!(pXX55_UfbJr!TLdjn# z9 zBeTK{{((A2*r1#)P@f2)qVmPX2%~J3C}HZW-RWqxilM*}T!STZV@VM|?xa}VH&QtG zT|$MaL2>YV1Pj&R4F=lFZ4Jy^UBFPi?>A&_ApI(x1%d`@_9r)x#n@7P+m3zPj{RFZ z_HXUjSMAtW?bx{;;j|nawXN}`m(AqjlFxDufxTvt6ZiuJ9HJg>5OR?79efyvJa?;M zrc;AVM+VuL4>I)vNTqD`^S9QELQ?SFMJdp2kV}FkxinakOBAqr$q~qD&_GT~Jn7=u zRtcFY@&IXQ-7RQ9Kj$=Zdv?b*;(yU3IRgb=HvtmM_WKhC8TjfmSi?hi|GSo#U zZ!h#wt3A%>umpeE)_7=4e_Nd3!?5$l>1;J%i8JIw*x|XAEgL3&Z}29j*7+`b5blIS ze7tC?Pp8~=qH}n~Lx->oCD+xtXHHz`nBXQZ`|#f{+l?b%UdKYj%y#S_;EX_8Us$Dm zl9J+6m^^J@&(1PQhww0)3S7Z26}5t2tfj)eYAF&Ewh}t*L|=ayJOA7$k7VHeU_lBt zvxV=C@mWuT=wHV*@^? z2}rLgd>#jFVAa~NM1Q+K-YFZpe`59K(B`^;S%1 zSr6k{t2?MR;pwt4$zFizh_AX+btvkv!5Q*yHaJf^Fj_y(KQz>pm^rlA-vcqjADn9p zSw&Fz(+HmMn}t_8|58oCMynhWHr~!ZwcfJ<5PDgo6^J0b=Y}zHg(}OwI^id=JVeL_ zo_{K?!bl>cLr*`IrShaGw510rx0XP_$2bkhi)7jARSHuzWI_vN{PCQX1E<`laI+{G zK+*QhT5JNz9%%r{=*jx%5d>cyaJ_aP#fLF(9Vc+#-5s|XwK8_oy;0NQLB-j4v>fj> zA1CyAL{I5J@+tw+Vp7O^e&ua{h5JyJ%2#Ryg2ZQ}<734>OxkmYxDmza!p|AY5IVC3 zIbaTGn7VgDKc3$aIrL@hhio83_LSyWwwtg~d}^z_fvZA&i>fYhZX?wjDcJ#Qi@-Ls`{Tp18C1{pehnlEL7mzj+6yl-Mx!zjS$Ms?gO&j38V8zCmu`Zd50;&4`8zTrk7J#RkXTsOSKVM>CyP zw=u_h`G4lyV=^4rb6x9`ntC{M;=JiUPLQa$YT)w6GJK9c;!8oc6qAONzpIQO*Jt$q zTsLr|Bxq$DVGse5e&C}5%DTB5$7A?Jk8tW>{kBcD5D+G{OCGw?B zOIa_vx-LFGr%FBbFK9<$gJ!#^I?VtQe54EU><0z-LaSzPk1YCgFQIMVe}~DTaqPk6 zczH{52KbhqKAvkbsbgrc(PYjmeGNzbUd}(|Haz9dU@yU{nbp)g7X^OyU^@6ny5WdVuw)2`4j_b84RMwIEG;8Ty*E? z=Ej3<>wqARA(lqTAIDT{kWhl??Ac6&h-Ap&d5XP1?~Buw+v6FIp_hA%Vc$q@V(H)< zM1`#L3Paeql!Y8rC>rn!5q02O#msep#S6LwsxLHHq@9%^hY-AkbTKckx^Y=}cJ3H5 z9x2HTF3gY`ex7i8VAa649#_qHaC(~`pD=`nshGR-AR0mc8BX_xINo&%{n;m+PLM&- z?;K8N8ed#SB}rC^0Ea#zjY5cM{gR6?-Ed;`O(MWZ?6U`bLt}abePN@(XfDBrVb@_Z zdj!ysV5HyoW>ew1pp&GWT`=H>F!A&kQt`yXu%}y$azQO#=}C@Vhaf@3w7v-D5mFz^ zY$3)_-2~U*vdX^4>BvSfkrWLHDvl?ee|#th@ZT?;lb%!8AFd0Xk}FjNianhyIIp9( zr;`x`{zd6Las;%2lA^`b5&jhCXcu#V+(3d9T@&-wYgdBu`soi4cB2^-2UW(uN7yaB z1f^C*z^}SZ2#n1?yJm9727G_!GIpMtVQ?QTk<}`oun#qcuU)4F9BY)Vi$4u+z90)G zl`B;GZE$&Y5mY7Br z>za_DDn)>P8+2K8^ztM$q+St{LPIUBGqM^9rBtWrq#~rEk5!L-0HRxyZ<_U|`SQc( zIR|ANo1VuZjr8ZKsO40oJ1RXJPDYt~@_~u35rPW4kbT~Qu%y1YqmmY|a$?dT?WwaG zG9IqJ>>FuX;G`No9*NLsK|wlBQx*ZtjQbv{h~znhIg`TT-=#1oyVuJlyhBak3A6(& zI(xJ8kZ#}!*j98~_IQ49y`DDiv%nDls-_r1jA(DNgy&MEp#9eD z{V;^j@Wt60-qR2pFUj)~UW%aC@PCA7(!-Cf0ft;xG`-_u(Q@l0WHUH1@qMIdCLX?S z@oq7Ex9Hm#MA(~u!c37YlYS8tM35PHFL=g|F#fs85M3l3FKQ8*eNSEL70H_2UnoI^yM^sJlNd z;VJuY8i54UF4xFqD1dI!F6{;QsO(jZ!W2bs_WT!u&a-^}+$>ol{pbeqye zU+2dLK1&P{%~ALuSoYBxbmNHOKX^r8&Y88|QagM5%rvq` z*Ys9FtWNU!8Qr?`75#(+I-$Q8A?q^q{_AFW(F{>Hpid;rI7va(DZ>utqBxGgbbmX- zl>2o2tR977Advzl4g6z(oYJqv#5pi}XJi_%AaCe&DlkJyCyaxcxVyGMP`Fih{0Z(3 zB!@y()cTFPY6l+A_pe~_;weQRAEXn0B6b8{Ke|GJuoQH1z6>R8%_o}9WQmVtqVu%Q zaW{PA4V){;F*0uBCR2eFK2wn6ITG=hfu8`UtBh;<)y9f?Cg(!jW5fO#8L>o3b+N^X z?mb&|Jeif<2!+53{>vAY)aOVOV^2|8QZrgyo^@a(nzss^Q4C$WquSS?FcV;k-P>P< zi%60LTmh%({F2FiMBloJo52x$2nCkbH7+d9fL`uQ)>os&@%(Ud26yC|VJraX;1ox^ zSO+ePh3UB;n;EW!&CAJj3jH!pntr-kFOeHAA2SH)=gU!hHx1%sL>ffXCjyUMg@$eo zj?P9HtVln*$d7&#*wGZ8#tDcm+i`3qOx86#R1@`nvHI<3dFBfjh8iIDR%;)kUC8k{ zZM7fqGFEb5j?crMD<%7@XYhcD415R8)9H&>#kam%<_i-hy1ddHgR^*rHyneLHueUM zR(p3K$Q}D5^d}N#SalAIknW?@gJ8(QnI&2abvq*sW^7rwq3hHA&@_wqe6`HW`jDXgXJk)z zSXp@NLTJNXWqx>}Q5v|Zw1z2bG#3G6L9@ZJvWPQM=Qzd42j-u(4w z^+9B0l~}?1;HwY*%2n;^Fil~Hg0=7kelE>C5y$ngV$)g~=A=GVbkjbZ;4?)uN+o)A zapch?2E6b5xVQake|A3KY{PN)i;CoRiR3I*%0yAxpTHXu&|7yo0og<@RN1<0=}=cn z2KW3A;M>t3C(WmHr0%&*Zz`QghzwpeADbyoOX;>d$)wLZaS8MNAhMiV~j*;24 z`(ai+s;-K-G&y^Bwv0%wE+Fqy`2VAJw8-qL*QQ;(i{A)du2Ud&7%Ue2x@7s4$*n;! zNNTlhnlYdUO5$-U7~}QrA-s(Qui{V^(-00`;f?=&Sjg8O$f(CB|AD|h9;Zg@vrA*p zfV~Bu8W_LI0xMtyQ@0{0BuJ`6NZWu>_QLxYVi{=imTXvoUk#JD5kZ{}n0l4L_2 z-i73=-rTEwEe(7`Cf!^YWGaof&{Ju>ckx@pO0=|=AJLVqW;H(x6z3kENoKX9ous*EvUaFk z=(0H-3)__9Vmz9L!($o{)gK)^lolqpNisw2={vk-xOiLG|4N;sG9BipXq6E(~M)AXR5a#dO|Z z9Z$~Ban{9o;psLzHnkR$3kZ@f;h{7% z>ymljF*D=7*Ean(>JC_greKIX#=xb+%tOiw(df{h;G~K=?v7ly(zK7-W_@^g^dnlF zyJV@ZP_*YoTPkYn;}42=9s?o z1^afLqt(J$a_;w$`;aZvGch+L?ZgL%GTYioZ4JOdg%|18D<|;uB*O594(>rcNg$}f z_A`4V88oXmxXF~ccT#GeMDxCuM1$|t@bncCb8I7Hp0f(7_xs#5{hS%9KY@#QzWh8X zs*zXU9Mu5+XOe15l4|VHK3S>(G${O?(^Q4X7ni3RM5`pK#(rweR22eWe5z_}PXAoh zfDi^>A_8u*s(`}gbKkp=6E^W_j|PhBn|qUZEiD)a-s2ztYD525CptuXwBeC+|Imq^ z?PjnURIfRvt?mEaD~Nx91k|9n8)Tr0I=o4ypqU_h^Awf(35Gv1$aRV*)9!M{Y5%(Gg+|E0kHWx#nB3-|{G z{=tC%8`^N_nNqIg&tuG4rhTnCgZHO-*J9q8zDf@v&|d1=aIj1noG?3F;6Be}IMlv4 z%g@MIF#!!!`+FG%_z&@9hLJfbOOIDG3}#Rn-r2zQV>cmR&0s^lue}J_xI5r>_y7*8 zy19iHXXyombu(MR4f}jYmTethZLqN2M&IP(aveg0C_yKKR}TCpOtycUTwUXfiP}=t zeSe}jJfAin>C<5?;M9N4OB+1M1W=CgNl1^SeWb`2%sW*<#-?(5p=ZVWHi{#`pLX;o z$Ong4h`~v?|Sw;~cNHu!K}ypoUj7+-VSWPIVC6 zzFXQtxETQN*o~WW@IH@+5Y{va4KHEFn<9W;VY;s1DRa!35~_2cJ#ylvi|+A+9C~1T zJv^MlA_u{b6bDG2aB5+#J9q_ov`?A5g;ztu*ZVjsaP?{0TzIk3B=QVGVm6bp9&`A4 zIa$MZVvt}A3v@EL087|1Xv;J&g5ZTTqAc5s#q^fO6+bxvSGHCZzH9$$T}J z%sL~uC5&OL0E)HACBsmL5Q*qK{=pqW078;}8XEq7DL7fZ!A)D}y`wDFa7q@3h+!er zncP+xAysb|HkQ!$pcD_U+VD|!in3^ggQ{1ARjHx(@9bI#dJC)JM+mB|2BSep)f_+; zQT#I;CkOD%z~y{ASkEc$O8>#*(;1lc>t+Do+M?9X6@H@}zaaqo>{uXC|MV;L@hgN;?GrxA7qBof?(bFLK84Vat>LA-1OHeag-lI0aVYTk zs*iAX_!Aff)|&ge6VOyA14u3Zyr!#26vOp8&f=Hzz|`xY2?qxP>qD|UQaIr<2I_V% z*fWbmEuCvRiBTh>S(_WVUQcT1NLm+JyB2ieBr|-C9qh5l;3JQ$%wv+-OmJxWH;(1y zQ}JYXvt^)^_rVSgypF21QAFTcWo&bq5h<;nE}>MZ=%gY;hS$vU z_`+3+3YQr&X|XJ+q#8ve6&V_O8O+yF=^+iHDC%NEHCy=1;wf}9C`C9cx0I*z)6p~~ zz`>H4{#0Z$5KT9$Fof^?_M@{>i7c^F2@y*S_hMBN60u5=h$TqkbLQm1+bo|ahKr2) z9#dV;7eU~Z4#?K%GCnek@j3b5yJLoa~vjuUBkCQx_J~&!TCu@9Z5`t~` zXL#789ymEVhR3DxZNM14AG~f>mwS_s6TGdYX5irU=mz5a-sG%aObcO8doR?ef;!9{ zjXtJ0S?s$RTqC+?|4rcouo43@voc&68{%#3q`NP{k1Gqs;6{2z(liEeb8P_ckHx%S zOI{{&B3e#}a69(n`sPVKQMml6EvG3bE@}P?WdSKrw2x=21)*?IFPK(xy||bTpgq--H4tNKzdI6{I!C54BV#aZ21m|4BSeXs+(zZr`VQg0;iwmCsdwFXIVdhek>^QnawxZ>?yp`=j^ zwS3D5z50C)te^9sNLLB>mZMMLpN)^ge4c}&$GGo7(!u@nVA*o8bowiuL1?LU&yk@1 z4qlisE<&GV;0nbr?jY*OSvi1`??sxx7*IZJ`8W>dIBS54I9Y^1ZyOr z%-BNm5G!A~N0{Lv#rB+CkfIM!l$PN75RE$(roZ8X1R?KH6?#&u>d3-DtaZyvd?4&- zeT&CPcs6No|8RP}l0uIk_L4v_%L3P9iJft@o1!(WcPOUC!kJpp*8f0 zx;i-q>LiEF*}0I$!!b6QpWgTt;E_SXsrBy8MW1OEsP~>&@r7~N^wslTMjhe<<-w~E z;+F+)tqqC_ll3e4ftkX7KO#!S#T>q{y&@jwM7kV8+dX%^X zrMkU3os)1LBZg-V2FYWBt)(%C<20|%9(4hX-I*sDp`ASFjVZ%M(h0%qiWl&0fg}?rrq~E%JC4}sooSxQbz(}}d ziAm5nbvNpFg%G*4ZTe{S9FEqY^7z>m^~-C4s?Ic2<9YpmJh}jL1(wSr@W{?CJkkIX zNiLf;++Wi09!aU*C7W%Bj?51*xlIM3;{=_a0o_8`7Jom|Y~LcDXkGheUg`U_Of%I0D8P|p_- zzUp`6)sTG&rv>NL=(L#0}r`*MLPYF)W3l*jPqd&tW9_<8*Wu?!jrZd4Q$c)5YcJAA|PS zx8d8|^3GuNH$-o`S-7wg9@&K(Ecg^+zYa3(>f0u4-6M4ulD=n`VMowh>DdXt?*OB; zxR>=5_HHBgID>V!agrGio}hHRK(i%WS`UgEx zWu;xJAMFY2Fh)SWMiA~U2kvW zpZ*p>xP(3`0iUc0vFq%N9u`7`OlE7Mr+?=(vznZ?t}?RHz$fBC3pk=9^chOEoy!bG zl$u6Hhi`SFqS+$~zS4*-I zl~GhP2u(JtFmzL(1q>N>OAF0ZtEiU_i zvA9CDzOpBpc5TnfD^#->NGT>(J7QvSg&^v9kG@r44t-T?*x)YhMn6P$1)@l+QbW?j zI)o5ZC<5@yAm&jD&%(|j6tTR*&@EyU9_a!|Q7`HY0~4D_Az5j;0Z^n(jU}ANB^<&z zfF_*R7{XpK!s`_ePBHPS4JRFy@HpstMOhbn6w{iJ2O*@#Ib30BIx9lhlQ|~A*7#d4 zqSYl`^bd&@QmHr?N+|f}OgE>_Sbd%h^T?}jQh5OXGmpF_k39BhpF7F{G|Y=TXNwDw zFD^kmh*rr7kNwnoUs(u%o9fHHvK*V!|JHIq2!qe=TR*>BK*7s*-^ZGKk6tOq$vyIH zs&|9}n=I<_<=i0-hT&)`FTr9CG+y79GOqy^hVu?ebQ`n5#PawG=&kdZG!1;J_gJSo zgPWcwjrpe;8CL`+vry|KUc`eNxa*bS1J?p$=8vO4fTJHctpk#HCx-Oa02wlUoXh@bT=jIoRCykIdl-nQY^!X0>7-P6Jo`AjKG{C(Wz&SI}4&P{H)%EBbSf<~S zM+avka@)R|Turi1t~yCdIV@98E%v$xFQ$EL_O9VN{u#U=+M(_ix)%$O>c{Z}?}oIG zufX*pTO6ys4v#>+2p*iDubOphrf&pca`jmmAlZxL$reF+5Tk?I6+CT?hZ|a!xWpsO zl}y@Vd76MOfdhDydX_TT0SStTohtVj8dS~Jq2Mu3?kUg^_GfvV65K|)mWY&jc50Ln zh=p&NlSpuXJ%TCIuF(R=RNLkvg73_y9h+H#>P_<9Y}_oTFc96sGH7q&m=XJ-Ik*PZ zOiioyZUXI1+&cMclnIWhwq`qH?-96;BDB(d+MjT8Sf>~%&Wq7fm)1CG80HryU{0Vm zdGfGfW_0CdH+FyqW^Nt&4nvGO)N9p69yvU7NlN0i1M(Hd@V2TA(R+QCf%YQ)ax|Uy zBCP;>5mt@utFN(dHc;Ep-ahmdB#YlVBe1=F2s2zivZ`BR*ttU~W2X=>vuIJu&`{pA zTc~G{o05htyeH{j`;f+7?A(hIP#=QqDrMV%OT3B0l}tO@23+CIOsdpct8*M3L$rWr zZmp_FXgglIag7H9--SWv7J$k7%%Sf-fJk~dr*Y}G5m;1iRPUVtDa3K&i`jhdxvCEu zL-Az9E|usp!IfaWXE>?D;b=UDd=)UuTc%+K$t`GEJTyZ449_5Ylh!+Ix8xeS4~zZT z>HLPRe4hAR;th0;!(8I*XH;*f$yYl$#{(i9p8ma7>$E!o-_rUVGr8 zR7|bw+*fi?Zc@uU*}h)S!xr0a-wPa5ZR@E1-6N12bqc)Jr*akLm#0Wl%d)RONTJu~ z$yE$Ic=o9>kBh42`%t9gs={M++}y0+LWrlqn}^~3zx9Wr(BoJDG2f!bWBg(|AFcm? z_TIfYt{le`{l7m&#>7UHdc&@nxI;6>PLp&2d9UPE4DQ$( z>43WO^`>!lqx#j|&_7b>l}P8#xYN_Bl(V1R$qoIVT-{tP-Fs+{$oqpW1+AMS!@W^Z zuDHjOZT$Fy7}v~EOLqL=MVauWY^s#(MKzUqv7oChWN?x9YnxR7$f2OVEfqks+;BJDwO$!@9|IP=v#9hBH|zQa=K@t>Zrz!~xweD-&+sbo zYPmIfGoN;Fc<&gdjyU>4Of{Z`_TD}ITk1A~&6EX9oF{*(#KMq*H@~{R2xEo6d;I0p z&w}vOt?0vdR>>`Q>n*nJHFNM&2QU1>HWt^sweZ;Tmk`p5CPt&B>lPPkR=hr%hS3>p zcTdO5rMT){mbG$R_?JfM{ZHRYxGnQTr2b{k4OHR?O-$#Z^B=upzVV9B&`!m#Y{t{j zo9km2njaMj`~eSmCi_+4cRmqowVwP_)Pfe_>*VTin_+EMy+`%GwaxX2{Iv;N#$|#JT^G9^!*rLhak}DlSv^v+Rq!5MG4I{64C&bvRxxap z`BD;5kZFPfR?p2a93%(~_@x+iXeahC{f*JG6h0-Xlaw48n8-bmk!8A2Sbo-s&`W*H zj)=ArfSfGx_^X2BNW|#iU@T4(Q2bFLvEL~Pe`GjCATU*m22PL4V<42;ek9 z;p)&rt28u?z}86$9Ykj_h>6A_RUk5p!pioJ7$_tOl<-ACP}G7CAY_1$AOOM_699HD zZ2);Z)dT2*skGro#shs}ZTJ(9X!K2Kq+$RaEbMx_0bhgSYczLk(?lE2K9luvFtzPKbbl{b}F!^p_%DKwu-M+8D zj@$CWzv83ymHY}njcu!0v?-+!ktQhobYmzuU9<7Ypb`R%R3)Vl`^ME72n1;OqJUgc zR;EyyF2Lkxh3LR4fo-g#MJZ%h$x2olq-L~~lt6%|2?~}Y)GVWzQw1J>R9Nf)1uWX` z;6mVZfyN&d8f-t9v1*LR6atSwDm)QTMqNRCV_5l-7kJ{U0>*8C{!lc=&*+8rS(=iS z1(Vq&oskIb(hpgiR6<_SP?7iC+0zyn}^AcAqccG3b-gyDPbmJ{sXQ z8msr+Xm{>r5Fg+XxxU=U(sv_EEUEY$qubg##(<3x?XLT`kfE(Q+dgvmhHa9fvvCz) z1Aj3-eh-c=?~+=&2SQ-0Imf!2*R;gk)^2NwH1)STlft_fuXZLH#|F~yUT4DRn+dh0 z%1th@7~Rlz{R>@QEhh7Yd)XyeqFxgYCUVad1|o`V541Wi1urDgPE`vJX~Lc~JwrnV zkOj(CkDS0QXr>$_0B57|^b!J3IM~gCk8~l7nTai}amT3%G|)AHW)``nW+0;aqTP8< zEZf-;xnKMyfCU#w2+mVlSq|F-aYvyH#>X7XV6;g<1}J^8fGLsmY&n*swh5xM!1YeC z<6sF?tWvD8XJHi=8i*|&CejUR)6x1Q^U2CXBqHT2T^nijHbn{3(-CT|0U~U=V^IP{ zs%A*qgp@ijmj1EWe^O^# zNs{EGj5Hrp1<}%-)7#D^F-hxb@4+wEH0okQPU%TXt^Iq?bCZOGvrHI`zsgJPjZq844fqZc+x$Tpxa7BnRicCZa7!JM9j=e(t@II!WZ+_BM4 zhuCH*=7fkTJJq(H3h12z((RQ2BIIyBU?MDTbPI975)o3k&ek z2Q1RKK|_U8>EVt+&an0A7~v&#i->f0g*raj{Z>V%JS3%MW#DquGcD-_h)#d zxaW$lK-2_?(~k2r*GoN8-Q!cZ(f<*~Yj#wW5988u_omOWfbe=udQ_JD;XR@0(Y+wu z5X5^FQ>D8*_${dEdwnd=gTM*?28k0sDV(gGGDt`g7~zY8$Q(=z5t9T){G>qi8ksRL zMeyTK#mgQc={sTsP8T@*QK4ny0Rx33ffBwb2(sPmsLS64Kp-^%zJzUt>rA)?a1>Mx zB7Rau7{^N*E>jR3N<}q9Y6C?3LsA@{s*wCg11oicq)3>iaPX6XLe30!O{7pnpz!Fs z0ZLAc5-1TUQ2K6wYLhxu)1@jj_pO8^?OFp$Z^AmPFJYU>g^a4WgMn-hV}5yA84nWz zft-9-m5EEh3ZzIDfa0ry!;UN0V`6QUwh&1qkTt)8_cR!I-yRp@MHL;Wyc_YOxJqH?-fj|7rHW!UV#Fp?uCv=F7->gN*awV)0EEX z3P1M>aBZfPLPVON@SXmZIZ37qO!-+O#$~uw5;09e#czmn>)}jCw;0DX>W0KG9kmB8 zVI;}%6tAUUjy_G65NdNaTFpmexR?;`r0bH{sQJ6U!~Hx^@5WS<8B5e zVd?(dO)o~c27&r^|NGI0zBL3PA^ZJ!I4V|nYtWIecJhi=UyED6=&9(IuFVYZTInX5BOhO?@mU>7tDEtDh{_zqmw9gG%UDW`t8UPNKc%>`e z9UCvTam6Gno^F+(smRhcx-m&+Wgp=1c+qvUeSZNOpoYH?_P$*7IKZ{s>j5U~qsQ}` z)fF)wg(RvNZ{!!snb{Ho#hi6WW(!He{0LtZMC@L%kupL|5fJf{!qEMWF)&5&<4?s) z-HVw%3y#l1Ob@+i{6ig){X3{YITpUU9;A!?|g`LAy2hd?Pm*T7uCFh0E*!=={NwQ8mp7)GtL|*RxN>L#CrXexjNhtQc&Lc(luZu_ zn|aUa?`LoawTVzlV9N}!!)YLbYpFvG7&Tbx1;p(y@mAd@c7b&O{e@BrFuOyP7p~$O zYEp`BadfRAy&3ifE+Jmy>S2zK2zO$02HZ`&oW2p;e5!USv=M7qC`_H|%Sn7g)a`_wXDvwol3zruUytMdkTviN2%WJqHw)>MV12_61T+M2o zOB-3?UD=?LjUTV()2p-j%xy3)!yxJJ0*6V;ef7Wkk>d5cZa~t*;tdQ*Bcm)bt;Cpf zauPL)ZP=W4)zs|=`%N`C$I-ruq+M#DOED18^)j_cUv%RWH2<{COf$Skdp=&S_7{u! zVt0N5)=0L|o}?>Y$M<4+_BIEA8&zSmF^isx90~}HLUltcUdgJnb;TYMsBFa5YP{3;4!ElfuFyNPBG;DHa4v7LFe9<7e)e3pj7Y^^{R1!H) zMJfMG|J&6+$NP3Aw<M5O`lCK^iLs8FemTGZ4Tij zOTG%tRY>}kW+dVNN-0#Hyv37}Sl%yphlM&>@m^Jw_%Pp)`F%yxX)nci+RC zE4Q@G8)S8jL3y71i%D5ADMN|=PuRBxKY!JZ^rXJIu5COr$eptoy=nzBF_e>A0fr6M z@#S>o)`*MKv3pOE0q(p(7_t+py}=6f48HPvOg|=t>FK)rs>&@ugQYN%fFxK(E!&Y< zq>%*~h=NTKqtz_iN4-~K_~C@6insyZl_lA3IMU(|OJ$-As4#g%a!c=>@gh9~U|~k0 z09gsL1InMf$=Q2&N;psz@H|yN;HydZdVDgugy()LfJD^>IA4wZ_H8*15)lJgz$`~; z!uwOs;jDF({p0A(WD12+7KrJ+lHRM3sP=CT z6IDOpFZek7bn*{ZWBtfEdA|s8No{Ovv8!9HHzN-cB9GP0fal4ce_1z@6`(y?1Ef58 z0uEv*r0HbF!H8nGk(2>Al3Tjs?Q#0BpQS9(1auf#Vb8|z)AdGt%8~N@BZY0s}hryb<%`qFn;3;VXc=lddeUi?| zNkr_yR{0&kR*p5HCS{03<}{g585dig~ z!84lC`X%RSIIU5s3uGIR6(S#!m!MWlHiqYbZs~G!gf9&Dtz6^!nl8<078j0kl@}*W zX$H@r&IlD_zM5zWQ?yh+mF}p|-CMAMrX7wC`JNRcyjHZ5xi0%_*c`9hrE*G=3xYe9`fQz(9h-x92_B%c*+Zerxng_bF906G1o>42cW#BWz>t(5rZE zB;#d^&5Eu>@35=EjrV)IKaO6#@-ZNfw?=Tn=n&40PP?rUoF0mQz6aaUi4-s6Zk3+N z9$~0Pdzr`P5QZC9UeS(rKeD`0xrnBqsw)OG4M98Xrf>v0sIddK>IoFY&KydF&hw4l z%%>eZwB%fIK5}DgB>vCV1 z-ThRot|7g3|4n->@w+qzaX%G^y^>>|Bwg{w#oe_-+lGXp#sVZ|@~acY zrF^i=0SRIU3VtcZ%wl8KkR;f{7X_hQrrZ@7N|6Xim7<_sQ_6g+j7#YPk-jOc=qaV9 z%P=uXpu|r(h*}*cC_XKPG3$%mdxkcYCUEGR(g(jQmnkbG5*1WnQDD*!$|(3%u;Wk7 z7rmO%^(mNRl0=B#6b$8&U7ifYi2{i~DkySd8pTU#0*JmToZMw;0OmvjIZsp~GMA;* ze=;H=Axp~zX#XY`D>*+?K+m9nq_2{_nv5mW1)Th>5Xns`>{Z62Q~^fc6q5EuT0Trh z*3?3PPEvAG-yJlD=;&kclte(M2?|&_DnX zMfB8ZW?>_RiHr$FT)lF!kR6Q)?NV%P;r6mxS}1Knl?xDwWf{F0AkUaBpqz!8t>s*S zhQ%enn>rW0V!GfRVWx8GK=XFKQ={Sm6Uc_&ONua(RVJXcOve|?P!s}Qr6^?W^J2u1 zB9Out6M@}a8bRJE=@I@=2<(_jJzI>#6ha;ThY6Q z^tXq&GW?9o)MwN2*)pD{`Ej(d`Byk0JM*u6B8^pjgTJ|xCU4HY2QpT8YkZimcJg8w z=LylM#jqqd^jtqWEP7dgkCvy`fE}#vvB>#yf?+?ulT*LE5gh?xTrLON5K#kQHZ5Bk z1|ov1?M!C(a#?_Zs0lE+mJ90Ve%+7eT2t7D;A*dKb$B~OyD($Rq}fvwP&s@4La`D1 zQ9_`YV+*2o%WRY+rfm9FfT7l!!$>nC!e~PxYoiPkl7uedi_#=(l?)M*1Vs3P5VvZ6 z;O3P-QGQECh!EHuvd%nT3=(Vh3P&N`LMT*bQ}8;Mt8cpN8z(8!-7`^GKeP&r3uk57 z)dSj7C>Rm%xY5G;4l!Mr%QuZa116=1S?9Vz?yx7e12-^ys0I?lRUaqwb60m8&L0s? z6xax)NT56eM|kV}B^=>98P4jI@@(nGS}v03UNpIij9V}-tU!CAvW_9ZOUN9*%cR;n z2Eo!UlQnge?9h?R%qWq#U3XVwG1Y#X&p}$iKoYiw%`*@8AxMRL(J=Fk1DsvUTyD63 z9*Y(g;#A~w5Sa*QrJjA0_*WlZj4#|r2HBP5+?>HxJ>gcVxC8g zy>FAT7a|O3>}421u7sz9aSK+;q2PF&%`e0;^kQ;hjq^tf+~qb0_k%F!*nv1&1!51% z%$TGr-Z)NQJFFtz9K&YwPr0<_Ru?v>oB*bTAx7li6~GaaBwIzC<^I;lmw%oJ1#8@alMZ%}X6p@ykl5w$hnF5S}snxr zhQMed491bnyt^v~c6=$S(t^XD5&BA8y)c6Vy$|*_wVTXFyoR^bwJDm-byK3k^j1{b z3W&?sy|73eo#NHi&fG3VaJ%1%yBwZ@DS{b)BJXWZ)fjg4YP^E|p4sjAC8faD$y)Gy znXN0cwJ4{i=~~eHHoNwGt&r~Age~+d%-DjWK4lBSdogDVePg3&*isc-zG=vbOAoa$ zYb*L2n6?Kwq6$-EYHS=8mtr(x3!@+@_!i;`{QWmYQ=68QM8hZEF~nq zFZPUR?ZXV3Pzd1Pa&@5%i!C$;SMT|J)pB(;g$PXX9ILJsf7HpU*>%7<{!sOL(D=o8 z@u6F6_Ot6bP?;xzk-1eFI~jr6ERDMH`O`-x8;t-ZBH-WkA07ULQEAW9sjf=Uzqv7 z?fC3R_3Z*sxB9{=mlJxnFug0IgyWRq($8VEf~9GtK1*RzLeQX}0FQc7TVjebpE z-gsIJzlPCUz`#ebMnD<`mW;{FXx$#J=2Rwz1R(@|DH-Wx2)f>s6H`tFzWK9KGEHbF zKckwry3i?%+OR?;B zr+9m#_g`lB5{g2*H_N4%v34J)$fa)@G-um!sEYmumP?tn=gbcP7IwFzA%nZ>nnVSo zjpL8~8+b%SnEqY>ZKGmTh0Aef&HBPhwIoVHt(dKlRdIbe@iY`|9N7 z-~<&r7H{-!(qOq+2gr>@G!^ z>h3p<1bzXAZ6TRin4OXY1bs7L=!D?jc=_I+0*qPU`9@(`#{yA?o~*SiH3!BZ$eYw zC`?H2#o9N~I5v=m&BBDwHxshm?DcQP0ruc^<9v!fN*bTVQaB~PYrA{OPitiWNR-xK zRE1Y8t!2%@63YB+F}{F1ig@ZB8OD7KDvt{#lkWNa7+057nnMm>f-3&I9#hJD z9k{SRSRy;>y?Yoky9UV2g>%CJW{7f`fiI(SisP_5pS&3V9j}=zp7d}ulUbD}lpxHU zuf}kx#)c08T76L8J6ND^jqv8bB(A%!Q1;I+R&WPnrQCJMkx_lDN&~U4f@Z=r)1KLV z;|%+gBfgOP@{5fC4hC0RK-|WDhnF+rL8f?)xOf#Mh8oW<&jI>k3T?veVFF`e>rjqn zM?a63ZVTcR9|`bJI#jCS0Iorv{{s(WREW@S9xr~KO;(`8>Vx~^<>`xVyu4g+NZ7HT ztLG3Ay|_GH%@-k#dSm~;qUpC zCV{RM2FTs{YzBs3FTtDn#`5C=76_+VzxGlYvSF3K4-YHB6C=*-dnguhJ8x`~KAHF`g4*RRapEe+ie@`AHE(?ws{O#Z0G-VIyTD9YXhOWe<>I)*QqJmE zH|JD=v*q_skA)h9KhrvhP(;10>XXF;F6DFXV%`51|sa-AY*i8xco2Z`abK@)Tgl{-GD&Eoga^-|9(kK95n`LHB zHyNGTO@-)*E2g+veu7KM@C!6Bwks{QY?~MDZ&M4BrF5v6<6JWtkpjuBbmom|ilu6^ zGq)g90I3TCCcvADsZ!np)&&xTj~RZUMz`uzp3dKmr!bkXV9j+)&$jwvCYjA{H>^9B6Bgew*7q!DV0X{8oTymxEhj`h&gF#met4G?m18q$aW5x~zOj&* zUGOhwEEm^zFvCq7ujbRMv-xZrwwdDsiAMFfD9yb4a&*AxezJi1JXTDb8;VJpSYT^bT zJ(HO*TXp1_owpLN$DE!0$0aX*n$-8;TR{#u$F@VIiH`SD+)s0o{z84$s3!cRVtdgsl&v| z2-j7|767q3{{CwGUb!FW%KgJA<6$l?OS}BNk-xp_(V;APF#{#Nxp3h5Wz(_rEVYw|%s9CqAGw zUG9$Gcj)g7r+J()mX3RnyE-#z5`1S~^<;<=cMbWQoPu=N#i%vYA{&W}+*YoG*UH6~ zX{qM*QdXIlK}ZJ^%TmbAAP}f|af!FfO-|fo8f)Jrrk^c+iWsC0jLGlE7g*IoLQ$QA z*|oJXAciXgz5_647FYYTGuY#Dojmzsl|{-UWTpvb-r?;sZ2qEgct?J{LE@8VCL0N_ zHApbtUczSE$4U1I26K0O(;o}8dYz&r0kuvBTQ!R)!QG}Lht_ye(KIox7Sqdl;Az7tZB2(>OcgwJA>zdQv_H+L7!rdihDNw=?n*3xy zS?a(;QQh**d$89}Ud`vz5TjYFa)X?NmTMi~(esCD=Vw5Zry_iGr2DCN&Xw|L3 zOA=QfG6<_q9mF2&nXa#Z<{qlT%d>^ILicCKb9`bFn>T!nKdqc+JVK~owQ>x}u0??z z@Cm#c zHPqg8I{)Mg^0x_G)_1w$;i1RW+pe*;6fE+yG#-p<_2`7=Oby~*%rBR)^-piPdNbdu zzmzgSmsbT)P1L$zBx|g)B3FN%y_$UPranGBj-~38l`BOO#K7)bie|M*?yRrD{R(cZ z+1byN*$P$!exX>m!1}lw>JI%Se}kJ_ol(N8YM;$y*%F5_(CrxJ95C2BUq-b?RbXmR z%!&CKyaz1>p@#ScS?yi(N8FHA>s$XQ>8?VN#LL%(|5j)Uk zwl5}X|H^8oOgR8PTCLHPcCmKK{IrB+eAF!zvsrAg8hJMUh^zAMY6;#Z3_^k^tR1i% zEn&C}N$Fdf05HLWmp@OIt2x9%ocD{6)C~f#$UsKtyj(oP)iPqTG>F=T8$r9hcc-tr zV<@Jc=|vH@!n@&@hAC{R^%8Spa;64xXjMO-pP8XV&cI3rra*nLe0kBq71>&;gceYd z+_`zdzL{nb!D+wG$jMTSm1woz-_Dm1x%mO}-)lXkv<+nw+Yt=f@6hAx-M`^>Wcp}z zl8iG*1Gl4Qw{itTIaDSZye`hwPZ*UxnbSAq4w(GP10217{NgS9?Im{mZrrmaQDtoq zt&FY%SWiHhGwdo!6GS(zw7E1vSgPEE)5vK=KxiPG{c@->(}2eTq8|%8K5rntI-8)> zq?W}EGB$)N{M;=%cn@IdC&MtsjV~?^a7f^7h|w{|f{!4<2RU+*ZuKsjGzyojPEzPm39-5CvnD>U9D`bjGE$W^T#UV{?oqQWMJwc}6eR_W4cUY0a-b$F#tadX*fh(%(d zK#@iXE^jISI5PK=xjf3OLXR?$QpAmV1NNg?k0Pf~qex?EVeBEh!7ty*R!SI*S_gwf zsgUj$qu}%l%T(V*!?$;^{w6KfJ z;tV1o$w*Z~3LC;!`z(+OaRmw`(kTUPtZyG#WwOE{ROka&x)>Y7SjFBiBQ}*;7lT8H zH&QK$dMCI=rsmO7b-I#^E-Dwo7R}0IkPv4IU6aBfKC$(_N8?IbGoKM}>xNiv>h1Mzh)4`{h!|sD+3uO-aI~a=L+Q)nQI0MC6Hv47r0_k|1dm zzD!c+=FY7p!Xy-O%ycD8?ciEs6p0X^QY>hqA@OxtvrGa z>BOz4K@WGM0`Ml<$G&5+Ajy+86syY+9_cA(N(P0?)(=m4d>+USokBFS2L4zol}Pi+ z?C==EOy9WnQ9lBjl7`YLpV0yRnxRwDUg+XwI96v&i9;Y!JWoy6=vXZ_hQ|DvPjjkB zFDnB;qO|5Uv!yn*s?9>H+=3m(IGBZFS|e9g@zfTK2E}Fzte-J@l$P!JzIr;}E(NRaIa7}A6 zOl{RJY+lV1T3v&WKo$n1csni+e>pIocl#WN?D5G7dJ+>UBfOG0 zcB{`No4jkd>VrpeC&yik)b+Pp?{#O3uEU{`F1h}P9DZmf;DQE) zh&VlT0C6d&9USi6IG@a(k0A$Pk{F$jKc~MTU0j{+(&g_|1t$cr*iQcknRW&?YZfm< zfpaStpyVO^v;Vm}zQohMsI@$bN~IW;-bAf`kEOnaI>}#?*&j)o_|>GXQIKn?3pe)i z^y!Xi;(f+p7bb;_KqP)4!Biec#G;^}XH!x;n&cAd%FjwpTr~Yt zpUkG5ZWglIy99!UQ7qX_m1Wn8WwYnna7j728_%-^OTy+!3aomuk#i!2Vm6i^%qJ2R z8`SlG3X_3ZLV_mu!CY|)668KXk@qbjm|s&WASmgu3h7x`FrsEDB33PY3(sIs;F+V3 zVM3DVZsCi90QG}ikUAI{DN+ci_(@@Dmm;+0aKw?(G>t&jNeZ1@Y8EUd3OxFzfWTO> zd`hgNA`p-&MFXcED5LeJ1QIw+QNXG93G9xz-^n_sBmy~2P{7J@#Bh)xFyNPB%zQ2O z$d!=^&@4@fh>eVmC{~Zt1R#G@NQQHR41LBls06r?s-%E;z2vVt7FcqTQ^+sUpcc2i z#~MremhRI=V~s@)*>feXFMF>&d#_Yd@s?y~vYQ*M(07s=@%_LgZF!|J!@84uvQ$2m zy;-8EU!B!FA(IF zgBOIO$)2&wEssQ8Fy-4B!lCPoflI?GO_OU_fx6n>xr+Uj{6~6Q9vVV1w+aK=P=sTH zrOLnDy#ya*UcS+0HmW4G<%At*l~YO_TsN`7kp*eBx48QLGq)_Ck7s9>aR1`K%D35u z)jsSlh1Z*c`!MVL(ar7VKp25UU#>GpMf{dy^nklEz9;)Pu@Nsr!{FSP_i<CvlmzWa zX2azujE*!wjFgANLi7$!eDQEGIeQOVA3V@mB~f)=Qa#Z!qQ{Au&Vs~s(QfQ&dGbler zFhHQw+};D$&+X|HcbN1tZmWC)ttjH~MPaHL>}_mPdKQG**I87obzo>s5t{pHKWNs# z4#JF?7eeM`ilj=hII;ax-O6za%dvLw>b4+`FD{FU%YsTNu12fw3ZnMScx_ij zf^+BG6r^3jMM3Fx_XLsM3)ci`8yiA{TY`9eb0G88c1a}E7uR=3Jnv>_cz;GYIC4Ij ztx|I>SM-R~iecEv2hRZ7ils|JK+%1x56O3HJ&3n=RrG~@DhMsO=(#-f72cB!k4MbV z?ycN>$#kS*B)4=sd_VuR11pQ(yFvwF6Y#&9~x}Fzv zu2t75@sP#8+7hzBfkYv)8EVy0_TH`0oI@SP#w>nX8i-^HxfI_lC9wWu*NY9xf@Zpa z9EmMZ4+xhBA9 z1J?oD{L?Bdk<3Dvr6>U6>5k!K4PJg19R!B2#i0{v5D@51XebjRuOmy!eqdicZP1Fg zAN&;#_ibl(64HQNZJux%$h}MSXBNNh<^#0~Jj z&Q9h#m#Y(vMR1sIDJ#MWB)Oid*uSzICA1E(ojPoY-X=4x=5VuoE!YMY2`(lglq zaTLG*v2lSTMR3f;VRHm0J4Uc`6{D!}C-ffwGxI7Yus9pw<0`vTxVUq622P??_jviY`_s=g@I%J8eI@*}Y2j)&c^DRQjcU2<1XyJ~`h@2|i zVEj>G;kX-YSqn@g3pDXn!KEt!v20-dQWAlhCMaOFP+&Mn5E$@FF$zN+=LzwXG2}-jFTFpajH;^KPoJbLzcGxDQs=V6_f&4d{xNUhY1&dn5aZ0FzK5{WMf;I z>#U_P(j_8uT9~=9s{n~WV^V^Kh5S+)S?2;(rb|%yU19p7uAwRlfvZv!vKyUqtDMzM z2n1~MU4fFFE$nedq*Q@M-xLxV*CrCB3MBewAW3`LTi&ddwzn0eWL3yyRm1*~GpHGq zk^~xkGhlL)JH>M83M;kD#e`h2vKi4;VL~OK^F*aDjw_~-%>opOKvyXWnoVYHU^6z; z2w47zh_|`l;_k2F7laRHr}Nv{d9ehy?!g$mUv^_EyD>(2MR$C4U&i3`Eq?7CngZgT z+p973EbQ7Cl=b}^gW+E6;mWSN9+)+8j&xY2_ z7vF7AeC*avGI6kUoV;Q&u=z}t!t@CS$8Tc~3rqa^2F&3K+=2(QkN8x5Sa263H-Cet zt{O?7!6T%-c!wV*xcilfy$8-KRS!5j4{&4E94iJg*(g0O7Q5pRx9C{D#gH0yM`A`! zSB%Au#k>iLV&^_n>1zy?k{7Wm{m;VUeo5t#^-1OnNlJK62W58IVM(0bS(!e8XPb@Gcz$rp^9cGJqqey zQjHsW`T8Jkx2zFd%lWJf6$+o&oV^5Z zH5>Y=JqS+$O-RHG07(c|GVcMr2S$3{6o(wn;nIMEGNQrqpE10DYeYqE_W&KY5RUuI zOT8#=#OP`fo4>hsuC@A;GSqruRY|e&gS8CiHr%f2o-SUV!r>ba^m_$tG;Tx)iw|2q8$q8$CVo(B5I&h7bk@Z0j=22kw=*3DT>54ZFXxH99 zrUp{Z5H}pwjo6f4RB&OmtDt5lPBd>1v>yY@0!m{bXF?0~h)S#)ADJ5x#P$IELdM%& zo=oAr@fn-|UEI!o0PJIt!1m<`@qAf^RF@%CPSJAgS$+_`Z?M-`b|gr5aJfPH6_*)A z(YL%H!h5o;Abn$_Xj)DXmv0)6qPw&V4(7M8Q`NT|1UQsBO#r|R3O>AW>s`f4VhE&r@bNK6|FWHGWE?VL3hZfWEd z2#IGcy%;u|@tO3LI8=7Hf*|r~+a2!}QPzP44I~L3n^P7bmW*ryR_z((6xqz?kgta$ zId;@zxT_fNMJ}&Ce;zOKB{+N-?Bk^SRBL+mY6l>^ zD??=eh-6*%5N_Q)-hn5}ME`|0c7RcTW4HoaRk!Oo_)PgJWT&c+U&&g~w6Ha>eKV>8 z_jca$Rl{YS+&rlCaV~)C_sgBj$@Jv>n6eWO6#R_`=z-(3~K`W7>l6S7EV#}7JDKG(6LTzJ`izrD~ywSeAwjV88R4_g{ zQ{S@NQk5z-7s0H~m4ieom9+?hMW<}M9D|4yh&KHyb!yg|=Fj0XgK!NI8HN&Ln~Gct zoNh3dOvjX6QW+p6gE9q?R0@O!&w`oBKo+F}OIJI>v|^N$L^wLr1O=>?LktHA0t0>_ z<83-ilezJB+@-0=R)=ZA^~GgcahWD175!s=ku`-UG)A;I@#`#a0%`+kZMSJ69b5CA zbDSm`7F?&n4LZJ@uG}>Oi|_zw#tVkw-F^%;(Kxn-25)J?=Z73+H*q-WLRsj@)9@r$Joo`KQET#oKiCshR^Ua3E2LVyTwb!I4|HCHuby(cWSL z4k}y#%9US{5F%N}uoxR}#6Qqt!^zd-#INYkN_;sg5+0pQ%bk zJ*nPbEYGx(_aG!A=|uxvPQuRxhwgR!JsQ=aY1MoNSgS>Ur)zELrMg?AVT*SdILI9V z*8yC0;ATs2$F5bcW8JyJrX2D@U`a&}ROF81@lWh(SpSEdTCNd4dwc2L=TImOaK#Mr$#^huSebBX ze}vPs=z4m2f&WdMyJfANj;_-CD-ux55Vr$x2QOCSkBs$}MBl_qc?)IY%pw0anDJj< z0>|b2nO<1|v_xNPhz^3Xsl?ltOUgeT*d6}I^O(W3VS*nUF68JIi}~UO>{LLwgX{!l zT%g=_-vn{+jhOr4Ss22Yo! znC$7E89Ci#jC1hY_=i3Hqf>*Xe+?d4s{#u7GVF#b4B85BOCiFpQLK`_;u1T=xFb1Ha?#mXC+LwlyK;!v<+8L!fPzD zGGTy|@47?V7vPFEpa%x4`^MsRHw@LI&m4*Kg)H&b(9o_UwzSWU0(Dmq?SF>Ajb--c zx9iwxJ`{Oax0$D&R8=_6S8xj?`Ur3>k$iv_WYtMRLsxhvUxCvqKS%R&F@az)=bLa6 z;ht9gy(m@ivS0(i5>5l<<{k`9A^^r1DqEeh+aJf1>G<8WBk-PO`_VScFCUrQ&?K!} zMIUl4)VHz!9ux%H&2eK<#I>Q7FMsUx4MVRd%<$Qb79_&09XOgHXtZ7kLlf#_jqYr7bCG>0jH^R!0x7Q0 z7$PB2?AaQu;PSQU`oLg8_cmY96`a1A2;lA$;EL8+)wUeJR^y_`WH5jdC6^Cx?NuA( zL*q*>1sE2CZ-=iAvAn`2CFdl-DIxWxB6H_-3Mj5|!V>arc?oH1r`R<(EhD2zK_6H} zUVJKU?bVkf9G1;p;#`~i!k8-hn(e`GD$?J^d`eYqq=cAH`%jz z(S{|4OTT!UHC7baHM(Du)H~#6L8a3!M(Q6?no>OPam+($ipT1J%q3D4pBhz|1rmfE z2fvWhKYCri)H{JLy`sw>HD_#z>wntVPhg> zvAPXjG&mTLro|qULo^0%HN-62ikMpk6IG4Zi50M03nQnL0z6Gn__EeT17TQ6AVB43 zguG3&;1G@~xwymI^XsG{TaAN+>x+F*u@91xigQHOL`XP%qh8xe$gu95p^#`e&{oKJ z@4UH?XdGKZgT;{W`8LsGG-Mn%U^k>|y<81{(%G-E)rmB8Jjwt}sl5+f_TjqOQoPLN zR@%7O&qZPUB1GR}qM@a~?Bw^Htt`v4{4t1S{%Hs~7%~uKUFEn3W=hiPhFL1XngLgi z^T}*jj+8CaU*oHoEm!k)c^{~>b0uI+5t-7U&?|TZY-&<(jeNav>mI$Hf1+O**qiy; z*|fU>yrNx~)BqVfJ*HjSv5CvPon92++qAdBu6O7`j3B6~n!N7pd24`SVuj-Hv7hH4 zVh~XJ@VEet#%mMCgd8QyQJ_?MgaM+N{}0VS|J1@e|D^bQ^J`%BgvfoH2JPNr{0UZ> zufeK?Sk!5EJA0Lx)K;@rGk&pbE0(P;tZ2?uja$v+oAcWCtp#`IOkAzxKr7c`zw?H! zRysD023uFN`X(X`Mm?LsykjxlfW`ay$I;&W63%tduq*sZpMx{WQ-rx*>UjjWxR%+k zdfDL&;R-gz$`FpA7v|?~a`qmgmCHDuq8I3IljQ`;g1tXhsRW_`R`VCWcGuC)jw$*X zE0I2;3&g@F0%!XB!%eFX8LL$t5FtI4&(-^v?kypjGUR6GYSmf5FuBg*GzobXEl5Wb zaEQo@F|)YOLW=vXB&9u^~^(th+KmND>I)i-Jfx z8^+>g{fsdaT7jH=SNOW0`5wubI$gl(B!#TIBxAZ10pxxwZt7kT6zKXOvs03Qpl=9s zoAx!vIQyl?4n#KGj&-eMw%XPy+ZW5aVp*p}6-}qAU7fP{*1Wb=orB#un>tl-phcZC z-+6mFRXH|^25UNH^bJGWsCsGyTRLaC0ZaOqIh-gR!|}{Zupgx*DwR2UF_}%yFVAZf zs(yjx(kp?_xq2kiMEy7AdFvw4Dh;|5u<#a17TG|SS%lU-=V;>3!D z9)BCU{(d<5hlpEqV?k1KfAkUTOy|cRkmz@E(;0Gz>W>=Lud~U@D-Kpm=T9vgV28(J zTrCu9`{n8BvQrC_BvWwzx+}^zc(h(GI}*xxnOSe8M?!ad=>+Z-OMRFa+E~kyRObNS zTW}xziA|#fVq4sphu4QPX-01ofsJ@cit95QAP4pbxKa{7v%h4}uZ4VRs}Rk5uqH@H zodGKX*$$v#{_jh?((w|`5ucAgtLEVDVjM4UsYX{Ss**|zKa7q)!&-EHwiuuLJ7M5V z((&aK4lHw%#QiOz${PYDZNLbZ4uT^%%%i@*$?ToW;}6}c@nG^~c09d2=^%39<>_lY z^Ur#1jmFdI{L}UY3|=sB4$&FTIIkezljG$^8N*#Idkm+yeTlf+L*kmhepq`BcjV~d z-qjD3M>4{@kLTSO8h;o`s)w`@cey&*>pn*Mat-hLQ{h)lwc^YvIzoAr&5K!v zD&-UI)Qhpz)CUoKRO@opK|w*WRO_L&JS(N)Wj&w6uq`UTXXIJ<1{e2Et93)C-&>XS z16zCLCj!z|;Gxn1Au9`7wD+1tv>?=!zVj21VfPU0kw{c*s%J1uNYLbIpAqCfL6OI4 zDJ>1=O41c?G*YzD!rYNUF{UOAle_PVHnnD$)_qsBWU{bf!wj5Q;$lO`;L_W4mf^!} zF;$65%pj(ApA~6p5iza*u80fP5pyL3iaFXrr6!Q17kJ&RuDK0WIQ<+EkxK#AtSZh9 zQz`b?T;JMO7Vb-@)&*lmR)y#$ieijEO?q%ED9X*j>z5AjliSZ@Iz?gDdHY`KfEHjGQUimN6vx@&EZrc_Pjn=oM* zjf+^1I8kxw#>Ol$MKh?TCm2GCVsOpkt=02-aXxZ`vT0%j10NTjQ2D;On}jX*V+hHJbmy!Q zq2EAzL~-7Ei$v%f+dzX&BDj1@=&?!^{SDY9{?4t~DBT^xxh6-4m+wM@y_Yk+D7JOx zdc450dT}K@>vZyRHiclDxTvEMz(7w-kP_nmKie%_t(X4B{d+(pr! zeDwVnNQ!tT^mnE+HAYYm`TTjmP!jwBa!uP%WenIJ z;#P$B{A?_#Q3WH_-%p4Tgy-AhMT}3Z&hY_I-!uI}BwwSo$~Oc}_Qpd_-fFNUG}s!Osg1(OR$K8bT$W_t}&H^*own zP{QDaWo;n$Bs#;-O#_U*UK7LjNwoCvp`{)RBbM!YZyrW&U-zV0{G4z+~UaFaA}ez8oOEYn!d!wl5G<$Kc& z*r@{V4x6h%%eAdm!GDj8*P!)UHms=E0j8|rx&e#U+Yjkt-#6UEhVo<^CvNn~x7v6> zEb=CAmU}oov4TUy#f11&M7mc-Sg4pAx5Z);Yc$Dx>7_NwGp9)PRYg{pPkDP{RB;T} z@gy3|#PQYr*1yl>`E+&HQ9S@Pg5~?}gdG3i!m)<$!QcM%Uvad01D>B<3_68-L!N~< zMvrc1Mvvl}eM^zy=*t9d)izWpJT@h2v1Q_pW$N4U+Vi!9xpUKWRL-8A@oQM@~zRP3w{|#uLb7KTgaru zoQoO^H}`~*(-p7X1DIEI2r3rQC}o>sCPARYksesIZ!hfLQ7Ev4w}dN1uM00AloYco zakeQL*=}>|aG&06z8&LE$ZPe}Fv}PF&awo8eaFQVCwn((nWh`e+)VCUs!7)pg_Hu_ zIU|qNv(3Cw$<9j|2UvOz5gpLCW$HOgkJXLU-w=VsOuiBHSbHh?4LDk!kC!X|4lBGH z4?bf#C*&Hzt*wDPzR3pdxERn3mRxuju{(*gH&1Z}dPcnwizBnZXc1t*gd^Yw?q5v5 z2gVXt>;Q8qmd*%f*JXUltAqJO)?zs%D4xXa+_T>c_e%Fs+j(av5FWB|MI0iMv|xPa z7(!V_t9S6uwy%r^T_Pyljk*EsHSu@ZfWrGz@yv!p1{dEu|oADHoU{ z_x8CS$+YOPQ>jb6$a^4RaK{T&zS)x|1d{bj10vEWjCyxv9FtCAWj*a-e9an7GL#oM6=>iU|5sH zH)*Kt&QHKfD_dROnp>W2xIYqVoFi3eugt^|#4O|#pu4!p6eE@VwC;~HGhVP;5bRwI#*jemI1+E}WG>$x$zWWzTc;+Z6+cf(~5Uy?tR2Gbz z5Wv#q!m%>$sS@3o!Ghg^6Dz+iz?fn(3pbDr06sXWX8PcyKg(dY!HqF}s(Gp*nl1Ow zFIFP3Kks@+FUA+48R!O)v_%N;e?>v`K$-kDU|(L0k0&S^Z*sNDIS_=hDc$$Fv%nj5 zXJFgK`ynkXrV4Q4l2+v(-<{7^3s{EL;37>g*daQX;qIO}+?eAnmHb^Q&7hMfEjHfvlfT77_tFZ{CFQb-DrlG-Zs!`0Okw~Oi{ zo~Nn}EBC+y5bcFf3_R~tFF39qYFbQSM+5Hy)Wt^wBe=`EKoyD)&Yrl-%E(U07S^Cy z@kx=G30jo3E`Ad`g}8ayi|N#yy!dG7yv+@r!X`xIP(TNIl41EFNikS64)buTVoPQm zJp(a+LZ%>;g~m*fAntg9Uy4y%V$6vtf)#%%USUb`49fr_S>TAT3NA6S7zRHJe*CEz zbF+%MeVX9+9~6RNK`}%~6d2))0uj~{GasA?zJn9Rl3Pd2>C*(a|DX^OYlNA@XTcr5 zD0a3l;>5}roF-uSqe6JUr41C zeMeP?AyNBgzqZFP!MSrTL(*=b&oJS;^G-w3Hr9ND*N}L8{gdr&9AiVHFb)xJY`T6x zAMFe!7Iv=6Q8bR%@EiU#oxdATVLNg94xS2!OvFFE7+%WYiaRAv7H!05Ed`b7Ye54^ zg2&4q3vdt4;Z3I9NzAxjCf$QIBQ=%*i$-pL(9(VzFD^ony<4sphl^u)E2W#k8Xzf+ zu#<}~^B7`WuQCuV@y?m&*=boLqEpyZdbBZ|Gnfshrc@>Ey!a^tZ|Cz5h#Q_3|BF_c5rX zg;Juv@Yd4l`056biZ#Dx5n$u>$4Ku)WoLC&^K($gBNOvJI67)09%bZ6Q_)E4&Fpmi z7K1$_q$I-XP7@Tc8sHfY5(EbPLdM)|=V|73cLul7cZ;pR`~~7U=9de&Ol7qI&n@ts ztfq(E0y@Pjh<1Wm{3}?WEWQFtm-O=Zv;ICgznFIC-ORuG@t40qYhR8IuK@r2>)$4` zui@JDm+$@#0NSvdyO(J9PbRDR;%k4r07^@I-1^HqP;>^8U%S|w(U1Q#+!Nz5VF1|J zeZGBo=wH3|NPiuTmkPz(f(_zZf(e`S^FXZS3+EW`(0BA;)UGnu7#x%kg1)aqlZtQ zeE00(&ZDPKA3pv5$q(E6yFY9`+uZy=Q1!?NyLqPv#Q5l&M~}bX|K{QLcaOIpKK<^= z(}&x;kG_5Q=!d7uM z%+|5yMINB`|4n3Y>o2}ui-i;>oUOln94{ab7nd_My?&j2n9V=USi^jIeo=3wPbMY4~QovHXay=bWbPUlfDzaf5PRUl1PH zdW!w~cZN3M^KN#wdcU#szd~#)-J=*U?T%tA%{0M#EAg6| zYhd5TH-K+W8wWRBnQgcd0A}P1Sa!Z}!D_1y>QhslXFLt{uXtz#&NQesZUr*5VNBhW z4EEltgAlcNi&|3~kgQET`LL5Ll-jBRx0JREo^kA_Y8T(>w^Pq0tdzlv160iP{L> zio&wqN=#Tm7R(_X92 zh_NYWL_MU=h-qksz+zdwkAV?Q4IM=}uIAi0>W~`>H7!;V;Sb457FE@h6$-fWqh76j zAI`=XZ{|~2y2542gGTX$v#HDyj!3D=Oa`x#<}rx-VkRs?vHU}?Ad;6_b9 zZ$qSIQ)y;6O_|NOLWZ>pwXA0tL$Z(Mw$r^If1J$0o1n!u->*yxDRWbyrYxaYMT~WnnoSBRAkG$UZg|uEEt{i)CEgn%rVhs8;Jh8O)GEh{MKu6|K0NYFhCOsA|PID4X6Z1*2hH zXZrpSTu!Z{B$FddTXqx4RKr?)t%6gjL$d9q$N@6_($u&$OGC>}SyZN@I<+jP07J5j z&y&8#*Mspa03GLu!$)P%V#ZjnHIw3C`RfvvZTnN$onOu;a4c$&FwNc~()aU0=8I=( z0Y7{X?|Hj5?x1``wkV=%_DA9YT|Tl5X#tpxSBvf#rY=0JG-SD%ur}o>;RqQE5^L={ zVH=V;U!!YgPcb)TQ1P^9Q85n5r1K`mNO*9_p|3K=x;OOXguY?467)1wiEq_| zaLr0|nh|eP9i}YpRhaS($sqRI;4KP>JB&6aQ1Yvjr^HfPF{ z56qKi8k8kiK}DMgmnPn@Y3OB4+|b1$G4-$bp;}2no!0EYbuUM5fAjZ0HZE|V6V?Xk zSdTNn2(N8{-|;~${0Y9UusR=DqqeXIqt6dUSCA=RCM65v*V)P3X*y6S@kIf}`F3{- zeq}cAvSm|9@2R@o`NdU;c6_#&pN9=IihuMWN_&g(CoqM=*II>YIA*CA*TrQ|#fnN@ zyFzUtjTH*Z^2G{`)(zpY7A=n*%=9sdB5dhzmWT%sF)+U9Ttn||bxz4&XYcS{1jn`k z;Racp!&-V-sBQX$sMC%4M;Cn>_d)yuASAA(k^$VW(fDJx-s<6yIb+`}b$$rHu}<5z zG=a$3Ct~Pf-3Hkb(w+S6EzIqc6F0_%QRA2HQyB6N+`mIBmEa-}DUb|;aHiG;1wu3v zgaS=fRG^E&L%+(w9;^??7-K$q`{?VhpM3lO;v0Hn3a9}Btd!1 zT0Z`kSy{u!tl?wU@bPwv!dgDwWfa!%vC!}t5o|t6P&QfNO;&i5i*%Ef-DG7qze`cR zht>cgbE4K=a2d6MO{!H9_zAW1)qj2S^x4zh&1c^|+~0eOv7bBNJ^W$s+h-5=pMLYh zx8LkN`|jBf-xwjBj(2-!fBW$_PrrHi==<%Rhfnvu*?qYE%@0o>?mc<*_`A)=kN39~ zZ+O*UGl!*;>Lgf`Sp+g?fXZMzJvdJ_TOF3ArulXE5~qF z_rKU+A9)aPo%z+UOH2bxMVX4BeksD(4xEMEN>R-QpHd(+mj~Lkc@^p#Zzk;## zYPHz-w|{%~5`1kC0=)+@rhgqhq!iefI4yTwAMqC?x>#%O-Eg)QmiGRNl{jLF5YQOV zy76+_L7X+jR=5c0qdgcBFdyE=h>S+CD_DY2KyHuVxB@|)K{GTd!zJ?pKjNwk$cXJE zMpDiW0sAO9&ku$|@|%shiW5t580H^>sScekxSM(JP_jaSF-tKB_8!2a&pqgZoHOL&B!rtGEBqfw5Ty)dlke1*@o zYz30G{H!;61+JI@tDwZf(Jvz7<*QI;K3E$p=IF|xA-OWL3Bb4R?+9qdiN*mMhV-+= z_~QNKc)grv{JnV&TaV_-dFUd+MS%~C0LPdv6(Qh^Jiy;=~@)Sz51MHQ}5F_{_zY6cCQ*$o#<#59YhSUF%JhMs>2 z2bzlYG$7R8bsYt3>Qt^S#ceho9$oqa#d=j5P<1aRvp=Q4QrMvdmU7=vfu*2{N&^aP z?+RM_3XJycdj{U=R#&4>|Ev;pf%(b-)I8kgs;c-v+&pB)*IPiRO z8*m6hbp=FCbn7p)29>zP`cF#qDKw<8sKMT7VI`u-2rC76jq0}AW;_+2+$ zni`?W?33FkWlx_d)8CXTI_QZxDAa2%8G5u8id#^h!n|B85~64-6{2o06Jjw{$V!CB zYlT8Yi5hK1a&QiJIGDO%3vsDUMd2tD`PHUT7Mm4;BdujW7u}Y1a9VnAXfgY7>EBcW z1ZS2)(Kri+#`bFWaBoSws0uL5{d*(3Ps{(@$o9$qWDPA zBt8;1i=U3Kxr)%*7*nc| z7m2y-3e3JCg>k`FEml_?ZW>fdQ0vNBL!q0(+)x8cTz`hJ)Z^%S)}~Hx0GmC}EHQ)G z)QZhJQm$5H25h2JUZ3?MqhoTWaxgBCRs)NSfD`qq6FcXPm`$zLE;52mbQ)S@F3`dq zdo;DXMwu~kqF`g8F}JDL+NH+0iB?044Tliypr&$AXmP+8*v=wsqFZB$MP5@SF0ZIr zTfdB;i9+iX7PeMXv+ETW!X~;6D6FDN*D0(_p>+z&HPSz!v>fib#Z^}7I^~tCG_=65 z#KCBQn^WAhnOiviO!B~p@rp&`w-soFg1g|xK?2i zYNA_XS0rXrrS%GnFcXD_78VZh@-_ie!F9__gD09c7M;d06|wh2^#C%O$SLadM8A{0aei%@VTYBm<3 zVDBwLLEBb@f+5juXc4+W0i(xF6_o}NqLchRrAJG@wz8ARiDqjSAI~H90T5_@(J~*{_JXEDK%(!kk`yRCSBoHP}shD|i97N6!c6a-P9yw>y2z9Teqt-bC}z>mOe{& z1U@J=<9|Ls{s7m8pTP6>_-8z%8UL~n{XW*>KhMW`LFn^CMf6alk=n~ zXA5q!ozBN6A%?r9eR%N_@__^?>+%ZTcYQN|HTm34H}LP@<1tWZpYZb!{s~uRk1mi- zkkB`xtCdkE>w%Z?AmE07|EOq-@6VjYh#P>z z3&-$IGmfBeh#(%U$KQXb-@ikwaFR~HAv*(NG7G{%X(!bG`#YQ@biX%yGZC&?ICjte zT+F9eQ}9&4&aU&#t*2VNxgmh{s(_clgkuY+z?r+X<{I)HUO*}ehvT%)x(b4Qh{zFS zoT5QSVe^#7RVa=jfz~75S_!U$ z*qzRoMN_&>bQ!5nk?rZ!WqH{vNKo1bnqI_0{Pki3Ur2%T<}u)%s&MEiQo*F0Xr&KXYxHKkfO|b|uBf!A2TDS}vTx>pLJb{|C+l{|zqM9?#$)UuIF} zA6{N`GdN=dhmFs!(0z>pZe=@^Mr5Gg&BjI~H+$e=-MqV!do0X3BRsHNC%YR17rEtbQBki=fy_;rTdJ>z6ZR=_4Ep z#fM0S=Ff{xu_$XTrM$WE`T2YX?|EFFzyd6;6|bJddt>RRPZ$sK@002Lyn|af;G}*S zM|dvg5~_4it3sp>aFJV-{a~bI7BdFn@&Asm>V>M>2>+rDA-_Z6#&*=CYXP>VhTGCR zJbn)^QkFU@uk~o6sgxJ!P{1sz0Y&VNEx38Az|3P`h@uvBkQSGtLz`oZXn28gKAkUo zAr&+6+Igj8R6m*)hwh=!jrd8gQ3tleMtssQ8z!L6@NT#rcv1UoftR~I2QNAMl4b$>)5CX+|aedm(1P7<$UhyIt5$0Xwltwk*Tr&xzr2dMgx~hr4!_eq`*`# zSuMF)79%dPX7FF#Y*>C)D+S&*VKsk(1O_^LmVk1PdcOiE8(dl9E>>QBz^|{n(+&>w z9Cvt03Jz-n3>g!+oGBFNq8>J^Cbi|aQ!xCEweTHWgoXop(WVyo(6)jb6!F41QP&J( zfi^x1ujiHc`!jhvw?5WXT$Gjw*g6;W@$_6zd+g_;$Ba${C>rm%iMD*V78_Yg7 zP*Q3@5o}>NhkL{59NwUv%vODEK<1*gTpoBK^_GFav4KU468b9t={nAJ8atLz+Thp9 zeN?jA3!1Ww<3l=oiJBWYl2!T!k2nH;ov|#{6^1kz)~+$Mxz3bg3I!`8UOL58a-NL< zeXZM2$zMP`bTaadWSz{Z7GBF;mc1?2zWcIkX_@4A-SNGc@$$e|&1hv(XdL$H@aeG7 zS8QPvPcsSS7H5ZRPZL(X^mdI!Y6sLa3`3zF0d(Wp8i98XrUZZd1H2LgW(X?-v0-^V zlZg}D?Lt)lJYiOVD4=y)8O{)%*D^nDq@|&Vw6$HQoXvu0Z;20@HU&nFwF4{uuuO68 zhIsVX{ZMNyYx}0MFz83lcM$Z#7*%tphlB0;rbD+cS{>moH~BJwFgsq);l($%-Xbp- zEfnHPrm|jTu_!S1fe1=Xy{Ih=G6<2CpKqp(nW&5fQIlwA4O~G|_7Xi|o3)nN>e5_X zK%g>R8t;T&k(I4gBca1p3i@aD!YykB(z z9tqb=etEYLqnLLFM?dUEFw{fiTTioG-h&Z}0rSSe_bU8kW7?h4&Jje6;?tM0?QD%! z^9%m*&TUxp@0-Ygmk&XvDE9%%doc2Hw8gD^RID6`LEGJUzqhM5P4T^wF5RdOa{;-K zW2>mGsN;Hyt7({fE40X{<%3a>J|ugae`fwv24VI(JzaLI-|28;`0xjRz&0+@E29xu zB|s}!kKt!%H{tB$2tWPY`F0nMc=D2dP(Q^&c4ehY8SD|CsrbhqV6I>${6Fxkng^WY z#s4S|4}|X2)3U)3hg5VW?_8dOXV0q2SNprh~ z5uS%K8*4mw6=*OTDXEjbzDfngH4`Dl88ivGPQ{h70Tt%XxGhm{QF{+YLU^%&uwYBb zSsxODWN!M#W*2rYl##qcOQNQ)DhVO6n0=s$G6sN(@wM9?<+*eQjq$eF2E|28_ceO- z&_-96nlw8q^2`>(XCmLs=hHWni{i5V1#CJ^mK`*h6KG@6?ylG|64b9#B}7>nn27Oe zk6>a2L0h9}Ks88~2oC~dS)NbyU&NmaNrEy`;80MEA^q;>G4e2=VutRzySE|D)~0F4HlFJFO1g>wlCrz zUO0Sk0?U*c3_UZP+ANIf7eE4*CXaC{$v%PQOv9O)*o^C$g z+k3RT6B*rWTAuT(ulzJEp8%Uprv4*6>6O0bCGy}N^WxvJYvrZ0JD*{s_|{*b$wN1} zxSXNg_v`EfMzV1mF`mo<>bPF>e0U}s0>!*kuPF3_)hT>N*wJ_yYdt*3(H5Q1UqR^?Uo-=0(6cX(A=-EpOTrH(8{02G&G7jtcuFp)D5`NXdk^*; zYMD^e7tTDoDmKnM z{&oedsQ9Z%btbMfy|~1di`4}F0TrB2`T{!$pZMg|QVXX?et-CtR)|$RG z23d@ril$7a+%cE=yoUWVr41_!-ycb6tvjatOw-%UIB7i@<4fbcM7yN~`$Q>oQKtNQ$M zdA>7t%g6!GphTuB@;1cme(VrD+@?N2fa0yn@saWI4jCNh_)AmiN%G2AmpkiQ=9a)! z%>f+r!hq%z^m~0<@ zYG8JUpT|oOHaT(oGA^?N=k6S!Di53E#yf74Y#$x`bTXd$j)X)_<&A`I35_fyGpF37 zv6By%#r(w#;sM?;IL7%k8OBC&PXBR~m;+!XDx*nk<ABku zoWYt{h*`N-_E2Madhqz`rb?F!g^So{J}qj_h*9vc3~TydUj@O17h-d&siWZ~8C|i; zardTL+t}J;k^VUa>{Q^gl>+-)?6ey%ASwp_o3){#-N>N`Eb1ru_z$Bk+()+C!JYGV z;PL!&g%OkKsuDjYD@(4wYzZeNxX^Kr=9ZHc#ZaYit5qgmiryNbGD3I!NnvcY`6`p( zRPvE(q*ykJgKuPVHiMA`^W{$@g;vKOrapfP&fLOVqGj z2L!-kmZF+oK?p33>hwcD{x(G5bDsa&7~Uwt@<36l=22v53G*nX3muB&`mk#MAcXj@T&z&0W%`RyB^ZGkhswqcgJ}$^8+8pWN;XU z=iwNUh|!_{?l1kKTjNC{Zb`SssFAw5U^Vc?q&UZW@~>|uj^xqPr`yl=zxx5>NcJI) zE7dq-)?^U!^5YKcOF0d z;mPji!|m+A@&?cTY)M-Ce0s^alh z*X`HL7tP<&ScN;yOuZ5ImqQE+%c@A|+osL31GCv$*+IVc>>%~f>>$sO>^N72b6h05 z2sAd-YKVE8^2FpJQykYK2czzEd^rV|3hY>)j*q*qy*I_FI3Qyua1bs;$hPF=S#nw0&cUD-bdDEm7+=nS!U7_BfsXX0v6ors%rKpX=y z^2b^kA+DB;5OH%xh+{xTUeVTo+zH^uS?R;f+L9fn4xR=-*0zPiF!O+{{Q{xYFw(Mw zrd&C$mJB(*I z^rnN&M4tY%kTapa^KQ9-u)#fyS!0vDD6Ay0f|z=ZzQ)W0IviYW%;OEN6XfrvF+_3r z)qO3K2}6?4RC>+UNicMFOTu^O7gu;&tCC5J`Ivv!`E&H;Kg`0KI<0j zL{SM=$=aS2#pvBB>f=ClS{y5xgt!LgInwLf;9XHz)hr}+rxM|1ib^Mf!EnH1WMC8rdy}AMjCN zU;mk27%j_o#V9Hs3jVM6$Eci#(eWmoGFk#1{)xj^)43px0`+*5n3p$fnOgGx8Rn^_ z$DeMaYN5AlsA}oEx-QmhbzaW5x+dok&(!c>Apw`VW&m>_D|%hNL?KM)JXMWr2`|~Kc67X z=R6QV-i_Iuo<&=~ecLDA?BkIgHn z*|Xcs@wu2M5x#`8)z{Nc<9Dy$eK2A~%ufyh(JN48uDzOdnyS4<`v z+*gE9lt>x^QNq%eCMIhLoG0!vH_B!{evj?3p>D2|+Z#02h&7z~K-Hw}9uLd})&kbC>&jlrUi&uYS5wKdzZEko>y+tJ8euAomyL-4%ow)S4z$8#$0AT;SjT4p|7mzmwfZ!FB zu*3Sww4$-bvW6=WMz>3lL&NYyfK^t!#(TF-E{kM?mIz`uO_0R~Cv1aIGf5&DAZV;ZV%D);CO2(OFY zuJN)U#I+OnS1`nUxKqRuBzm820tRoHv1X``izpYU&2O%h7o;CsfqXnXjbasgC=o>W zsS@<+K$ghpwAEE$%EyNThXTQTfn6X`3-_g{Q}E+t_<9UgI#U-67nleYbe-E+%SHA) z)>|$pS2TMk<~=*l8kzz45)lIsTF&zH*Z_1DQN_e;KYMrGPLNfS)S_0~VYj)$PM|R9 zZvL==_rdO{M3Y<~)>w*vy}~b9J?vvD5!r991>S$j(T@#h9}idXpErjQ+r?8NwA;9< z$SxMH!16UEaLVNeR-aPSKthTz`mexmgA@MG*^&-m)#V8JU98_^3uGQaNN-`gdhjA; zl6g!|kSEVS!fW67cvGV9`Ybj&*`2A_j25iQqVNmp*B zbC7A`=`)N<;%R86c)ESEcp5TIyh&PopOiTX-!(Ba)-+6(WD>o0V&;`5k#>q=z?gk9 z;h(A)+`L|ZD_{7y$=5}Ocd-)uQyY-P2pcw2q!BA)2<@4#SQgrD9t&apI^S+GsJ}rT zA`7_$;)sAZd-G4nFpfJU{{$WAImnl-pt|wyx$V^9H*JBq5m(Fp8jxIIe}VR*U|EHDvO5N+iz%D4XO_kI9_J!4uk( zH)(D-uq0!6mS5~X+ccCE2jTagAw|I$!{9coEJo5W6^-{1|r;_*l(d~ zd6EDGRKh+rV>3?xJk~Gga2Tm#_X*lJU?uFEhHL>02v3Bc9w9oKz&o@rVH#SnxrMeo zHh-KyJj|0A6%Zw?iZ*O!MQa|rVvT~A&Cv3#b_+DK2|CU}mxz&T&lV{MnI@h9PYuZu zP4O>NGSOB^#R|hZM0i4>m7Z+jNdc&KAWXLWgSA8$SQ03_EPTjpw@s~!EDAOx(I~Ll zc2lJ@T7eCzTw~>O6-NMD*HwhT|2-#uiOI&RFAD~F_c9&r;)D9l;OFgmo!ArW? zZ=TS_J}9qyFYZ?G@}O`^s0c^OrA!~ZL_EKFf_OeCPdsgL>D*erbECgzxdghkJm-#u z(8VQyUl;p(VHV&ip$x~ttSiz>lp#7GSdfce^#T*$qvmUr{P&tw8+OPPcDKNJb zZ{667u~$l4{)r0nGr z^e-}W;!Pr3%ZxL;!gq{hKZ}I36Ubuts?uETz59XsCPyRoNP%PvvOnM=nPU7W>^~d~!b-YfF~e+d$Pr73pHg+3^}zrkh8l>4w7uzbtkOcpp+F z^qjy$9q@>W$#SU4FTkX$%8%lU`8U&oQ(hmD%)hxv-Y>pElG4TM7dXw=;-1$a2E5wo zd`7vOi!F{Ia9D&ou`WLV%k<$l@xi8FkGz;>8#S9bt=Ifg1w6q?Q~vFyu5CzDN0f^c z@pmIE!1yyP*koC&i3441njo;_y%}@yaCgWzV-&iGoS!z2yL;&i?7v8NQ=Oe%7kLP& ziVu>I$Rmu69v90Sovm^Ls-m1u^X>}dCHvo>*X&#s2p9i$dGYqD^kobp^m>5@DDN-l zx7l#Joj;|@TEaD~SXK&7y=Ifux(L`AGZe4Z!qT1KH^zp*J1*?D(G7T#F7k++5agBkuY5*Mz10Tpsr!~4ENYg4Lmpk}xso|b0(Fxkkc;6K z@uZ%g6V#QQ++LIZJ)_%XLwloP8_=T9s1yllHV-igQ3UEdn>F2gij6v9jmat7I(?|X zt!|Uw81Ce&fax769us8uWHD=6GAS}FZUU*6GruZ_mT(j*umJvb&&B`A9V*fj)tPcA6KtzXmT6dd8+6>jWEKLdK{;mzfJF z_~PMudm{d8ZGB?Y3gI=;e0R$?+c574MnC>zOg1e0Fx)VJlQZ51s@U-on=4v;VWK5% zh+N=eA|SE~A%mp|M1#+34~rEIUHD`Ejs8d-#|4z?NC5sb{}xd)z$z8Oz9r0P1$GKh zYCdu`-Y)Ow8+eFrnVC9o`m0d4hikoQ5Lxd{|4E%xN|sai&B96^gc**KFGlS*jirE9 zXU6Ns2P%9!Zcc~e!F1GUO`7dScQhF^`jg=ZKFtR0_P9Tuv^rGI4b~m=%FyX#eAezZ zPaEUT04wI6o;Ld9*|;(2pY?`)fIS_J3GiiK88Rw@+@lrvHs^nNnMZ~+;aIU--6&Y* zR{v^S(DVYg8qHBl+Zrn1W%$+?47L8|vj>2q_E%9b~A_WOnPT}B}=Uf5wUoz@`dB4GRNgPS&Eu%5`{tS5KfR_s+ znxBaOsw{M+HFWvK*Jd7-QT=Gp=t^S69W}jK>>&$Pz@+*>4s5xQ$E*Y;_!pi7j&D;` z$@YU;Dm0+w0=b2bpr@!h5{r@xP1Fijd~nb{xd3i*J5jdR4!>TR3m-f8bhUZN+DryB zN_3R^Oojvw1z}E3#DDWMOMK1hEYb3#LBp6?<7~N|w`I1PKVZ&HnncJP0+uWCy$;(Y6EUDfCSq?)W5?DQxnjn~0P_uvm?xtrObk#I z#W#MU0IrGR2i6p^kjhDd=oo`#_4x39y;$vcMayzRg09Auwl+fs+~o#tM9i1UP9#Mr zJZMITdk_hkP97w`%c0EEGeq>D86tWR2_kxsd=W*_9PO)F?9BfcZ_8oyS#G$4Mq7aBLM#Re5!w(`~!)-QK2j_}zd9{aP6h0rtt79<^iU+c+ zT`?L`crgpIAcu{C>^>?5jIJ8Qsgb}u-j5r^$S}gVuJ?GyKXD^TfaQXV6`YzE znERwb?jQ`={MdLz=PkwzWjzu{u~oQ`k%WOM^bZx2ROzsH8!VrM`+9-g{gyXI!x*Wb zV!8=K(l8b09wD}(DhlJ|D@a!S0e#31EEP~wnXVR*ST=M8l;6c1 z=i5C_?6LU3lT9@(mrFEsWs-EFVhAX{2x4?7*`Eq5dCD^4;HzTDW4w?dr%<0!xEi(i zgM7=okPp6U)CT`T{A)->qKT?yKBZQ0ql0ZCad5GOd%4qZP=0l{gXJN4V;VxjFc={) zXN>VSt06Re&CcMyy}YYIOEOEn1jZ1PnkIO{1i}{sPJYz_AS>FY%o7)uA(0E9MV8|CMNu;i5fE*K60%@{u}fUY>nx(VdMqKL&saP>%eg~4PEIoxcrIpkPh zi;fL^ohG$Gmm<1>((=R5rhYKL#=1MuJVhbUT}w!Pm*rG(j5}Yjl;A;>j&P^FCAjl_ zOk}5Fim+N&CI{;J>4)0rY0s+@6NFFcaGS1{9LdMT4N}dE9od6i?$?{?x9s{6H-2h$ zeGjAmp@mxn`^P9Bc0;5uQIPz_VF|EE@2!aUQ3^G-?X(B*ihn<+fPQ$#y ziv_;8$yWQt?P3l$N)n@MHYjN}(zAARJ)p>miOFUIrido=Og?eDz(F@Y8_R&WIG^LB z2N^o2t6Xv`C{8DA_co@cV%AV;*A_^d$IVub?Mk=I^r^te} zoqb}f(P0nONLb5NhzST6tIZ=;ykFd?Qd3f8=9`Pv?V6>u05%>A?;iJu`IGGlNmjg)h%^t8Cc#S}Nyy&tQ75I5h;bpSu^i9>5<+{RmFwtoz1<68 zZ2y&IWi%uai7YI-ZG}LrhD{i1Ak=Vo4RHfe+?(bqTPzLB6iv5JnL##>e9pN>u3-+l zjI*L!Wp2d0M+@j@uhC}cAhl{7DzVxix}mz8@D>WR$oqo&mpr5Tr(6zvs@rDDwrHG4 zPNk~SLIK{E4F82kD;BC5(t|t>9><>1etk5*{sLPXof)0zSSe}_9j1nt>s@N#rm)tG zrvD24LviacQ4kFm*Df}@Six=5y&!3i4%)Au*YJ|B_&JxjoMbM1S^}k=w_Gw35Pkxa zdY?&N55!U!WeG3RN(c^UY>w8CtDDgpZgNt})Oqb{z0A~s0o8z!kkY)H&(746m)As< zco8nOZ-bi^&isys>hfu~&mLa=GKV|LkiPoL{EBzeBImu1BqT%Ka1I?L3@LJ4uNkyQ zQ;r^z5y^KL2RCB*1W6jJJFG*XXLyZT`too}a6s(}x$Zo7{Uauf&^Eg;R`I+6 z#1TyLG+@k<@RF4Ygr!nB%_{3$SV6NX&|$Ok+74K_<1o_utP+!0stvB)3G>VsS{gnn zw1GE*9gyiTDL$+E#!Ki<&v|HZI>!=LA~mqOr9gFuDBEk6sD}k~5)6bGn`)Rne?Az) zqwt~!RLYH8CeE{ z1nRYo##^FN0Z*0S!k&qC3phdT0(=}UiZ8IpHB{eA(Ni6kP*e9RQC;>;8JG-of2M>{ z!Q;hBC@S2ex+2DT4UXGY_}vV|sn@>MYk2k)+jrQoxK%kRUh&Es*y40R0Uhd)T{S~Sn^lSmx;am2ydcAL)thx@x@dx zFi2mcPv53We1U5e4o>K|#Z7j($0zBkaqLiVaF>i{uzg;^L5R*Cvf!XXSIWjMxYYO6 zZbp5`Y+xF|;kbcnD^%p#Wpk+{wF@FROT@Oy13!Dohk(e5KvF{U!ntH8&bkxrMgT)x z>5wib4vKcFo}b*lWjF6u%cpm@SN98NMC)C@u7L zY~~pI%W@smYr9+8R!iORYAtIe!AsS6J!s(KC-i|lZ`e*>W_J&eqKH?8ln#n) z11}=z*;C` z^qKNsK0Q3d6?~{sfy3m$Iw@!Vnc9ImxsWezbA7m}Vq-nPEGcC5nJR!AaZ5NY5zZNe zM=Yyh21fdvF2-6iUx#;h+w2aO%qTf( z;Nzy2n@mI=~Ap<8*pp7z5-q@N)bVB4!>Be8_-f z^e5Cl4yeDkvU1$(Cv+03Kr(pF{c#1Jh;qx)=d7Xb(8aRcE)A{UqL7PfezAJLoP)z8 zH+c?HVAHuG!*a-L;_%Jq#+I0dlIf$!=+W{LpALt~VqY#EHp|8B(`&f#xjQL5@_+u; zsen+@WSlL&{k%~N0T!#*H=J}R0me^~Hf@X&TgfoNW3}PUjUZ@;e96e;08ZFtIp_pZ z9({T6DTgS=dqHd+n}y5`NMVJN_M#DfK8H5~vTJeck^Qnr4KeQTseLuMB%3lIEttaB z3KS>sWET=Bkrx6|A|jGWmG2-OPVH#i1G94-IH?{kGEpJ%hKd~-N*z}vY};WT8Q77p zw#1iuA8A_+K&=unfM_HhLLGBU;>&lp#pzM;}08sh-)khFD5MBpsqZTDo9Lm%|s1NVA2}D*rh1HEdc)T+wj}IH$ZikQR4in%Nw1iAV#gE>G zT@m!|@X?alcKz^DygD?aJcFBbo!vZcv)a|eAG+l$k>@Gu^4)-sgmomK1d-{$oYz^< zJ{IHkwrAq-74G2`?NWoALZ-_`F)ld}Ag;KFL}`fJ!gda0h+&Y`i+U2L9grQ4P2)!PR6CJ z)b4)sR=iUv`Zm>i783%F1?CdlsJEYR(c9iET5c}vnALt#T`Lx)zsL(lj*VxiH-V91 zsnK~PQR6v6CG5Xh!->o{`3A9x#=~hUK1xhqq$<@$3X73MR>BBAYy#W&>ZNJ(2x#&Z z*h4kGAUY#vov{cxOPFgJvw5U@TI;$0nU<*z*`0oXU71t@sOH+UCE4^#Ja5 zRlNY^L6?j!%t|z*B7@6s7#mx#zfis&-k+p{#{_qm>6gmIHR|==S_x~|@K&eMohK6^ zH?*p~DN;+^5x#{qy<6~6Gg1$E#|9>)dB+MTR40~$M^g%!mR*nH8x-VP`fgJ)c&=0 zB8=I1Ip6Ir;JR+D_SgR$PtT^kes9p|&Ca@w?sPC|3}(%q)1Slik-X>XXbbjCCDtuJ|0(@t=ai@@W2AOad7G|2dw3I@a?~ub%PrlPF)O zQ?j9F62ht)j7&~$qb;z%g@kWdv#qQUJ#LNJ^~cC7f{No7b~$$o)eNi%0S!tN0&@?G ze(84VUbmGtXwN|ZQ5_9ddaYY1NhDIA1j10@U?tp95NJLcG`f^}fpCRnX=jF2X^4ZE zxH-a1v0-4G;OKDo%P4fhKtu!|HI`DD!!)U=hawym)}_Z2_2{o$iE%{l-@N!^I)b|U zk`#0zU9x7)NEfJivUHF6*p(a+-}WjePvy9?`a-uY z*vbghV?exJiwAhc{AXb%AnM=nqVYOg-Ql@dLXj^C5=RR!cq|}lnr)LXYp6K#p?D1= zfnx-SqrBKvOUf5eanyhNEwtRo%mHg(h{tt$TbR1r|J!fYS|smOY3m&BcVWeMutC25 z^6O%kh1UiOyRpWbhcU2DggL=+isK|<^_3uTwNF64BzCBV^evu zNf8nI;55ReyoxTlJOC$QbP@WBb+i!y^3p;JtG2qyz*3XLnmR&6O&4K_3>C;60kXmw zk1(htDl}qA_Bn(sLR%k?T&?9LNf5i@(F;|Z~(Md!qHL<9E(4e`_wnnSKd zyNSpzhULWy(>&j=mrvyQVsfAODU}N!-)0{nE|Y|)oQ<%5Kv%9AvDBbcrihNfY*JPt zoKXOndI*yxh&7;|;FM`hf_Q|ayj2pq2lMZbm^kX)g#j*=@>+DIc@i5m^l zwtD@e&(=jfez>8bzer1c`}txO95tx}1A?IvS6Szbx9i;waxDXz zNT#V!m63#j^E<9vhoGr(l@Xo(@5lM_AYv*^WdwzPgqL>@Le#=mMp)kF*c^nc##Ki2 zYW;Y9f0$uJsLDuU9>#*6QxJ{GaHI}gg{h37C~!63>f2~6|B`^B)BbDr?We~j#t#J# zEW|Lw6<9Iq4;dU`?J}`+?cQx~vTb-bljMiQkVfn+oNwqsjMth121j~qG87F_@aolu zd|E=QxIBs*k`X3hKW%P>^11;bihDraG&;fPzySm!bmfvjf&5QJkqawoQ8{9f!(Ubj z=9RohbhREWRxpW#Mn1#SE4yc>@_L93(nv>NJm94$bXXNT2I@HjFM?Jx6F6ZI$sQ+| zS>WCw02qC8>7ScOn6g^}ui$oonEt`M3G`m3XssRH)4%@PmF@Q%VdU_|SaR+- zi#iivi)WQlGc+Sha*(}-iEV+P!l^77Y2}qRcIbAt zX+gn$PFPv6{3_hpM;~o>A~8kCqa}C~-hjWM4MpmT?Bj%M<|Q2bJQ zgY3X%b_qcW3>WA((JA@4@ZanC=5qgpS%Uj7lK6POIj`X!!~6dKgRkIf#A3hAUN7Ju zYj7mYk3s=O%{CGYvJ8zpkZG@&tS2Rmfy`PAxaOc4*F!O|nAi!aBp?)i^RirxG0vG_ z8$mv!H9%3k)RLXRGrv$@?Qe#r{NgwB1r$QXZc-KKA}qKV>otX`UK1F!^m$u&3D*aq zm=8vLmT-qqS;LL`Q=35%JUxIv=942rd0#W2HgV@5q6GDOQH)qP0PT}U$W;SpdH)5j z;O}?uZr{L}0bGYjGx;{Ih<1eo4>Cfkx^ya}6A$+QwsN@u1&bffb)q5lHdH-XZy(@V z%|Gnfja*6q?dU{&gB*E7*km@sB-DhoD7o}Qb!=<$9Q8RaIb4Ph8GrOM9Tk8~DAdrh zvr5Qu@*OqCB7PVdk1-aV@u(WUI!xYUvojlvI+IbO*Et(Cx~GuCIGUXe8|_(Z(46(# ztyyzI>5I^%Chu{0+8eanr-Mebb2@Ew`vB9Q^aqX8=3p}EO(xA*uST5UtrpAL{ytklo+kZlQGj2)3{Km2lMp`!b0D=A2=AXh3zGDq&I^a{{(wSVkZ}w) zXanJf6&^ikWvuRD=d;glYEEly`fk9L-#%XN*IT?HN0_T+LJ~Ce)2DCnlC(DNnj2#^ zb8ZC!&l#2tz>+^AH1&-eG3}uuP7EA-RIH2jd9fj|L?&L~_%Yz-+d2 z8!DkRvwJJtLx%TmqPg6;Dae9-n@xtZYb)V{v1cn{&C#%A>oB{u@wC?&PTGUU_;d=p zwSMokF=}-?jcIc@hHcoSHye#<)8*{e&bn}!tqvsa~Uv4xGJ#CEh%)@HMlaS6^1^Kfo2y{xj@h#6IX>!&?}H!#xsMF?r!n z)*=x59{5`PjMp7i*B9^99Il*wn)t=GVClOwiTs#*G)V!p;7{0m2^-sBd*ZRDPf1wp{k?=eIF1n)!^*YycOHAkyd7ow=zH9bGSuBG zM_^y*o)W7|TTC?I@`2Kn{<{UZa)ruFyj8`lE3<(tWYDIJD)hfsWuhu5R@oG!>V0g7ftT{$qvUM1* zc5pVGjrz@5qtom38{N@l+!(aleQkMuc2t%METYQWwt2#X-(FR2Q>7>7XI{y8e=hZpIXr4VHDek{|TdB1mt6 zFMp9Q1yj*f+F4%DcNw0817vM|D<(*z^+Rp?ZLvSE)&Bc`uT3s4-(O5V{rvXd-oE?w zt!MzhL!S?KyT#oqyE&P?TgiG{n7Q)b=zL9u6rCTj9@TAK;7~u?|Hw?7kInz6{U@CN z?e^Afoc}5VYE=PhCjrr}`~+2rrVi7TLAM_}|MA~m{UX-&Y-_D-B*lg3=Km7b2j@9_ zZ*=}&f!lR*Sisc#1Z6Wmtp7-_wShonRP11ygIUyAOUEt2;@Cx-P=$R=rSNLIMI1EI z@}u~#xWpE`ZER!;J>3fQRPJaEl#;7UVY0W4Ig2o)DOgNF7L7t&!X6ejgk&qhubnzZ zGciKf290a}m^&|{>F=@gGStU6%R4BzC+>5b4Fs#5DdfqN6XLqEx zl(vUaeRF3tc*xD2k>n_wJHs@b$G~>%G5A~=*pEHFGxhI;o_)eWfozVZ2tj9z4%VXPsB%e-*_l3Bbzo4f|UDsLGiQSa%>_B zc-;yg-;#1f*o6@+el_wPW=2JLsMm;S`S?LJvU*IZB+nh*#iV#_%1#5bCT~m!;tEOD z64@~*$y!EC0RreygtIV{qpM>Q+JuY4A#t2#HcF``tB9@%frzsspb}voy#DPTF;Of; z&AsP#Y5?zOevLtY8C(xoR8wGI%%&5l4!?XF-^2B-4B}$C4-d5RU|D%bZkrr$;K})c z1CK_D?%yhXnMW7X7QCf#sIC&IN_q!^tGf&?T5mImGwV_e<_ml6m8M!mrSgf8shaT# z8!MIxfAe}BxNc7U|520G6$hz75O!3zv#O3EWDJ1QK2YZx_8c)4Gs#_z_6iCr$Q4-*Xg|Dih^G_9orCZ5Y@+m|aFeMzbU**R z6h#TdFXZdp;tmwfy{t%xS{B4FP{hFek~$#;aY+{5zYv7fzwL;TK`467@cBF!%}3ei zx9Yu|tM!L$4O=x^TG9~mqqd#)&sCJsJ_&0BwIa9T#7Mnnk&P$|*IuFK-+{|qbSq_R zo5!Td299UNQ!>jXl8!y><~A$zSEzW1tzT9gP?rcHXDGlbWNi|DH4`9zNH~nv$Trk+ zNm@3%gw%@3yIxn@C(#{pctwWq)!G$SuMge_8mBNzvCN4BB<$;U{f8Sr72o1;09VTS zC3VD-EY6s{TB|9H+<@6tH0q*K0#S@82({BWm_<6;>@Iv+NSLwLiyhn%dw)5<&1BjE zbW6%ylS**(+9JzXVhdC=t#zT*5M8wIkKL+I}wyD8os|Dn2_eR$H=U+8%ev7 z%h#LXiemEh#GeMEIdu-_>xt$vt3g3B$Z+!YO88*p>lLx)=u$L#b(nm;aeI8$nl=ZG z&IE6vOnc+T=(Ia*Oip{P&Y<5L&1O1#4tCiXh@JBKSL;ZFPlGn$S)OsX5Iid8E> zA_qV%H6g=9w#5M|1xO0v+&S@^;r~ycJ12E<_}n?wi|pJv+XvD8^C`EP(F4oa#hj;u zKtV@J;>Dy6Y@$|gnM2O=p%5&VN^Teje0Wcq;(Z*p1xN|sqK!&>SGeuT=I5S><~)Y= z8}?~TYp@c=bvr)u8iXgn9-25(MtaDFF6k<_u`|In)mYED@VqWOWUiJ}+R-lJm_GSs zv0FeGCDGqkP$iw9TB#XB8;Y3P6$DS;!{uU*(f_n(2n19KB^h9zrYPAVaflLFi73=8VUQ9?Is0^#OiVYH zk#nw+YbjRc28%G)?_elbSM2*V|dmX!wb8ouv;8=#@(UbCOZ4e_M|)L^=EB( zhIcY(bZ70;Mt?Nz!S1v*8k`Qs|Gqg=-&{w2k1cSH z33q!5iazvC*rE8cmzNyUXcP~*FLsb0ZF}rcK@lL+2+XZJKUntG0;DNf?9re+7C=IP z%&-^RlsICI9v90SwS5ym~3M0>M2awO##C|kw?~; z69jg*?7<{%MkGq?+@{EdSbp9wmOB&P5r2kQ565*xa~T;?kkURx$#6nAC44YqH$|*D zE23z0s4z``(C?p}%^H*O0A2u?jb@F}U~mSNbWY)$v(Z_5I-qEa6Q=3(nxpBs(`lTY zH9Js!X8>h;dgEaO5&)*dc6&T)jdZ=AmkrZM^}KL=Msb(7paTGrva#5tds_z`{&c^Y<0K4x7}7+1JdFF63<7mdIUGAhU9y2 zo*puAp`K4wqhb*rLP5~y(?l#Ra>v|-8*P4%?YE(R^nJG^^|BjoBiV4dG~ofNZMK9*r?Q)Ot0fe7CFc#dOKB&)F5-_a;>e^|`&WGQ>rP*1 zy1d_zr6ErfZ>xy5@Pqg_bw}qB0ur#*B&0!?TWJlpX6i1fvJXFQ;f*`FuYxN|H{$Y+ zb6E+mcjmt>s_!Lsc7^+F>JhUjM&jDIjU--yOL)3mu_tbv3YKE7whLnSpML!(Nd1``rvAKx!3_8JIv+)`qi<@sn|2hw6W9Zo0vAh<|@}ZGvzvylEVWbVR zEO^}2YaWB;J%x|d)5KZBj8UIqQ?(VfXlU+SK7Rfkg6ZmK(n>tiAmz0v5E#t6g!dLL z1Se~laV{$mPB0=wdK$;|n{0cRo!}?vSNocnji=J4|BZwpmXeXr{+Gu zxI-M6$o4}GY0+P#%D{$~A7SytsMj2(>yptr(A8wi$AB0-Qa4f&ax_sVVVvgo@;N1`KnIc=CP3P*p!P_Q_q5l?)f=)fVcQ!X$n@oIhX0E?Km#|vYS z6{nZ*qCM6-5}gAkV!f5$a0Y#-j|Dxp4JQ7OSCB}O=87higZ)-4-dHB4L;MygC@JHj zVPBT?q8KZjAerm}!>1I}Wr`~;!iEHevq)Tb%uJ-e4mK07)`GTV-Xd4dxsY7FqVjje zyw-+0^Q6j=2KCaxdcoyF(?|OuMqS}Wa=FZ3EmledYplVSz$g4yUta}334h0ah-qGv zXU!3hHv9>`7$y=kbuT!Q-6s{SxO8<7@psKuE&^Y=>Qm3DxV-8<6{Oc;aC5*?ijdfW z!|l%)^w;ZA?NU58tUSg`cxV+onmw+w*pn=UYB|-QR{E&dh$w1I>Oib7`DlJA`(`nK zPlQ&=0?WFQAhL|#j~4rf`Q~ckU=a0YY5(zE$kZb%jlEwdbM9aQut@H`^V+> zI;=>kZD=vs?Sm~!^?7qEb{=2nOEZmcZsmr@d~>nuOzhcOj`s6%_FCNR3^}R+??PJw z*5a!MFDc4ZQN89Wq+T;Z;%6ybYUiN}09wmcZl}d1?#B7_ip1nlofW922jY3?TR`7hLRegd@I#?5WM;9`A+0X3*TECJzO?IrXz` z!c(nem>vXGH1>!+gD}i?jk|8WG^;rfK1khx&BJt!iyyP~dkKiy8JupCy#(c>?lM>q zTm-nFY6e)#X@GA$pOyU8Ym!VvZn4)=)n~DP@OAq)^Nsi#xOw+_`f2>`^}7!&W_)BZ zx)4afwHu#eq?m}*%mRlB{&Wk=x;-9fv}_>uNP1#vTuqFvs8bZi{3Xja>cLsFcBBqK z4379RInsc&2i~cC4RKPhS=7^1MwL@E6&z6LgesBKRrMWp)jrW;JWo-m0jQ(4heX-M z^)7FB@pn&A-Yn~0%lLINwoy*kGo7hsw|%@ zeUt6)*T6gBN*$ran!#VdY=G&o1*-dEq&^&9_{D z%Q}Lx;NYFhn$)$o>o@ZqykJRc*3)SR4+QVN&|2v75bITG*+2qVT4(F+!yGKXbznoY zRq!vI1!;=yCM@*t7g*d~jJQ08Lia$6$#D*>esOyw@5+*5;WR@iG-2=nYFpC+x7Hm| z(wa&`>?x_-k@;~le0{OHT{FC5)ssaoZE+_ScTU>5p5`^^#j>4NL?hBbe}Pj+$r~cH zyx`CPE)u)M;uXuTj{xZAN$fDqX4zvl(Pc;JpkSd1}I6B{RG^qBByh5mOQl@cPLSx?+ez=B^(=2@+V zMNCz+TjsB)x}C+$(he0_t4ku02_qBlpvbhi00-Lz$a=ViqTv_dyY0V-;2{19>|J0y zdcMED=j~g?>(U{-5oTcLf0OMN*SZTJdrSqNRJeQKSPYOIa8hgnK**zPK$( z4fY6HLv_fsP)|F-NA+M9d{Qz+hRk@qd9o0Z=XNQ=buX$chM!LPiq#q~mc!A_Z|Eie;<_MrPOh!g^t-=5@Gn0w-8-xRx^7nPDM z+9D?iT!2O0=0#`Il(`0!Ba0PD--$daWe%>_598&02R@EA{@8hGu1pZS#2e|XD~ME@ zC@`Gq+CkwH^9!z0Zd>5cjR3ROD;GyGy$H*2r&bmKS8KtoIzt8Z<>T|FDvhg9cLL}C zk`C5d#NWe{uhck86n8iCr3~ZK$hG>_wj6ZA$}r6mv%jU1_04G**y1Kzf+7t=jduMW z00h_^?W9^yUojYJvCOEDPSu2m%4U)A@F5d-pcc1J4Cml8xCJ5uOoz-$`%#$@a~5N( z_Pq9b{Rem(>&F#l3)%y)9P!T^$e#>>QdVy=M$VWEkDk;qlG8fP64*(Sj_m_1NIEr& zN*yaTOH(Gn7SMFuQ+!q!EQ9r_=?-tGEb zu&Tlt0TwDa*8-(M7GYwx`1bQgP$ExbCv$g+fm<-EkT?=PBZ!V|Ilx@&U~BihhT$o3 z!T?{ZKv}BFZT=PKxdQ;tK542EwTvEbZ(&Y8>8+6zCa4=~qkF2hy3Fn#prQb-f8rKIQ(i=xE%n? z580W>jGw;0{1Ia~V-c1TFCCe$ZZK(19IXM5x!@Eh>|tDcf7hCU=9EF*78JLJ0|NdN(E3=oB3=KHlH&`P~;SRNC*^6C@)V2nXv)+ zH=1F54$tA2v&7=^MC+Wj{^J4p5)S?$+Cd98bd|hD$l4zVMKH{RCN#Ts%>XR4ny^++ zt}w(eknFMEngSH^?+{nv3KX)vEI~oA1vMxfQk)_bgfD+sDtTd4p(ti=vt3_jH*lIz zyL$LTv38jEC?@T8Z`>WV8c=lt>V@_OlSY3$8aMjW&SchxCnNvL7spVvUbZ@h zCEy{;V_32rtUgA_B)lbu%@`iuA}XNZQqR}WCSvEG+tftc)Y9NQcP z@+y3O86K{OD=LCB<~+ayRbiWsr=!z;x7C>SyHJH~GDGKg&}($s?N)Ex8;tv{KKZb) zD>IL=wZ`4f=(IP1vid!Ek!^6=X$)GOexuVG&ZhnDS#vf!CBT<;etku0U+`t><$L7O zc@-01&i-hZDo!20*h6Rg9O(|ShwP}e^L<)jm)UD&Ou?VtclIPdLJ@tRf_9n7e6i~2 z`&ghKKfyij5#+3Wv5!aysj-RqwUEHbM%xQjhz?dD7PX!C*=h%ch?CYtADD1OxVE)Sh~m|1Z=TGz--Y&z|RnW_>aZIBR?S|i{R7ZWK^-d_(8(ZCqS$ovv5BgOqSN?Bp%m6*z+UYBswQm>V#pm@Z@W8lW# z=DZm7JHwxcvN!NN>P>bFCssEnkUHh%U;hN_z57+^!Mo0=0K_}Iz;6gxTkV)u!c0NM zeqyGMI03iTR*A*4#+Qy>81+S#E10qtEZJAaI2`Uz-mk$Qgfs^_`K5zEF-9s3N(*Hj z#y0r2Eb%WP8ZFKWlMn1QBuj2^-HDPq3xx|3Fm!CPu}-()B_vC{5AfgwCOTt2oTB^i z$1=O4{5YFD^}q_2Sv;J#e@i{-cIY}3@sw2JX9@5t9u{1!Q~1AwsFlw@ugpWuBu&z= zOcmVb*OQz0vQjg(3ZipnxY;b9gmHkXTUgrV#Qx)ln*CR748`#z@bcq!euLXOc&js8 zLOQG`gkd3aGCgx8d4Z7KWVDJZ}W6sjHd+oR@m)NC|QM?H8j10E_J4qNa%>3GuV%qG*` zX|E_$+nbJOr;|prI~z8-@BnH9-q&a~+U?2dY&JSQosA~nIaDk4^t~drYMd|vwGN-* zIIU=68?I-BX(hR1<}dk$naTgp6QfoA4u0W2JLEg3p8B5|p_N?XP8gke zu|lQBbTlBD<(OT=J+THz3Fl}aRxrni1zV^}QV|?iC~BV~6Tu{kgsSlNfQ-nLhT=-3 z0oV~;4Us4i=pkJm0^*88?b*^0K%y{Wv?;gQ^^}bjjO=i2aIR=Jj1tfO%3fLgD5>2p zQBcQ`_PlVGs15?ItPYS8*7+_btx2UGy#`BGgbtPVIP;lJYsG2){WGKcu zNkJy|&M%AI;p;m+n+)idb2;q8u)<})9|Jk8q2&N z0VM;;5%iorZUulfa3f3D!n1Fw;#Xa8tO zvflQ>XHobC4jUKO6$lVu4F55GKa$~lIDABVe6z#@8mLWXAHkTZ6Wgz7(3k>Umkwj$ z@C3={`86c}Gq$cSG||beH81NslI{-aFd|Nr;wWAsF&sRJ<8%W7QU`=);>GUmgr@8X zeDIFm&AA1u<85po30v@~M-Mt*P&;CGKUsVQFBvi} z%qA7kZj(tHezl?0<4L0e6dvxblGJeIMAE`XDM;NFfL|`gm#?g2F6UqA zbXs-g$~%9i)4S)&FDO|w$~b%W`}6*+l;s^xu)-cq%%2u37-1B_sC_fz$E3?*l_z{j zNRF)3UROkIg7w$9mBLc~Y_$X~PYwHfsDDb|7mhBS zYh?p=G$3b~<@tn)v&5SD2xU|0+m0S@{@j?1W_6asK9J7 zm%q+BgTd(R6iOYmCWA(I*oMnrXPsH2)$DY-oz`U1Yz_$UWiNk)l=Z@qnE(s1OJITK z6iady#yDDiN$`ZiD^M5iD|(lh-pDp6;r%axS4OW)it=Y z@-0y_G0obZb7YaW4V)~l4Xk9A)Ie1PRDLQZ8)IEISr5Vbk~M&x_JIv=$T*-yvfz}!0S;ng*g{Z6 zcpMr(;X4$U`zMT`LBaLO#rx&s&V0#|-^G*E<1VPyLXMA^7F--v6oEtNa=(C7c%g;K zd?!`HlHLMN65WE+a%;*lc`d*y!irs?7?PqA;d-%>&x(pfc202EAV`wefN62fS4cc2 zvuRmHWE>&(B9XK_`M^m+`@l-{^5w|~tRglJ6iCs)o6?EPv4BbvRMTQhs3EF|CdUJm zVN4QDLnVo(q1d8nh$^CC&yViRaE177(y2ubK1tXdv=W+Fh)vQQY<2M~IUSO|0IeXi zfK$@4J*&~30IMSC`^EJhDpo?okpEPPf=QB2!8nOql4Pte6;u_$s_l0aRFY^4CSiyw zh$>>?=%V{y^qJ)#n8pddApt4b_V})=ARp^AYExA_N}44x?Z4TgxoRje2vz5C^KVsFzS59?IN4+K0b< z*Ioms%WDWLiPbq;tZRkH2Jm@8f50xT;uM0y1Z+i_1+0>}+`Bg-3%DvG+x6N*ED zWjtK_9tp-pyin40#a*Gw^{%u#bYa!d<^(c4o~v{_p`fjV%+|ucSQFX?Pa5SmppqC5 z6)+bKiN_|i4f-6B#cm>XGeN`!a3zTaq!O96rEo|-N8n2lhg6>)3#zgT_lv`_FnEjVZCvKfd? zYYV=L&{y+2C%2xnjRcsa-i7u`v~9LeC|m|`D3Sysik!3zD0642B{9J60uxzQ4vGtU zqNSx5GR;8B`8+OYHL)j8ko&&47E^cumkuCLgO)=>IkJb!!6ylygHDn^2VG4CaD6~o zFtH0t+EaM2Ny2-uTJ-XWkOx^&Y=~cP12YTp-56e2tmTy6#_?PV3h>ogJbe$aC@j?Dw+*SBw6Op222py2CFP8Io_}5 zpR=XF$acQ1)(PvhhEkI5zqq7hYqW-~BCgnof5>i^@EV#3Z^QeNxT!Z^u_gE5k~-Ui z)mrerFWZH9%~KVEDN$l8dU8J*!_|lP^6k&oIo^6vSrB;LhCa%xZz>%|zRO*F2~Xeo zP#TOWV8NS#3K*}?=5|$3PxSiBaJjjk|4K?Rr^`wek)>p2a6CRbV8cL*EF|q%j4c>e%-B;$ z8!?Xv@}u*}>NSBuFCHA0)J9s2?@N)&ak3NtVD@YN#}c0M01BJtscb>hrQN~8r@i8? zA!#`)6(6qbyhLI6Q0QOV$zMitwv#VY;D(Wlp(i7EF21zOBnFZcie{v?Bu6lnJoQzx zlr^=+YMncNpY4HY2~AUe{}>Bnp!G81*a!UfnI0`#OSg9pY%gsOy~JXcnF7b%JZ?t| zuamnn^1D``4GfM@mnUL9+6d7;=aGkr)(ttbTB541ld!YAaq_HfZS6RA;5%$>-7Y@H z<`$pzP@D5mx8}+Zh?vmM6hx4Jhqkie8VItztPw!4awi=p#VKw;`0^PT?0N>p>^aVg zZ1(D6wb+AK^EKN}=KJ~iU&N>dJ25t2{!qIzf7Jf9b|TEkcsbwgE+#*~9Q*5kj;F)k zsM8xXX6@-19-D2SHAa*ExG`(adc$tB2k#q%3l$8{I>TA#3`#~0d+_wZDHJytb^Ei% zYi^=xkuG0O1p@h#?LMa$9Z=|xSwT{f2$vR+Kbpz- zr>`cUv>~VWA)hXwo~%?&()7`%V`fiTWWGnjlttdHdI-4%hpw5ZXyK(}mzJARKxFM% z?BAPr;bY->OTa@`PPAk>O7TRCZ5i92FU@;$GM8!rskiitrf~)7Jo&qn=idOVHOL%JRy*(Rp2ylQ>bB{Jv=~LC=9X4V*Aasg4 zbHG-(J0U=*W9_Y8x-G6I_9@QNz$SbYPZ!hlc>eU zq7BHNiy~n|3YjVs-Vl(Gr6QT8X%ZPYwm_r#ZgHKShGM|VgfT6(Eaho728b<)mzi_$ zTp~5H(I|SP66EqA`NFyRH)+DTux0)A#%-P=oD0boE|*M}IJ0u_Wg_MPw2&OTk%MLn zI{dm`+`wVylIjE#IhFAY0&eDE>> z{q{*B`oL@ClqKz?tWrCTONg^3AwlEcw|7GTBnHUOrk_-xlEx^0m+g-L# zyEUm`%Gg)UH2dW)hk{6CKJ6Z)q!GRWY55nbSu*qDsv~PlDe_n!;9+MxcNdiPH!Ndj zwGJd@TB7KNS{R>R%#>+pcCX-x<2!h%c}3L)fE;`!II_NH3F+Y~8**NATi^f(F|j>N zY~krLA1>^BZP0mzX^G}O{)LNPO~ z@u!QDUfzdfX|siCSCpomBo5^TQqfjiyXIT_TXtW$KykkUb#J%VvdZ<|<)Ew+ZA3}J zo4SBlWjSTDi~QTroL;rtYk8TgmJOREA{Z02l-2ecD5Z;lBc}_YCFQPaE;w6Q$Va(> z_ps&eC~;wMV9P{w8YfBTK(Yn^ z1X??8bj(&_oKL)|KL^cYR+%|wEw?Bo-gAAXi+)Nj1Qb9=KJ~04cu9WBd3&QUl>yYW%VRAP8N*-D~Xlp&Ddg@q{-}EV$c6;OE7$~+7pD3dk-av~_Z?*PZ74WK}g4Hn{|Amvj%y9%O; z(I7ZXvzvwKp^&T26w8?;O;yR9CmtS}(15{f^zP@=sk z#5Vo5*=9R@%RTudHH4&0%n*#%m9VhFn^;>|x?U?qH8H2nO@ti?^v=q?c>5(O?AO9vF2Dm#3Zzu zp@>CA?Nky4*0#RNzCmR(JWdA@e_F_VqTH7(IRj8}X>$Nt=G-qap>vIyqR*D=`5rER ze9pGB_4Z+oXYSfcvn0-8D4Ufz05v(~EgVBVCT;=FdA#OIDxw(cArF!%-0St7xWxfuv4U_O zbeV8o^912MNTzVG?hD^$nf-l@HA7QIpbJ|jncJE_7F{^5Si1ae1+g61Qn8%Y31T^L zzF48{$nfSytPjdGp>=f(BUXNt$++iO`H?>6AI}jLJHr2=EtDPzvFW54LRP3q5Rt3b z2p6D`%S~Vxcd>%XO?xSpyKkg>kW4Y-Rab~9qZMM#2%6}?<~Xm{s;fa}-G|hWTJ182 zNo&7gNa20M+-*i#R^|Ds=jh!m5xH96Fu)9Z&(W{!EQ3q;x_5DtGw7ltEjI7;gwWJe zJJ%OO-WGk1V&rfsS4=9WK3>VG9*Y4>0DVn!QW-e^$sB#FmfD$-6Sm^;#K&Qmq9HR_h}dnbuCoT8x*Fe`u7Ro385j;=P4vpa{Yx?J`t$%fc1p zGQ)b%YRHHe%V57WTEkj+G5xlO+X}n$+SPiQK}E%De1vwj&+fAAc}>E}U9tJ>=^lmBrT>H5y^E)o$mruKW_V7x0!$A9$`4!78N5-j=!;%2zHSt}y z*sWU}*`IaS1t!;Fl~i0f8Z=fDs~D{1i)*~;W;FJHg=%f)|8G+6c@0&McDzjU`Jz|3 zd7Lm5U42>fW25oMYz5PCpPBg`IygA5xyJ*TeS)E${I|v9(ROlIj}HPAM^qq{k=;OQZeaB3HCx_ zP7=5Cy~Kt21#|Fjy?wgeOS_TbqDkvx)Xk-NMHr^58+Z4XqD!TLurA@-9GBdZ`~*qd z>3#{UkZ<6IHnsnGrfNO!gZ&)=3UwMPw3!WL8K>-GF*wp~9QmIoUv zhYQK`cR14En{+FnI zlFONR-XagFaPC1Nfgc%oua!j#K!-FP#dzRuXrD+W)@xE_^_o#ay{1Km0^YU^T!RW` zp9JK0GYwlDByg~E;}1mq?)d{TM5SJ{amR+D1%3Fz2$i(gtKHt}3EL7;$VvB&`(t$Q z5N4+{U3k=hukjL`w$iFw21lhw9+WlF(I_Ur%gL8lw#S^SyZU>R?eEu+Or?^ztaIF$ zv-x_yy@QgVxF34AT0&4zpH3MMOMBE2M?y1c*sIqhOLf?2J4E#O4z0j&c6FUWMezCZ z`f&+U-{6aQ_A#L1UB}Ox8z6uuWx_s2@aI}eq}RBOs%al>ycX*^nFz0>G<|Kz7zWCx2djS%G_QXoL$V69=^#!eLYp5;`P1lH=I|bb@Ih`15?18zLozsdZ;6F7x%N zsfDEuC^iktkQAy`n_;gYXS=Uk{K!zr(W_Mx)2|{$tEo*{7t|p9poJaoc5ujeB4z#` z|FZ@or(XN3AIPXJcD1)ZzkdA+Kp!^n8ry1*U#-@AT)$Cq*-dS~hDaR?*Z3(gK;lNe*7zRj2#UYtWh5TH838J z*L%Qp_3(!?>6P_6cnNFL>nqr*?YC}Z)LbW=DO&ch_v<VeCd^6cQj) zKx(dXKMb*0uMrRm70m{81|b$XttOHJ7!or3`co0V`(dP*6 zabSxdU?etZJxr;pzzo((OEv*AXCpPQw6+m&72#wmYKn7()DS8`GHkBuom$+~vO%0nc5;aV+gc`Dn zn0Pbnh-LqBeW>Xri>V>2h*_y}5O$>iOz1|@UdzTSm_cMJ3zl9>f=EWnNaVUsh<41% zfSMwi6}y-Nt@UnsK9+NX{b-{~=uR6<_iA!E36Fl2ezvcOr-d9)dK)@HdK*kj&s-&K z*eU|6vJlmFPbjmCAVF#uP|M9-a9r?I(PibQYEnC}Oo1JkBv~EER57u>Q#BziNT!Gu zM3R6OT&j51_^Z6~sBx6K0NG$#T=qI-L#GNY2Sg=#El_5sS`cYcT7ann;((|mo(5zJ zr`xBAromDLvxY0gfA{z43yc~!0-7nLPgKjwTwrXHsRGMEpu$FJ(mJ3_Q5~2RIUT^~ z2nj*1l%2FqmmBMHV5$n49QeX9pB^b7C}#gr^AxEFCbidO^&*uDE&^Nn8=kX^^-Dy~ zv$~X6a>S&uYvEKRPyY}LV(CVe#I#qNO6C4+1kAn^9NTbOZr&nk6%i9_K_$U;8NW(W zYv>e_HBbe4HSF_*P2Z-XvNdt`Ue$$qj=Y@8hwiQwY1^B|=WJVjTq)gc^Pn}5ym9q8 zsMP;zvK_x1qV5S1Fht&M(v}vERuxfmAR-tR2UXlEA3UY|mEeM`7M$Z)`9v%AI8`D{ zb2@}&CeRdN2_{)k0(_2;iJp}$B-gWYV5$n4>{$t_b`+;VZ`$A~J!-=x3v2_Y_N-f; zu;O8=i-ak+3#5fkIaYO1q>3*3yIM@f24#wCgJ@w{AvUy7ip^9Jrzzi7@-BwqFpWE~#whL)D+h!?fO>C~URbneg| zE|SLm$x4Ez0T?I5PS`Hygqx@xVlKbiJWxhi=*~`CjnS~#YP9-i zgU)PxcGe&ED6twG9Xlht(`^kqy~cPp>@~XGHY9aVn*GLXayn}EnuD`W^Naw$Lq_&1 zoyYrvnb??|EAo7bl6{D)eCD+s4XBuL{p#qM*0Bt0Gw#F5?X^EyX7#Z$s-Kfdjs5ef zny;at$QTCf4X#yV9354N92=>*TIh}!RrbQ%8 z5P?cq$0n6>#SoCoyeS07QTn$MmcJ#a`5Tu-xEPR-Aq)2r3QaMN=cfb~pSUbu?67Jx z7OJL8(;RIoC}KEwOG1n;a=6m=j08ov3nn);(>h@UHVB5Ro6GBMmaV3;z!FHIKCxzr z152{xyf!#5*<`nHbziXt^`eZg82B+nI_xB-LALe^$lF~ zQY)S5NMlR=A@IrpB|C2~*F`i1y*InNlRRN8pOWS>60(mP*?*+)^5b&-c@9^?m&?!a zFdQg=KC)EcLKEH6g#kS-7gTw)vRb<4!8RTKHB1*C-HxI-SW!2KOW=vx2ACu%p}ixT zAs3SkpsEOT0fi&;m7j8k3M8PZ6B*rz?4zj3rN(5$iMEe!)!l1 zs?L9VZk1=%t4ylW0vtoV9%tYq2j!(;L)|KhtC|uBv69*Orh$+dgT@KjDOdTiRo)}* zV&D&?a3xvMb*4P5%-xK1e()zzQ^hVx3*9a96J@pAQsJz&vRBHD!z6HAH9^X zAm)XPu@vt?>iH59Jxt41GNf#(?^a%3Tr_Oz$I2H8>G+6QBV|ekPwoR$IL(3ubvgu^BR@>aq1DVZE~pePpYdD&{mnNQrB$5Csp8wJqXD)dcR&i-K|$* z5#1?oK3HZx@vJS3UoYuA-=2_A;aA~!`aV6|^$d7^&mByMbW+=LqM&$XJ+FJYbOQjx zij+r72@HGRQbglK0tEqU%4M@(?w8u$u7~zzgf7TS;z)BSnT1SqdX4_RU9&VNeevOC zFrddfx_kw42Rf`gZNa(Xusv+_2D7t9cRZXl`e*Ha zW6*2%Py5Ywt2xwXj?Q6auiu}JIpnrZ#3xwLn9Ms6G(aPVHV8x^$r5{qXK>hDc~gfj85$PK1fr6UFAQjcfCi|N zmmOhkzVyd7-6}mSJ=NUpr?WmJGL404_sYj zRTLsBkLqBmI?EAXvecl#69#~WQAZ9C#I@@6bpLyVA0~^q&b<&dfL| zj;Boc@+P01(O1l#voOeJ2l9Sft+U>^f7SxWw>fHb`{P-oe>&=6=HBpZ(Ctr~Gkq1r z@qQY(`M>84!^bV`i#^JqG>d8v3sp+Fnhs>5zXwgMEN`jQd z_TewVSj^Kc7@62aS^oCS^PMQ`4op$Hn#KI^>w0kmLC@s^-zNbVl1P||5pgCw=-|R@ z3F9?ai!M=&3FSfhE3X}dvxE~LwKs^1u{@d0uX+C7_LT-LlSwx;?jI3~38cZ8qKxKS zQ3(Qk{DikE2&zm7YNupSBx3v%1fTt%vc=tfVxk;Skzfn~WWyv0BnVT4_lxYq{ATfJ zp5|pu5e-%*f^NtcL4zcSu-=Q;U6QUgAsq$BkwP_9a+KeDv(PgIdHeVvjzALoLW7YM z1$N_Vv4nw|aQ6!V2xrLm#bpTFuvLPMnYy^TUtE7#WjoMC3daOh$~HCR^G*;<0rV(N zEP`O*%49GtE6goXK#H-FVts`QxsMvGObFeOFM|eQ_Qc!u_F)cB>^VEICJCU3-z6C%SEPQo#S zk`2>@kuXdl>^eY@fDMClxmbavWjJs)XqhN>TO|$Aigk?*#uNx&3=t^?sZ|3tV3{ns zp%R2u5>W#&#enAw_X~Jaj-DFD^a1}nRxjm&0+DCoE5n=Fu!#EYm5_Prv3~QBFohOu zoQVHwFC4O4F2px1X+_JA;=jQJd-2Oo+`bmpH>vZCcj@n4ZITSoi!5ihJ+ zBGR?8m%O89k#}!*VLz%HYAl_)&}Ea-ZLLm8)LkVa8ym4MJa@bv@M4msH_WhtU;!+i zmtX-PYdyj1^kB=><~7&F0?M}(9wch4_-xG<4o)p93+KX?3g~q_`z#me&exk9*k!6g2K#Z|8o8nvOZ;ScmKuw z#j+fB^SI$KEp=bm)M6IHfaZk?dGBzyM#QJo-5>W__qn_jZG}u@q(i9SHVod*1~4gc zU}Gn5&nPB*`X+W}CUTys#5F2Uv0gKT7%YDf^%Mk%cfBa}(p?Ud)>NpoL@@5d(vP?%T>ua$wfhH_@e=dNo{@=z-(j*|`&O?#)oX^6dQB72x(f6Y&2_cDi-ClZT=Z?kAF17> z5lZNYmaW11x^+VB!GD$M+AcD4T7o7Z}DFEa?>LZ?}wti)*t>$1W* zgR-@VEyls?_55bGT|XR_2ODdSi*RDQxtJBfCPp&otps|S&`~nD8p1s;S!LtR z{Q4daZDsUw2T!dF+h2U>mzF&rU@gBS94K{u*lG^o-e{|Fc6K_0=NCq^#;6JRKWAsn z&a6Lbj>dx~-Twrq)jYq@>GoQk$zaf!Ook%oe%Kg}PA3hxdfIQEPR|DY-k1QtL+boX zUlvtEuq1JwxXS0v+ZLi?+Wb*3e+u~uE_`~^@1G-Q{si7T;! zDiJ`n(mlWmO3DLlZVw#f34wwkq;My(uVA?BJC*t^Cs%u6#zn~aV-76!MBX(ph21Pa z#C)0HjTj)c@S86Z$g}(t8#6hiMiqQ7#o#Gq+3kD-a3H^>*X%Y2Q@HXs8jbo;x1u#} z47>eNV>lU}%{u+gc+{Jc`{DR4lXj=m9d*Wy=GoZ*-r3$eeKRf@u%j6w5Ef5sp>u2*BxDYy`5T9_&Q=l5`o)W`61EbJA% z9SegfTJiWWf;t;t(yx99Sdm+oZ=H=f)9eQ_?Lc?L=t+adqSl&-*2-UcrtCJ z);3)SleQ?i6;yW&;V35yhd9F8x(jFWDYAtldKha>K6#FsUngkW&hr_pGWq4gCRMgC zoJ$|Fui177g}n;j(h`l_0tIc=zSsrsAio7z=(J~yuAD*!az}WU7c&H2ihF>$KCc|+-<`4wh2M~v%#=2>JH!~ zyMDhl=(fB4W@{4M91jQM)^Ii*HTvT*ys3<@EBB|}R%6=hcE+tvvpwz22=IkB$3{ml zy*JjBqg!L$D!en+KijsqVxV7)tmE#BHM_Bpzu?16;y?ec*l0zXsY6zEG&ZB+1I!iz zbS2&0ndv2CYICcq03m}~WT9Z`mAG~MmXXUQFqiDGjB=5E;jdZVB1-`2y|%Vl==kTEN?AXYCHUbxa?A7gu$DrMTz zXtr61^|eJgt)tajuPHBqVi5-NePUC_E++FsZS=Iaf-%Og@y+@x8;rRRfdjzuR}GK{ za&Tozb!aG6VKOo2$0x4BiiskC_;2RhFWDC2QTUJ0n>1(d*NfHu^6BC8dRb*g`k0y8 zRNSa-sG1xQH$E(LQh7G5x}s6aChh~iX7;nu+GLf`Cr6PhO@`9`SOR_mHDIgueB3#G&#nn!!9O2fc5z6e>OYAK_Bi4G|rmvm{b?9 z5DX`SPNO%1TLj(Ks0H6s*ujlg^oFP1&S2Jh2u+ftcH6zLhHC_vdViPl;s<`zzqNf(Uj`6CK; zIe*hwuIkY-M~y9^=&Q2MLWa^rifxlvJth&bx=U@IC|m-4mESfRnz>km1g|2VEQ+Qs zoO7m@B!yrJf;k1z$|skhQAH#?3f+FiyT8d|5om&F1fqu|S3Cl&BI3L40%CdUxd14E z025Bs39!C5qa|Wfq@o=t#w^T1Y1zZ9#HMBrR~2>4V7EM5Y-B^PA*F_;<3<+(=eDU;x+ikIaia7st%K$WuGy%`q1{_UO@agj`bCc^5nQ z?ruBZz=L6ldny~0oCn*<3lUTP4BpS8ZIm%-#xux;JuY?{l1u9K8lJ{TCL^G@BrZ)> zFt{GS!)$kCPCcQ$*dfA?h$?tR*+DKUw@3)=!SN+soIDsK5^WMYD{+Hqw!}>46$EjU zZs%V3(7bNA%pMkR=D)8Y2P5Gsu!c$?vRG9if>1mnYKVig|9%dox=%2791}~t?=uK` zo!7ATpMNhtX-aumKO(idM9Cg~(}&F-s#qq`z1RsTo=T(&OsYN0SRfD&z0pA>LM}Lu zq?}ci$QjTSQtnuiIK+2m9LdYpsw`7tcUlP55JGJ15rh_R`i*L3ZUV-O5)40M9Zjq_ z0nH&K3T1DdJetBkR*w%rWCH=GJCT|ND5_;1Nn;Dtg-L|;7{O4zmLtFv{-^m)#m`ky!d-qaVo$zHlIle z6VBM3SB9DC<%f%d^CFO@v-1A(#}kAai?=WF{Npa$R@cbX#>Y?!b?C4Ec2#*W0Bnl( zq4~j;k2oFO!ynh#4a}h0)x#g|IDl=#ui0|>Z>#kmD`}EXC_N6|nOLv4P=Xk$*<3#D z_Su6S9`TR63lTB&K3;F0a9$`)?ADLl>+F5Nrl$@Cjo6^n?35_wZrAT33o?p&Vm_i> z`qlllOfPP03m21_xAU8R$8caFKxVvOOPKLmTevhc#hbAYnJg-drGHgtQ59f&!lZVS zgO(67*!gw4*h5L=19M|zO<=}Y)ZycPJpnICm-2?82AjM?*mw&yB4z04au4;?wZEV` z4Zgd};4Jic`%VwFM5%^W1wj0$P zRf81^-D~lRCka@>AJ=QB)c+>iUeEWq_e=7aa`5HriAYsXB%{*X%al4^u2-;|bVrKm zvqlUpU%$v%Rkh&6+NAX^j+LN=RR{lLR#q)k zMeN(dfCctMi>ux05No01YNgd_V^4bxiEw(=HV)!7`d!E$W5Kt5!+>`l?j~Mn|@~BlfrR zMKaY1fkA0TVx{HH1uj5H{`KFI)nb|KZ_^b5KJs&tOfajwrad_L>WF3y=@#2L>2+*= zv}iy68mq0Hr{C*tYxc-gI}Q?BwnC1)ckAWD&3e_}rZ^B65&5@4rFAYcZ)m6vLA7^G zxT3nrWPD$nT=Awczn~-`LR+}?=8i(P?dHZyEJKZ3=<1(F0 zcYA)9RNS=1g_m^8x=4nwY9W%oIcj9$PA=K#)?v{{#5p>ko<(q!=!~?e`)J7-aAb}D zJfAMr_J?0#8}?u572B7gTV25n&p{xiE@@~Mlspll2nQbv$)Gug{M#MYnss0%UTPqS zp!+^WXAmJpx&7rR`aVQ~eDLc6FYngtJub)6H<6kzg7n})Bv~ly@*Ysp@Nr40$w*Pp z_aKSv02~8ygl^Wm1x@V!c9<>~v@%VxZ})A4QhdOkV-wD}P5we2OG-Ui)a5$L!o(_y z_Qc>o&z!H0ogA=0_ldN`w!P>NI|@+5&AuHBR}8gU2`z0%p^VAZV0nH@b6Kc98@*sI zdW8A+_4D zIA4m?;1rEk0kV;g7F#Tf5F$G8_x5w#d?X7WD!+%c(m}vnEK4|Ac%?kq5v&(+bjP&S3NU4P$K-6Vgd71b`#%Ky0&Qfd< z?V*@0r75vGperalQ!f)ST4~13Gh9hRW7rcDHE`tO2~|@r0;L|wPf-iX#S*O;p?h`! z(AA9hb^={(1+6L{Yp9;`F(^fO*(=goKF(;hu?gzMVZS--(G3@K7W|NQh<&tQ2Wc%A zX{ge25h$HuGC;F?o4F#L<)S=JW#_A>*O&)ql)^mlkJOh3W3;-kbqGPm?ZbF=gB^U# zxv|~^wI~}&s8(z!Ll^dkqGn^4j250Q=B5G7FiU(>N~F2Y#S^NETm(uhA?7+4OSEDT z!@j`I{;!Ml8|GUqX{1PU7Bbd5z@bWTi7MFxMskN_w7~BXI!(7yX0|NC!ioDY{x3n@ zA`djo|MNpDrQ~r|)Lr~2qm}hxaeYmZiEX;u2`xFVg4C0N3Db)MW+=q@Qltr|XtWA! zO~OSH8_t;l9rfSnH*eGZ?Rp-hkUXTJ9VidpP|?pG-iq{;hca4WAFw{L`*4eut@*q4 zdMR?#gc}tPe5hJHph_d9#Ey0{g(_oMW)4r>NvHGumk=H72~3dQjH7zDCM}w zqSbS8v*mIB@oKilc>pY#?Z4oqd<<$W86=?!$p9M4FqkN6BN-IOsDRm81fVAAbdRGH zBAq<7Rh&@?Re=vlgd%+4Vr57$QlbVQ0#ZiAJ^|WGJG@=5cPZ3LmRv0&O4A>tj65`< z+Q@^CSU}H15vdTh7R!{oV*@kmBvJav!4j&D9PkKj^1k0X>Aly*o z@(`(#cZ>UU$@4?Xxry^CXavc?goT70Fd;tjXxLm8jU7(WNb$8p@*W&xI_mjzod z{LK{dKo*46>oJYTekqV2)-aJ3?#|JVs~}E>dI@ zG*Vz{=&0#Sp0sT7-JDzL5v%p@cZ+*nyYgmpI4*>U?*x zNmtRiIvwahnvjwJ*=ZWYUYD_H1vBuHZkZ#V0aWV}azrT_$uiJX!TfN7WS~UZzu)a} z0Qw6x*!XC(4J;{^iEKkfG-?|#vMo#Njfvi8I;X>r=S-JNy6#fF4D(*HP+_5g3=cwh z93pU07S(#DaHJ|Qb%SZ3#V2;p9iR5Xv=6WsB1i#Q1fg}Gg^Z~GEO5Nwd{r1-Uug$&)kCCiWFGv54f;T&)&q;&zW(?X7_P$0vl{k zkUje)-KKA+n;oC^3T~#G%{k@Q)}BH#Td#Ke1Rr>&B>kz#$RSGQ;AfamB_73Ofx1{~ zF)>EIPjP%?x8Dgiy*^C>Z-2dY#{XD-dWlMMNSdTbC<%(%5+yHlB+w>0)1bVi!|HOs z-(aG&?cX4~tFzO9EgKixcybNlCaiuwI^eX*Ut6u32YR&GjTJ27T zEt!Z2Ht70XUgz5$3~T+ys9EVWahpuDPFarz<8Gx|>yPX0eiN7SRwdxeW-#LFQR#V* zkPlgSHiy+0><0L_`awsrj{G^35^)O9f@?mYRQ9b*rMNCy-jJLm{T-~t{)8t);^~r3 zlUFY4WU)(r{rKk189;F&egz{#uU6|ljSh6%ayn1;>x5U#S@OsFklYdu8XJ7 zJS1xIsQYzQ{e1duv0HqOjxGu)DY3`i&#bnT|sVRIn#x6dmo7)iwPNQLS`>?v%N^bFi|LMO8LNd$5n?5UQ#b^@rVj?LBqrw zt;OX3WJZBLnM#F)u;?My|55m^6h40<2HsexA{9su3$NMELOtgws#}H2ARnd(xIawj z942D*Aki6olvKTh$YCHx3lfzBb*D0+a@de9DqxF}A(O#E zScTy1!6n9VY{g=Fi8@c=z)H>M$!t>+ZLIu=ghM4zENsd=S}Ys3Of0)}xL7t^m{>fW zkc=_LZo9RiOXRW(i&>}4t#d9}D6;l81`;qo`mLQ47UoCJtrPYmb4`Q}U8ppp1v~rZ~tmj%S>AxvU zlCX{_ALFd6rl$?tX(CCSa?~YNiqiMAWE9tO7?f1FzZT`%OezCN(L^#BB*Be;*vOO@ z_06}wYYB^bWd=u><&iqa5;L2Ks^_4_Yn0|5h+m_!7zHUK&h=@q68-6dY9+6H{Lw(6 zy+lGBb(NP1EXDC_Yk1ghF;}Ofkx}Y0;ED;1(&h9)#AZJr#VoeDCr+*$C@N`p%ltw{kRW%5^(INcdlMFOT6G56`wUc{ML)D6;H=;xrG=^`m6 zsgWa+zCVaPW(X3yAA)FSfl7?SJzevFbl-cC-B;$9VizI0A46Gi;W$#MhmF6Tf^|Qf z@c+CV6}8-4gu&)nv;y2kx4Ff}a(KT--cF*c#e=IrFYLMzHe%;E2SxJxfKfhozN*WY zyCTMLl3e2wD$60^f#%#h0{3gHbeISROWIpGpPy>#rwFJr#7f4j@j%yHu$-LHeuaW8 zP#~_gmiUDiA#Vi>^dk&-4p}G)9SFOZ{^@i+-y$W5C09aM=Sd?O8_z+YisKiUPZ_oX zhUmbDe^6x+$~mbrl=0m579O2eNCVHr*~tU*TTumk_ORYA{=wG8 z^<*Wp;F=4;ePi!#8d=BA<{kA~lheV|{7pOxOmF5{aKi@!u1&rNS+E{!o8+`#WAW&M7NT2HFvJbG;is_t-%d9e5 zF8@BPA8gZ**3I*59@6+RiQaG5SeQ{&yrS3(ZJ1J@{4p(!1Af@2BXY+u5ZMsjnWv5Y ze13unXsX=jNdNbIe#O9Z*I8_86!p%~)1$A}l{V>_F^_OKL^t_XnzpHAsY)M0u32gp z%zo}}KQbtnM~-d5KW>-s43Qmn^;q#WCPxXy^$d1I5HQ1l+J7Yq1l5AZ7sUqVKmU&D zVTOl@6&-;hjw}!0KZ-0z5k*!cr^t}i%`HgR0*ynuq|tk6AJ^_}`ms%)*@wY{>FzLu<%wto4%RD)KF|<3;IM)cfu8q0iXj+AjWLv|-4I)6J-s6;0C_I3IL)QlJlOj& zFguo;ID#6e4J`+rO|ezBfy9JQ8e~Pk$R67mV%w$M|MAkBNo2Fwk#~k0zjk}I0VOU} zX@N?m7gzI}>FVZyB(RUQND`0J#!6~jLfO=hvq=({;2^g0u^5U(2%Fo*OvIU(L688fsEtmLMcl5eFjOkPxOEwtAhMMGiW5=YuC*FS{Rgq zRBDYrSVp}4HRw*J#!#Dj)p36Mv)`+ zL?qQ_!~GZQz1eZykdale*hy7I*}R~SOHQI{iU7)Wh+SJ)MchPZ=TUIwB;HX*PF#ev zB6lNZ=ZprFL~_PKsu^8aRf{B6R392FrZO&X*WU)|lw6cZnGDDPp^VZ|QWjkZ(#?+S!E(OfD65nIWZFehc&iusFZJUxEoB*k(j;LsI)E{he&mB$C zv}s&<$|EZpGfDMq$5u2M65xC{zS~e{smS)vpvs%QFdcH(G9H5lEvtO#kY$us`;Cov zMaI!6MrI^0SYYdpY!CMmBGsn>r3MSky)G<-k~LK%j|K`Chl_&Sf%j|!JAZ^ry}@yZ z;Jc9wBmuG+rB#h(=oZOoAP5(f`~@W@J;VyB5Cn**$|?aJibdin;0WPXH_H@BpK%Wu zEi?4>V^EK?%9r*yqqG)JQ!Ers7mE}Q+uLTyGO@<)B^jGj3(Yzrk#T?-uL?G#=7>WD zAmkGiOC?iq5yGJ*DzHe|OwbU~%<>VEnPB09@lJZAXby0Ia1KPccn)B=fNUyvWUdVh zHb6S7ypSzqM6lq(MWZYt?0Vn7CKqqUpN1E2F5U+j5(O9_lPW9ZQIv|hnF0zI1}9RN zM+u_<1B6j!V}wyaal+uTrPXdT#d*gWT)4r*KI{TRqGo~yN@aow;fQ2WCApNs#iQy) z$e!JujG5XpOfm%(Ad)I8WVvKyilk8xabjHVA1EWz{>x~(yJZi-JxG);9f*lDR#wPj z&?*y%frSgi>aW!8L4*NYhRQoUV1XSBS&JYDPQw<&ReI#w;`cZ#Z~6XD2hxSJ!L3X6^atlia_0?E&VC!=4XPLlNwStZjQK$>k