12 if "km" in resolution:
13 resvalue =
float(resolution.strip(
'km')) * 1000.
14 elif "m" in resolution:
15 resvalue =
float(resolution.strip(
'm'))
16 elif "deg" in resolution:
17 resvalue =
float(resolution.strip(
'deg')) * 111312.
21 elif resvalue < 250.0:
23 elif resvalue < 500.0:
25 elif resvalue < 1150.0:
27 elif resvalue < 2300.0:
29 elif resvalue < 4600.0:
31 elif resvalue < 9200. :
37 rhot = {
'MODIS':
'rhot_645,rhot_555,rhot_469',
38 'SeaWiFS':
'rhot_670,rhot_555,rhot_412',
39 'OCTS':
'rhot_670,rhot_565,rhot_412',
40 'VIIRS':
'rhot_671,rhot_551,rhot_486',
41 'MERIS':
'rhot_665,rhot_560,rhot_412',
42 'OLCI':
'rhot_665,rhot_560,rhot_412',
43 'CZCS':
'rhot_670,rhot_550,rhot_443',
44 'OLI':
'rhot_655,rhot_561,rhot_442',
45 'HAWKEYE':
'rhot_670,rhot_556,rhot_447',
47 cmd =
' '.join([
'ncdump',
'-h', binfile,
'|',
'grep',
'instrument'])
48 result = subprocess.Popen(cmd, shell=
True,
49 stdout=subprocess.PIPE).communicate()[0]
51 sensor = (result.splitlines()[0]).decode().split(
'"')[1]
54 if __name__ ==
"__main__":
56 parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter,description=
'''\
57 This program takes a product_rgb (rhos by default) from a L1 file (or list of files), bins them
58 then maps the L2 binned file using a Plate Carree cylindrical projection,
59 and produces a faux-color png file.
61 The arguments can be specified on the commandline, or put into a parameter file,
62 or the two methods can be used together, with commandline over-riding.''',add_help=
True)
63 parser.add_argument(
'--parfile', type=str, help=
'input parameter file')
64 parser.add_argument(
'ifile', nargs=
'?', type=str, help=
'input file (L1A/B file or file with list)')
65 parser.add_argument(
'--geofile', nargs=
'?', type=str,help=
'input file geolocation file name')
66 parser.add_argument(
'--ofile', type=str, help=
'output file name; default = <ifile>.TC_MAP.<oformat extension>')
67 parser.add_argument(
'--product_rgb', type=str,help=
"3 products (e.g.,product_rgb=rhos_645,rhos_555,rhos_469) to use for RGB. Default is sensor specific")
68 parser.add_argument(
'--resolution', type=str, default=
'2.0km', help=
'''\
72 #.#: width of a pixel in meters
73 #.#km: width of a pixel in kilometers
74 integer value (e.g. 9km) will result in SMI nominal dimensions
75 (9km == 9.2km pixels, 4km == 4.6km pixels, etc.)
76 #.#deg: width of a pixel in degrees
78 parser.add_argument(
'--oformat', choices=[
'netcdf4',
'hdf4',
'png',
'ppm',
'tiff'], type=str, default=
"png", help=(
'''\
80 --------------------------------------------------------
81 netcdf4: netCDF4 file, can contain more than one product
82 hdf4: HDF4 file (old SMI format)
85 tiff: TIFF file with georeference tags
87 parser.add_argument(
'--north', type=float, help=(
'Northern most Latitude (-999=file north)'))
88 parser.add_argument(
'--south', type=float, help=(
'Southern most Latitude (-999=file south)'))
89 parser.add_argument(
'--east', type=float, help=(
'Eastern most Latitude (-999=file east)'))
90 parser.add_argument(
'--west', type=float, help=(
'Western most Latitude (-999=file west)'))
91 parser.add_argument(
'--projection', type=str,default=
'platecarree', help=
'''\
92 enter a proj.4 projection string or choose one of the following
93 predefined projections:
94 --------------------------------------------------------------
95 smi: Standard Mapped image, cylindrical projection, uses
96 central_meridian. n,s,e,w default to whole globe.
97 projection="+proj=eqc +lat_0=<central_meridian>"
98 platecarree: Plate Carree image, cylindrical projection, uses
100 projection="+proj=eqc +lat_0=<central_meridian>"
101 mollweide: Mollweide projection
102 projection="+proj=moll +lat_0=<central_meridian>"
103 lambert: Lambert conformal conic projection
104 projection="+proj=lcc +lat_0=<central_meridian>"
105 albersconic: Albers equal-area conic projection
106 projection="+proj=aea +lat_0=<central_meridian>"
107 mercator: Mercator cylindrical map projection
108 projection="+proj=merc +lat_0=<central_meridian>"
109 ease2: Ease Grid 2 projection
110 projection="+proj=cea +lon_0=0 +lat_ts=30 +ellps=WGS84
111 +datum=WGS84 +units=m +lat_0=<central_meridian>"
112 conus: USA Contiguous Albers Equal Area-Conic projection, USGS"
113 projection="+proj=aea +lat_1=29.5 +lat_2=45.5
114 +lat_0=23.0 +lon_0=-96 +x_0=0 +y_0=0
115 +ellps=GRS80 +datum=NAD83 +units=m +no_defs"
117 parser.add_argument(
'--central_meridian', type=float, help=
'central meridian for projection in deg east. Only used for smi, mollweide and raw projection')
118 parser.add_argument(
'--atmocor', action=
"store_true", help=
'apply Rayleigh correction')
119 parser.add_argument(
'--palfile', type=str, help=
'palette filename. Default uses file for product in product.xml')
120 parser.add_argument(
'--fudge', type=float,default=1.0, help=
'fudge factor used to modify size of L3 pixels')
121 parser.add_argument(
'--threshold', type=float,default=0, help=
'minimum percentage of filled pixels before an image is generated')
122 parser.add_argument(
'--keep-intermediates', action=
'store_true',default=
False, help=
'Do not delete the intermediate L2/L3B files produced')
123 parser.add_argument(
'-v',
'--verbose',action=
'count',default=0, help=
"Let's get chatty. Two -v's a better than one.")
125 args=parser.parse_args()
129 param_proc.parseParFile()
130 for param
in (param_proc.params[
'main'].keys()):
131 value = param_proc.params[
'main'][param]
132 if hasattr(args,param):
133 setattr(args,param,value)
134 elif param ==
'file':
138 parser.error(
"You must specify an input file either on the command line or in a parameter file")
141 extension = args.oformat
142 if extension ==
'netcdf4':
144 setattr(args,
'ofile',args.ifile +
'.TC_MAP.' + extension)
146 default_opts=[
"product_rgb",
"palfile",
"north",
"south",
"east",
"west",
"central_meridian"]
147 geo_opts = [
"north",
"south",
"east",
"west"]
148 l2bin_opts = [
"resolution"]
149 l3map_opts = [
"resolution",
"product_rgb",
"oformat",
"north",
"south",
"west",
"east",
"projection",
"central_meridian",
"palfile",
"fudge",
"threshold"]
150 tmpfile_l2gen =
"tmp.l2gen"
151 tmpfile_l2bin =
"tmp.l2bin"
158 if 'text' in MetaUtils.get_mime_data(args.ifile):
159 with open(args.ifile,
'r')
as lstfile:
160 ifiles = lstfile.readlines()
162 ifiles.append(args.ifile)
165 if 'text' in MetaUtils.get_mime_data(args.geofile):
166 with open(args.geofile,
'r')
as geolistfile:
167 geofiles = geolistfile.readlines()
169 geofiles.append(args.geofile)
170 if len(geofiles) != len(ifiles):
171 parser.error(
"Number of provided geofiles does not match number of provided ifiles...")
173 l2filelst = open(tmpfile_l2gen,
'w')
174 for i, l1file
in enumerate(ifiles):
177 l1file = l1file.strip()
179 clo.append(
'ifile='+l1file)
181 clo.append(
"geofile=" + geofiles[i])
183 ofile = tmpfile_l2gen +
'_'+
str(i)
184 clo.append(
"ofile"+
"="+ofile)
187 clo.append(
'l2prod=rhos_nnn')
189 clo.append(
'l2prod=rhot_nnn')
191 clo.append(
"atmocor=0")
192 for geo_opt
in geo_opts:
193 if getattr(args,geo_opt):
194 clo.append(geo_opt +
"=" +
str(getattr(args,geo_opt)))
197 print(
"l2gen parameters for %s:" % l1file)
202 subprocess.run(clo,check=
True)
204 subprocess.run(clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=
True)
206 print(
"Generated L2 file for input: %s" % l1file)
207 except subprocess.CalledProcessError
as e:
208 print(
"Process error ({0}): message:{1}".format(
str(e.returncode), e.output))
211 l2filelst.write(ofile+
'\n')
216 clo.append(
'flaguse=ATMFAIL,BOWTIEDEL')
217 clo.append(
'ifile=' + tmpfile_l2gen)
218 clo.append(
"ofile=" + tmpfile_l2bin)
219 clo.append(
"area_weighting=1")
220 for l2bin_opt
in l2bin_opts:
221 if getattr(args,l2bin_opt):
222 if l2bin_opt ==
'resolution':
223 clo.append(l2bin_opt +
"=" +
getBinRes(
str(getattr(args,l2bin_opt))))
225 clo.append(l2bin_opt +
"=" +
str(getattr(args,l2bin_opt)))
228 print(
"l2bin parameters:")
233 subprocess.run(clo,check=
True)
235 subprocess.run(clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=
True)
237 print(
"Generated bin file %s" % tmpfile_l2bin)
238 except subprocess.CalledProcessError
as e:
239 print(
"Process error ({0}): message:{1}".format(
str(e.returncode), e.output))
244 clo.append(
'ifile=' + tmpfile_l2bin)
245 clo.append(
'ofile=' + args.ofile)
246 clo.append(
'interp=nearest')
247 clo.append(
'use_rgb=1')
248 for opt
in l3map_opts:
249 if opt ==
'product_rgb':
250 if not getattr(args,
'atmocor'):
251 clo.append(
'product_rgb=' +
get_rhots(tmpfile_l2bin))
252 elif getattr(args,opt):
253 if type(getattr(args,opt))
is bool:
254 clo.append(opt +
"=1" )
256 clo.append(opt +
"=" +
str(getattr(args,opt)))
259 print(
"l3mapgen parameters:")
263 subprocess.run(clo,check=
True)
265 subprocess.run(clo,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,check=
True)
267 print(
"Generated map file: %s" % args.ofile)
268 except subprocess.CalledProcessError
as e:
269 print(
"Process error ({0}): message:{1}".format(
str(e.returncode), e.output))
272 if not args.keep_intermediates:
273 for f
in [tmpfile_l2bin,tmpfile_l2gen]:
274 if f == tmpfile_l2gen:
275 l2filelst = open(tmpfile_l2gen,
'r')
276 for l2f
in l2filelst.readlines():
279 print(
"removing: " + l2f)
282 print(
"removing: " + f)