From f2002d4d7df2ec520c197bc6eeadc277284988a2 Mon Sep 17 00:00:00 2001 From: Hans Roelofsen <hans.roelofsen@wur.nl> Date: Thu, 2 Feb 2023 10:56:38 +0100 Subject: [PATCH] mmmm --- COMBINE.py => src/COMBINE.py | 39 ++++--- .../attribute_table.cpython-310.pyc | Bin 0 -> 1512 bytes src/__pycache__/combinations.cpython-310.pyc | Bin 0 -> 1963 bytes .../source_rasters.cpython-310.pyc | Bin 0 -> 5275 bytes src/__pycache__/target_raster.cpython-310.pyc | Bin 0 -> 3652 bytes src/__pycache__/windows.cpython-310.pyc | Bin 0 -> 2540 bytes attribute_table.py => src/attribute_table.py | 5 +- combinations.py => src/combinations.py | 9 +- source_rasters.py => src/source_rasters.py | 64 +++++++++-- target_raster.py => src/target_raster.py | 36 +++---- src/windows.py | 100 ++++++++++++++++++ windows.py | 77 -------------- 12 files changed, 206 insertions(+), 124 deletions(-) rename COMBINE.py => src/COMBINE.py (70%) create mode 100644 src/__pycache__/attribute_table.cpython-310.pyc create mode 100644 src/__pycache__/combinations.cpython-310.pyc create mode 100644 src/__pycache__/source_rasters.cpython-310.pyc create mode 100644 src/__pycache__/target_raster.cpython-310.pyc create mode 100644 src/__pycache__/windows.cpython-310.pyc rename attribute_table.py => src/attribute_table.py (88%) rename combinations.py => src/combinations.py (76%) rename source_rasters.py => src/source_rasters.py (69%) rename target_raster.py => src/target_raster.py (86%) create mode 100644 src/windows.py delete mode 100644 windows.py diff --git a/COMBINE.py b/src/COMBINE.py similarity index 70% rename from COMBINE.py rename to src/COMBINE.py index fff2493..d188f82 100644 --- a/COMBINE.py +++ b/src/COMBINE.py @@ -18,11 +18,10 @@ except ModuleNotFoundError: with Flow("COMBINE") as COMBINE: destination = Parameter("destination") - source_rasters = Parameter('sources') - testing = Parameter('testing') + source_rasters = Parameter("sources") + testing = Parameter("testing") source_rasters = get_source_rasters(source_rasters) - rw_windows = get_rw_windows(source_rasters=source_rasters, sample=testing) combinations_per_window = get_combinations.map(rw_windows, unmapped(source_rasters)) @@ -43,12 +42,14 @@ with Flow("COMBINE") as COMBINE: max_value = get_max_value(combination_dict) max_value.set_dependencies(upstream_tasks=[attribute_table_to_file]) - target_raster_written = write_target_raster_chunk.map(rw_windows, - unmapped(destination), - unmapped(max_value), - unmapped(combination_dict), - unmapped(source_rasters)) - target_raster_written.set_dependencies(upstream_tasks=[combination_dict]) + target_raster_written = write_target_raster_chunk.map( + rw_windows, + unmapped(destination), + unmapped(max_value), + unmapped(combination_dict), + unmapped(source_rasters), + ) + target_raster_written.set_dependencies(upstream_tasks=[combination_dict, max_value]) if __name__ == "__main__": @@ -61,7 +62,7 @@ if __name__ == "__main__": Path to destination *.tif file source_raster01: Path to first source raster source_raster02: Path to second source raster - ...: path to subsequent source rasters + ...: path to subsequent source rasters Returns ------- @@ -69,15 +70,21 @@ if __name__ == "__main__": import argparse - parser = argparse.ArgumentParser(prog='Open Source COMBINE alternative. By: Hans Roelofsen') + parser = argparse.ArgumentParser( + prog="Open Source COMBINE alternative. By: Hans Roelofsen" + ) parser.add_argument("destination", type=str, help="path to destination *.tif file") - parser.add_argument("sources", type=str, help="path to destination source files", nargs='+') - parser.add_argument('--test', action='store_true', help='test run with 20 windows') + parser.add_argument( + "sources", type=str, help="path to destination source files", nargs="+" + ) + parser.add_argument("--test", action="store_true", help="test run with 20 windows") args = parser.parse_args() print("\n\nStarting COMBINE\n\n") COMBINE.executor = LocalDaskExecutor() - COMBINE.run(parameters=dict(destination=args.destination, - sources=args.sources, - testing=args.test)) + COMBINE.run( + parameters=dict( + destination=args.destination, sources=args.sources, testing=args.test + ) + ) diff --git a/src/__pycache__/attribute_table.cpython-310.pyc b/src/__pycache__/attribute_table.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c807626c53ce94ab3f359a253bdd861a6eb6365 GIT binary patch literal 1512 zcmd1j<>g{vU|@Jxb36GVGXuk85C<7^FfcGUFfcF_H!v_Tq%fo~<}gGtrZA*1<uK(k zM=>)(#8{$OsyI>@QkZjCbJ?QU7#YGD^7vU8QrRn285uwjEXM(ni)6@SEN4h%PGL#q zOkquBOJPgpN@Gi5PvK}`X=aS#hRSfJ@}#k(aHVjAMR`*ggBdh=UV_}_r^$GWr6jR9 zTa)n?Z*YETQF3ZfVsS}oQSmLV<ow*E%=nbd<dR!_#bBxUBB&g9N@{UQW?o`RW`15W zGsqw)W?^7pU}Iola0dA^hk=2igdvMDiz$UMg{g(1hG7BoLIxLxX2uj|FrP7t1<Yds z^B5MeLS<QdnQNJAn6ubY*izVg85tRBn6ubRII=hwaMds^WK7|ZWSGs6!a0{Ig$?AZ zUQpQa1T$#zR>g90DJUo?SQR7|CFUw1d|-tvjOrN_DI|YE#fwr)N{jL!oMc9*H$fB= z0|Nud>%j~R44(xU7#PwSY8YZ!Y8h)7Co&Z>1v9K<C;~;fCetk@J%d|}6<{8i_+{v9 z6_Z#{P#jZGl%Ex!oS%{!19od(YEevaQF2UTNl8&=QfWzQd`V(bPO4r(<t;9ooXp~q z<ow(MI|-1DAnOGfsx)#Fvs2^I)!XFcCnx3<+vy=RVYr>0fq?<!_F@&7+xco4LD98< z2~0BAFfL?V$e6+)$pG<>CSwuE|C%hfnDUEnu@oehWZdE?F38C&Nv$Zk#gUX)oSK)I zo2toF#L2+G5XDtolnhNUU{6B`ZUzR1A|3_?21!r~0fi460~3?jf42V^4ul165y+(w z-5~W)^KUVhA;gN{#>#@s=Vf4E&}6>Fl9E`Gc#AzbKc_S|ulN>gW?o8aMTjQjE!NbE z<kTFnZ>m`Il8ei3v4$n)l!BZt%D}*IiyN#mJ|{6LHOEhr`xa9{$}LWp#F9j}qQu<P zTRdq+`ML2$smb|8DaE%~vQsOIZ*fBt6)2K!v6X>LE55~3k{_R(lUb0IpIDS~iw(pp zE-T^#IguYkfKrVnOA#p36tRK?Kw0M&b4g+nn%8cLV2fsur;EivIgUqwk&TgsiRGUF z3)?Rq4i-iUMy~%wN+7?mK@u=Z=z^jVlzzau6cnZ<3^feRpi+UcN(+Auf|v%$4w{U& zm~&F|G#Md202u^vH^^bPc+*o$;&T%#;=zHT3W{!!ogC~%AhssoEw+Nhyp+V^B2Y@W z#a>X9nwFYeQUp>12_kTafD*wiVc-0e(wtPk{1UhP(!3PcqN4nwTSCP}$$HRGhm}h# z;L?h@xTFZ;dFIT#60mg;ccHnE!zLGOt{o^mz}bL<frpWUk%>uwk%v)$k?B7Z3lk#~ Nhz4Vx|4fn+i~zCgXoLU& literal 0 HcmV?d00001 diff --git a/src/__pycache__/combinations.cpython-310.pyc b/src/__pycache__/combinations.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..52b14f944f89c2122448097f296b18674c7a2626 GIT binary patch literal 1963 zcmd1j<>g{vU|=w-y`8Mc#=!6x#6iX!3=9ko3=9m#YZw?9QW#Pga~Pr+!8B78a|%NW zQw~cmYZNOZM2;<rErlV4IfpHmJ&K)?p^7hsA%!J}BbPIZ6Rd(Yhbxymikp!koFPw? zg&~!v(wdP01i|Wfk<{@))I~DnF_tr=vZt`6a;C7Sa;I>l@~5$-aHepzurxD938b>8 zaHk5UaHI;Qv83>%@Pb8!Qy7C8H2GeF{Nbm`c#ADOGcP5-T$Aw@OG#pJwkG2(Ug!MW zq|CfjxCC!-erZv1YEWWvNorB?E$*V!#FY4Qu(n%##bCMkBB&%=QEEwPQC>0=$b2Yf zWnf?c1tc>ls2Ug;7)ltj7#A?5FfL@QWvXFXz?{O=!H~r=n<0g{gCUD`Hp5(&g^Y|0 z?F?y*DJ&_hEgUtBS!^y0&5X6oCF~^}C7d<PeGJWv&5X4yVBKsW-6`y|SyDJkxE64i za4q1eVOhwykP&852SXNb4ND4VFC!yE3Rf_LCU?~%E(HYz1^3hvh2qo_h5R&y#GD+3 zWU$8*OEUBGiWM^R6cQD3GK(RyMMa5~#R?^fMd_&}sVNGHB?^fO#hH2OIjIVu;LtBG z$}CA$fCP#n*leqU#G=Gpuq-sNtP~QVDvI?`!dM|cDJwO(q!?KrYPed#T~d%(l2NQs zlCJ;_afSRmg|y6^REXXpaOhisIk(ty^3&5(i>lPzGV@Y0^U@Vc^D+xdQ!%^=akWAf zheCcS*tf}y(3k^JpqON1U|<ji#hw}i14BAP4MQw{En^A80>&D~g^XEDDGVJ9S<ESn zy-W*O7BWm^Dr5>~&}4cEG6j^vAm(eb-eNAw%)iBwUyz!2iv<*FQCvlt`Ov_*#h#Xv zSW=Rjr^$4SNzWjP7bO5zG8Tc{u#(}Ip0ia<VnIQ1OhHk8R(x`PN@@%w+ER;Rii?t= z97r7M6;$5hvH`_ma(-@sodU=QpghaQz{Di+pY4B@N_uKZJVZNGhfPj?a$-)gogPA4 zm3U5md1`TqLRn%?X(}jPKs=-n#cW_;QpIGYpvf4;RGRFk$#;vrpeQvhHM!&#dvbnW zNoqyOE#~ypl3Og9d1?8#nDUBlv6keQB<9@WhWZZVwp+}_ASDoHRc660ro4h%%(<C) zw^$QF$u3H~IJG1m5_c$$)no++N)bB)149uf0|Ub?Hn4``C}AwBi-bVR1VIESDsKs( z`<)*YJQ55H3_Lt6j6#eo|G8LLnArXau(B}9F|zy@U@lSy*}(&fIcTI6qofp2{s!fB zXOKZA;C$Z9P|H}u;KC5gS<6(zxPY;SX#vwhhJ}o^jD@Tzj44bl3?<Apj48}1EWJ#i z93IS|$?At;C<_AvLomotF$M;POi=P;k723>7alc?lflUi;yaKRHJOV9K<;GBi(&;w zEkddY>~Suel+5H3aEdSl8460^VhmN9xry1S$l)6gQl^JU5FjpCR}rW%(`3BGT3nJ? zRHDgJBm=UKwKOj?KQBrg6s%Z+{}yLzUTJP>QDRA|CUcPr0|P^pKw?e~vW3Nv=mdEJ z;%2aOMX|a|2jp^aT4v&46krr%EYf0NV9*q~#hO=|TTodf4{{O*q>RYSFX91l1z=n~ zNCGY{0(rei6qF=Dad(RyCJqX4NU{RO=PhC1{FKt1RKNTZxBSw)6xX7n{Gwaj#YM?5 zgKi0dIM6f=v85OsD&QnjBnz^g1r&Z@S3*38=1mTpT(Bi}pi-k4<UI}s4n`hE5N2ZH iVH9BGVFZy(|Cm^r7?~KE{xdN#{bOS0`O73D!3Y2j{}xvO literal 0 HcmV?d00001 diff --git a/src/__pycache__/source_rasters.cpython-310.pyc b/src/__pycache__/source_rasters.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b9fc20a4187b78cd9bfa0950ab9e5c99ed5a8af3 GIT binary patch literal 5275 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 literal 0 HcmV?d00001 diff --git a/src/__pycache__/target_raster.cpython-310.pyc b/src/__pycache__/target_raster.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..121ad595526dde3d97fe371f7ef30a0a5985baa8 GIT binary patch literal 3652 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 literal 0 HcmV?d00001 diff --git a/src/__pycache__/windows.cpython-310.pyc b/src/__pycache__/windows.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8b7c66308c11ac29be546a44a6ee04416ca9f5b GIT binary patch literal 2540 zcmd1j<>g{vU|={_e>-^#Hv_|C5C<9aFfcGUFfcF_uVG+dNMT4}%wdRv(2P-xU_Mh6 z6PRX>Vgb{vQEVv;DNH$xx$IHwj3BklIUKp1QJjnnRU9b{DJ(f$x!h6Qj11undHgI4 zsXUeDj0_+Mmg9xUMKa_umNU3Bq_C#2wJ@ZxH8Vx=rLuE^AV-Qo3TG;J3RfzB3U?}h z3Qwv)3U8`l8dnNm3V#c0Gh>uc3S%&Xrr=AEKm0TqZ?Tjl7H4ZR-eL>S%uC5H*JQlK z8=PNSl$;urSX`1?RGbV_h>V3`o(^GPU`S;Ec{GYCg)xdbg(;OKg*lZag(a0Gg*BBW zg)NmOg*}xeg(H<Eg)@~Ug)5aMO(=ysg{OrjiZz8dl`V}4>@1cj_7s5>!4`%njufF_ z22J5xyw3T#Ntt=65I0qMb15h&C^#w<XXd5nq$(7pCZ_0@7iE^DDwKmAt&o_PqL5iq ztdLk-oS&STSdyBeP@0!nSemMk3^pjSBr`v+7;MTd&Z7MC_~MepqLN!25N3YCEuQ53 zoYLGps5m#AmtSy;DX-`jTS<ONVovcbu9EzM_?*<VlK2WFcI7RuqSWI2oKlc2$>1ad z4KNU!gMop;8I(vo7#J8z7#1+rFxD`oG1V~Fu%t09WU66^XG&qHVTfn0VXa|^XQ^SU zVTflfVasB#;Y?wyVNYSK;Y?u?VW{CqVeSRVailN=Gib8-6)`d}FueT#|NnnYwp)ye zw-}RdF(%()Ou5CFdW$hlle37Kfq~%`cUn<?ZhUc0W^!urEv}->{CG%^-4ccbP&{$~ z6@lD)ixuqITWpDGX_<Mcx7ZvZG-pXsVqS4teo?L_*DaRf)SR>;HU<WUB6bh~@?;Sw zhy^mDh#SNL<&Gj=5Q~q2fng;>ksJd9!!J!|tC+-sg5sEhqWrA*<ouM>7>E;6i(-n4 zl4BswE7mKhyu}e8pP83g5+5%D3O-P}W8vXpWc$y?%*M#Z$igJR$n(ES3?-@P!L;0B zDosvif<^;~0<l3D92Fo()-cvE#4~^bb0wqSO2#4y1_lOArXpF8gB3vp$hlxQ7s-P{ zQoJ~|BpyqkX@eXGGMS69N)^>HICLa~Vh-dc5C*Y980;=kfYvZ%F$6OdDS@1z4001A z#7*eVNyqLSJ(zRYFr0%!ho2@VD5&!ib5rBvZ*j%P=jNxB=788d@$rSFi8)Xi_W1ae z{N(ufTg;hxB}EFLFkvoEEh$m~xl|QIAe;zhfr71wm4ShQALJ&G!#EgN7@1g@n3(=C zF*E&TVqyBj#LD!WiH+$O6FbvSCJv?_Oq@*LnYg&V@rm;=gY~|=z|O$nc8jkVTqwmC zK}w}typVJfpOKoGo>6j(2g)taOex8@#a5h{Tac4_i>)ZNq_ik6nFSQkPz*|y!munU z!wAZfS&R#qQWzI9*0Pi^r!dtpWU-_$OET0jN-)$gHZ#|<!bMpm8ETj$7;2cBnQPh7 z8EV;6m})snSQoIBu-C9QGnTN|ur)I-WUA$?VRd1M^{nNpVRK=Kb*bg9VPC*e!db&r z!&Sp5&QQZ$!(GE9&QQZq!&$;r!o7f}h9QeLg-McOA!7<_GgA$B4ObeI2m?q2uRNP1 zLkSl)6)Eh^Oeq|_oC_HlK?Mh!IYTW+p+TWe4a)+)6wVrs*$gRMHH@<vQn+iFW;4uX z1FK^$>M7x0AW*}e!n2Smn4yL}m_d{G7o);0ww(O*^wc77fpd!u8se<rpe~XD6+)o& zTO<HVtDGd22~`}<MXBJ@x=IjQlou=HrzsR?R;4Q3VvKkR%J`asx7Z7cQqxkCOK!0z z=jWBAR+QXgPERel#afh@m!5h{C_Od5xFE44GchN=peR2rGbi;HQ(nO>j@;6mlFWjf z%3I7isd=~95(^4a^HRWx>K1!?YDr>ANzpClqRjkTEcpegdAGQsNh~L`xa1Z~W?owU zEw-Y>yp;UhA_I`$c#3pEi5!%Ui}XP(kZ6%H0|P@87o;LdEGj9E;)PcpAnq-8NXjg} z#h4ex3ocoqC2%n$sK6yBIJ<xeP@cKP2g<2M<uHXtpzH&xZFxAEm;@ME{xdOyNET)m zMiE91Mh-?6MkYokMm8vBViaLwV`Tcz#KiPhgcZhOVi5tU`p5E-<v*7g(@Pl%7A77> z7N#OEkl&b#bU;1=5pJ5oMeZPuC5Vs$WpmcN(%gc|B0CV91Cj$X^NT<wRuQP+yCnb< z(}Q{zT=zhN3zYY63HySJ6u<luxBSw)6xX7n{GwYz#YM?_&@hJ>Pz;WoA}x?TEJ^wK zIk#9qkpXrhq$CE15tsl66o(C@tg-{8z+wvq1_llWP=J6i4<ipFD7bhS1sIwB^RX}~ TGckjLiRBLyByf<*Ac5Zi{*Z{* literal 0 HcmV?d00001 diff --git a/attribute_table.py b/src/attribute_table.py similarity index 88% rename from attribute_table.py rename to src/attribute_table.py index 4723dcb..d85d74e 100644 --- a/attribute_table.py +++ b/src/attribute_table.py @@ -29,7 +29,9 @@ def make_attribute_table( index=[v for v in combi_dict.values()], ) tab.to_clipboard(excel=True) - tab.to_csv(f"{os.path.splitext(destination)[0]}.csv", index=True, index_label="Value") + tab.to_csv( + f"{os.path.splitext(destination)[0]}.csv", index=True, index_label="Value" + ) @task @@ -40,4 +42,3 @@ def get_max_value(combi_dict: dict) -> int: :return: """ return len(combi_dict) - diff --git a/combinations.py b/src/combinations.py similarity index 76% rename from combinations.py rename to src/combinations.py index eefd3b0..7ccdde8 100644 --- a/combinations.py +++ b/src/combinations.py @@ -11,6 +11,7 @@ except ModuleNotFoundError: from src.windows import CombineWindow from src.source_rasters import SourceRasters + @task def get_combinations( read_window: CombineWindow, @@ -25,7 +26,7 @@ def get_combinations( logger = prefect.context.get("logger") logger.info( - f"Finding unique combinations in window {read_window.nr:004}" + f"Finding unique combinations in window {read_window.nr} out of {read_window.total}" ) arrays = [ @@ -34,7 +35,9 @@ def get_combinations( ] unique_combinations = set(list(zip(*arrays))) - logger.info(f'lowest value in window {read_window.nr:004}: {np.min(np.array(unique_combinations))}') + logger.info( + f"lowest value in window {read_window.nr:004}: {np.min(np.array(unique_combinations))}" + ) read_window.set_unique_combinations(uc=unique_combinations) @@ -46,5 +49,3 @@ def make_combination_dict(read_windows: list) -> dict: return {combi: n for n, combi in enumerate(all_combinations, start=1)} -src = r'w:\PROJECTS\Nvk_bdb\b_HDB\b_scenarios\2_regionaal\brondata\Regionaal_Geworteld_Subsector_rel_Y2050\25m\Regionaal_Geworteld_Subsector_rel_Y2050.tif' -arr = rio.open(src, window=Window(0, 0, 100, 150)).read(1).flatten() \ No newline at end of file diff --git a/source_rasters.py b/src/source_rasters.py similarity index 69% rename from source_rasters.py rename to src/source_rasters.py index 27371c5..4526d55 100644 --- a/source_rasters.py +++ b/src/source_rasters.py @@ -7,14 +7,16 @@ from abc import ABC, abstractmethod from prefect.engine import signals import pandas as pd -class SourceRasters: +class SourceRasters: def __init__(self, source_list: list): self.source_list = [s for s in source_list] - self.procedures = [VerifyAsGeospatialRaster(source_list=self.source_list), - VerifyMatchingBounds(source_list=self.source_list)] - self.geospatial_profile = getattr(rio.open(self.source_list[0]), 'profile') + self.procedures = [ + VerifyAsGeospatialRaster(source_list=self.source_list), + VerifyMatchingBounds(source_list=self.source_list), + VerifyMatchingResolution(source_list=self.source_list), + ] def verify_input(self): for procedure in self.procedures: @@ -39,7 +41,7 @@ class VerificationProcedure(ABC): pass -class VerifyAsGeospatialRaster(ABC): +class VerifyAsGeospatialRaster(VerificationProcedure): def __init__(self, source_list): self.rasters = source_list self.status = True @@ -53,10 +55,10 @@ class VerifyAsGeospatialRaster(ABC): logger.info(message) else: logger.error(message) - self.status=False + self.status = False -class VerifyMatchingBounds(ABC): +class VerifyMatchingBounds(VerificationProcedure): def __init__(self, source_list): self.rasters = source_list self.status = True @@ -72,6 +74,27 @@ class VerifyMatchingBounds(ABC): self.status = False +class VerifyMatchingResolution(VerificationProcedure): + + def __init__(self, source_list): + self.rasters = source_list + self.status = True + + def execute(self): + logger = prefect.context.get("logger") + + reference_resolution = getattr(getattr(rio.open(self.rasters[0]), 'transform'), 'a') + resolutions = [] + messages = [] + for raster in self.rasters: + has_resolution, msg = raster_has_resolution(raster, reference_resolution) + resolutions.append(has_resolution) + messages.append(msg) + + if not all(resolutions): + logger.error('Rasters have unequal resolutions') + self.status = False + def is_geospatial_raster(file_path: str, msg=False) -> (bool, str): """ Is a file a gdal compatible geospatial raster? @@ -161,6 +184,33 @@ def rasters_have_identical_bounds(rasters: list) -> (bool, str): return out, msg +def raster_has_resolution(file_path: str, target_resolution) -> (bool, str): + """ + Check if a raster has target resolution + Parameters + ---------- + file_path: target file path + target_resolution: expected resolution of the raster + + Returns + ------- + + """ + + if is_geospatial_raster(file_path): + raster_resolution = getattr(rio.open(file_path), "res")[0] + has_target_resolution = raster_resolution == target_resolution + if has_target_resolution: + out = True + msg = f"{os.path.basename(file_path)} has target resolution." + else: + out = False + msg = f"{os.path.basename(file_path)} resolution {raster_resolution}m does not meet target resolution {target_resolution}." + return out, msg + else: + return False, f"{os.path.basename} is not a geospatial raster" + + @task def get_source_rasters(source_list: list) -> SourceRasters: diff --git a/target_raster.py b/src/target_raster.py similarity index 86% rename from target_raster.py rename to src/target_raster.py index 2c37b26..7431809 100644 --- a/target_raster.py +++ b/src/target_raster.py @@ -12,31 +12,30 @@ except ModuleNotFoundError: from src.source_rasters import SourceRasters from src.windows import CombineWindow + @task def write_target_raster_chunk( - rw_window: CombineWindow, - destination: str, - max_value: int, - combi_dict: dict, - source_rasters: SourceRasters + rw_window: CombineWindow, + destination: str, + max_value: int, + combi_dict: dict, + source_rasters: SourceRasters, ): - """ - Write target raster for a single RW Window - """ + logger = prefect.context.get("logger") with rio.open( - destination, - "w", - driver="GTiff", - width=rw_window.rio_window.width, - height=rw_window.rio_window.height, - count=1, - dtype=rio.dtypes.get_minimum_dtype([0, max_value]), - transform=source_rasters.geospatial_profile["transform"], - compress="LZW", - crs=source_rasters.geospatial_profile["crs"], + f"{os.path.splitext(destination)[0]}_{rw_window.nr:05}.tif", + "w", + driver="GTiff", + width=rw_window.rio_window.width, + height=rw_window.rio_window.height, + count=1, + dtype=rio.dtypes.get_minimum_dtype([0, max_value]), + transform=rw_window.transform, + compress="LZW", + crs=source_rasters.geospatial_profile["crs"], ) as dest: dest.update_tags( creation_date=datetime.datetime.now().strftime("%d-%b-%Y_%H:%M:%S"), @@ -73,6 +72,7 @@ def write_target_raster_chunk( indexes=1, ) + logger.info(f"Writing chunk {rw_window.nr} out of {rw_window.total} to file.") @task diff --git a/src/windows.py b/src/windows.py new file mode 100644 index 0000000..2764858 --- /dev/null +++ b/src/windows.py @@ -0,0 +1,100 @@ +import random +import prefect +import affine +import numpy as np +import rasterio as rio +from prefect import task +from rasterio.windows import Window + +try: + from source_rasters import SourceRasters +except ModuleNotFoundError: + from src.source_rasters import SourceRasters + + +class CombineWindow: + """ + A single read/write window and its associated unique combinations + """ + + def __init__( + self, + row_start: int, + row_stop: int, + column_start: int, + column_stop: int, + nr: int, + totals: int, + top_left_x: int, + top_left_y: int, + resolution: int, + ): + self.rio_window = Window.from_slices( + (row_start, row_stop), (column_start, column_stop) + ) + self.unique_combinations = None + self.nr = nr + self.total = totals + + self.transform = affine.Affine( + a=resolution, b=0, c=top_left_x, d=0, e=resolution * -1, f=top_left_y + ) + + def set_unique_combinations(self, uc: set): + self.unique_combinations = uc + + def get_unique_combinations(self): + return self.unique_combinations + + +@task +def get_rw_windows( + source_rasters: SourceRasters, + window_height: int = 2000, + window_width: int = 2000, + sample: bool = False, +) -> list: + """ """ + + logger = prefect.context.get("logger") + + row_starts = range( + 0, (source_rasters.geospatial_profile["height"] - window_height), window_height + ) + column_starts = range( + 0, (source_rasters.geospatial_profile["width"] - window_width), window_width + ) + windows = [] + n = 0 + total_windows = np.multiply(len(row_starts), len(column_starts)) + for row_start in row_starts: + for column_start in column_starts: + windows.append( + CombineWindow( + row_start=row_start, + row_stop=row_start + window_height, + column_start=column_start, + column_stop=column_start + window_width, + nr=n, + totals=total_windows, + top_left_x=( + getattr(rio.open(source_rasters.source_list[0]), "transform") + * (column_start, row_start) + )[0], + top_left_y=( + getattr(rio.open(source_rasters.source_list[0]), "transform") + * (column_start, row_start) + )[1], + resolution=getattr( + getattr(rio.open(source_rasters.source_list[0]), "transform"), + "a", + ), + ) + ) + n += 1 + logger.info(f"Created {n} windows of size {window_height}X{window_width}") + + if sample: + return random.sample(windows, 20) + else: + return windows diff --git a/windows.py b/windows.py deleted file mode 100644 index 973c26f..0000000 --- a/windows.py +++ /dev/null @@ -1,77 +0,0 @@ -import random -import prefect -import affine -import rasterio as rio -from prefect import task -from rasterio.windows import Window - -try: - from source_rasters import SourceRasters -except ModuleNotFoundError: - from src.source_rasters import SourceRasters - - -class CombineWindow: - """ - A single read/write window and its associated unique combinations - """ - - def __init__(self, row_start: int, row_stop: int, column_start: int, column_stop: int, nr: int, - top_left_x: int, top_left_y: int, resolution: int): - self.rio_window = Window.from_slices( - (row_start, row_stop), (column_start, column_stop) - ) - self.unique_combinations = None - self.nr = nr - self.transform = affine.Affine(a=resolution, - b=0, - c=top_left_x, - d=0, - e=resolution*-1, - f=top_left_y) - - - def set_unique_combinations(self, uc: set): - self.unique_combinations = uc - - def get_unique_combinations(self): - return self.unique_combinations - - -@task -def get_rw_windows( - source_rasters: SourceRasters, - window_rows: int = 2000, - window_columns: int = 2000, - sample: bool = False, -) -> list: - - logger = prefect.context.get("logger") - - row_starts = range(0, (source_rasters.geospatial_profile['height'] - window_rows), window_rows) - column_starts = range(0, (source_rasters.geospatial_profile['width'] - window_columns), window_columns) - windows = [] - n = 0 - for row_start in row_starts: - for column_start in column_starts: - windows.append( - CombineWindow( - row_start=row_start, - row_stop=row_start + window_rows, - column_start=column_start, - column_stop=column_start + window_columns, - nr=n, - top_left_x=(getattr(rio.open(source_rasters.src_list[0]), 'transform') * (column_start, row_start))[0], - top_left_y=(getattr(rio.open(source_rasters.src_list[0]), 'transform') * (column_start, row_start))[1], - resolution=getattr(getattr(rio.open(source_rasters.src_list[0]), 'transform'), 'a'), - ) - ) - n += 1 - logger.info( - f"Created {n} windows of size {window_rows}X{window_columns}" - ) - - if sample: - return random.sample(windows, 20) - else: - return windows -- GitLab