2222import shutil
2323import string
2424import boto3
25+ import zarr
2526from botocore .exceptions import ClientError , NoCredentialsError
2627from pathlib import Path
2728from datetime import datetime
5657""" )
5758
5859
60+ def zarr2tiff (input_file , config , process_existing = False , limit = - 1 , create_cog = False ):
61+ output_files = []
62+ counter = 0
63+ vars = config .vars .copy ()
64+ zarr_dataset = zarr .open (input_file , mode = 'r' )
65+ time_data = zarr_dataset ['time' ]
66+ if 's3://' in input_file :
67+ input_file = input_file .replace ('s3://' , '' )
68+ # check if we need to reproject
69+ if config .s_srs :
70+ projection = config .s_srs
71+ config .reproject = '<target_epsg>4326</target_epsg>' + \
72+ '<source_epsg>' + projection .split (':' )[1 ] + '</source_epsg>'
73+ else :
74+ projection = config .t_srs
75+ config .reproject = ''
76+
77+ counter += 1
78+ for idx , time in enumerate (time_data ):
79+ if time != '' :
80+ datestring = '_' + datetime .fromtimestamp (time ).strftime ("%Y%m%d" )
81+ else :
82+ datestring = ''
83+ for var in vars :
84+ output_file = str (Path (config .working_dir ).absolute ()) \
85+ + '/' + str (Path (input_file ).stem ) + '_' + var + datestring + '.tiff'
86+ print ('Creating GeoTIFF file ' + output_file )
87+
88+ if not os .path .isfile (output_file ):
89+ extents = config .extents .split (',' )
90+ gdal_translate = ['gdal_translate' , '-of' , 'GTiff' , '-a_srs' , projection , '-a_ullr' ,
91+ extents [0 ], extents [3 ], extents [2 ], extents [1 ]]
92+ if hasattr (config , 'nodata' ):
93+ gdal_translate .append ('-a_nodata' )
94+ gdal_translate .append (str (config .nodata ))
95+ gdal_translate .append ('ZARR:"/vsis3/' + input_file + '":/' + var + ':' + str (idx ))
96+ gdal_translate .append (output_file )
97+ print (gdal_translate )
98+ process = subprocess .Popen (gdal_translate , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
99+ process .wait ()
100+ for output in process .stdout :
101+ print (output .decode ())
102+ for error in process .stderr :
103+ print (error .decode ())
104+ print ('Created GeoTIFF ' + output_file )
105+
106+ if config .is360 :
107+ print ('Converting coordinates from 0 - 360 to -180 - 180' )
108+ output_file_360 = output_file .replace ('.tiff' , '_360.tiff' )
109+ print ('Creating GeoTIFF file ' + output_file_360 )
110+ gdal_warp = ['gdalwarp' , '-t_srs' , 'WGS84' , '-te' , '-180' , '-90' , '180' , '90' , output_file ,
111+ output_file_360 , '-wo' , 'SOURCE_EXTRA=1000' , '--config' , 'CENTER_LONG' , '0' ]
112+ print (gdal_warp )
113+ process = subprocess .Popen (gdal_warp , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
114+ process .wait ()
115+ for output in process .stdout :
116+ print (output .decode ())
117+ for error in process .stderr :
118+ print (error .decode ())
119+ print ('Created GeoTIFF ' + output_file_360 )
120+ shutil .move (output_file_360 , output_file )
121+ print ('Replaced ' + output_file )
122+
123+ if create_cog :
124+ cog_file = str (Path (config .working_dir ).absolute ()) \
125+ + '/' + str (Path (input_file ).stem ) + '_' + var + '.cog.tiff'
126+ print ('Creating Cloud-Optimized GeoTIFF file ' + cog_file )
127+ gdal_translate = ['gdal_translate' , '-of' , 'COG' , '-co' , 'COMPRESS=LZW' , output_file , cog_file ]
128+ print (gdal_translate )
129+ process = subprocess .Popen (gdal_translate , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
130+ process .wait ()
131+ for output in process .stdout :
132+ print (output .decode ())
133+ for error in process .stderr :
134+ print (error .decode ())
135+ print ('Created GeoTIFF ' + cog_file )
136+
137+ if config .empty_tile_prefix is not None :
138+ empty_tile = config .empty_tile_prefix + '_' + var + '.png'
139+ else :
140+ empty_tile = config .empty_tile
141+
142+ if config .colormap_prefix is not None :
143+ print ('Coloring ' + output_file )
144+ colormap = f'{ config .colormap_prefix } _{ var } .txt'
145+ colormap_xml = f'{ config .colormap_prefix } _{ var } .xml'
146+ output_file_colored = str (Path (config .working_dir ).absolute ()) \
147+ + '/' + str (Path (input_file ).stem ) + '_' + var + datestring + '_.tiff'
148+ if process_existing or not os .path .isfile (output_file_colored ):
149+ print (f'Using colormap:{ colormap } ' )
150+ gdaldem_command_list = ['gdaldem' , 'color-relief' , '-alpha' , '-nearest_color_entry' ,
151+ output_file , colormap , output_file_colored ]
152+ process = subprocess .Popen (gdaldem_command_list , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
153+ process .wait ()
154+ for output in process .stdout :
155+ print (output .decode ())
156+ for error in process .stderr :
157+ print (error .decode ())
158+ if process .returncode == 0 : # delete if there are no errors
159+ print ('Created GeoTIFF ' + output_file_colored )
160+ try :
161+ print ('Deleting file ' + output_file )
162+ os .remove (output_file )
163+ except FileNotFoundError as ex :
164+ print (ex )
165+ output_files .append (output_file_colored )
166+ create_mrf ([output_file_colored ], config , config .layer_prefix + '_' + var , colormap_xml , empty_tile )
167+ else :
168+ output_files .append (output_file )
169+ create_mrf ([output_file ], config , config .layer_prefix + '_' + var , colormap_xml , empty_tile )
170+
171+ return output_files
172+
173+
59174def nc2tiff (input_file , config , process_existing = False , limit = - 1 , create_cog = False ):
60175 output_files = []
61176 counter = 0
@@ -71,7 +186,7 @@ def nc2tiff(input_file, config, process_existing=False, limit=-1, create_cog=Fal
71186 for input_file in input_files :
72187 skip_file = str (Path (input_file ).absolute ().parent ) + '/' + str (Path (input_file ).stem ) + '.skip'
73188 # skip file if it has already been processed
74- if (os .path .isfile (skip_file ) and process_existing is False ) or (counter > limit and limit is not - 1 ):
189+ if (os .path .isfile (skip_file ) and process_existing is False ) or (counter > limit and limit != - 1 ):
75190 print (f'Skipping { input_file } ' )
76191 continue
77192 vars = config .vars .copy ()
@@ -395,4 +510,8 @@ def create_mrf(input_files, config, layer_name, colormap, empty_tile):
395510 print (f'\n Using { args .config } \n ' )
396511 print (config )
397512
398- nc2tiff (args .input_file , args .config , args .process_existing , args .limit , args .create_cog )
513+ if str (args .input_file ).endswith ('.zarr' ):
514+ print ('zarr detected' )
515+ zarr2tiff (args .input_file , args .config , args .process_existing , args .limit , args .create_cog )
516+ else :
517+ nc2tiff (args .input_file , args .config , args .process_existing , args .limit , args .create_cog )
0 commit comments