diff --git a/TimeSeries/planet_mosaics.py b/TimeSeries/planet_mosaics.py index ce8cb236b5915a60e9ad7a92c5dd9be06214ef95..8d0563f6685a7c23b58d53068485691af7c7f843 100644 --- a/TimeSeries/planet_mosaics.py +++ b/TimeSeries/planet_mosaics.py @@ -8,6 +8,8 @@ from tqdm import tqdm import urllib.request from datetime import datetime from dateutil.relativedelta import * +import uuid +import glob def fetch(shp, dt, out_fld, api_key): ds = ogr.Open(shp) @@ -80,21 +82,12 @@ def fetch(shp, dt, out_fld, api_key): return - - - - - - - -''' -class PlanetMosaicQuadPipeline: +class PlanetMosaicPipeline: # --- BEGIN SENSOR PROTOTYPE --- NAME = 'PLANET-MOSAICS' REF_TYPE = otb.ImagePixelType_uint16 - PTRN_dir = '*' - PTRN_ref = '*' + PTRN_name = 'PlanetMosaic_*.tif' FEAT_exp = { 'B': 'im1b1', 'G': 'im1b2', @@ -104,119 +97,83 @@ class PlanetMosaicQuadPipeline: } NDT = 0 + # ---- END SENSOR PROTOTYPE ---- + @classmethod def _check(cls,x): - return cls.PTRN_dir.split('_')[-1].replace('*', '') in os.path.basename(x) + return (cls.PTRN_name.split('*')[0] in os.path.basename(x) and + cls.PTRN_name.split('*')[1] in os.path.basename(x)) @classmethod def _img_id(cls,x): if cls._check(x): - if os.path.isdir(x) or os.path.splitext(x)[-1] == '.zip': - return '_'.join(os.path.splitext(x)[0].split('_')[-5:]) - else: - return None + return os.path.splitext(os.path.basename(x)) else: return None @classmethod def _img_date(cls,x): if cls._check(x): - if os.path.isdir(x) or os.path.splitext(x)[-1] == '.zip': - return os.path.splitext(x)[0].split('_')[-5].split('T')[0] - else: - return None + return os.path.splitext(os.path.basename(x))[0].split('_')[-1] else: return None - - @classmethod - def _tile_id(cls,x): - if cls._check(x): - if os.path.isdir(x) or os.path.splitext(x)[-1] == '.zip': - return os.path.splitext(x)[0].split('_')[-2] - else: - return None - else: - return None - - @classmethod - def _tile_cloud_percentage(cls, x): - if cls._check(x): - if os.path.isdir(x): - fid = open(glob.glob(os.path.join(x, '*/*/MTD_TL.xml'))[0], 'r') - mtd = fid.read() - elif os.path.splitext(x)[-1] == '.zip': - arch = zipfile.ZipFile(x) - fid = [name for name in arch.namelist() if name.endswith('MTD_TL.xml')] - mtd = arch.read(fid[0]) - root = et.fromstring(mtd) - f = filter(lambda x: x.tag == "CLOUDY_PIXEL_PERCENTAGE", root.findall('*/*/*')) - r = list(f) - return float(r[0].text) - - """ - def _process_mask(self, msks): - msk_pipe = [otb.Registry.CreateApplication('Superimpose')] - msk_pipe[-1].SetParameterInputImage('inr', self.pipe[-1].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterInputImage('inm', msks[0].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('interpolator', 'nn') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BandMath')) - msk_pipe[-1].AddImageToParameterInputImageList('il', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('exp', 'im1b1==0 || im1b1==1 || im1b1==2 || im1b1==7 ||im1b1==3 || im1b1==8 || im1b1==9 || im1b1==10') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BinaryMorphologicalOperation')) - msk_pipe[-1].SetParameterInputImage('in', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('filter', 'erode') - msk_pipe[-1].SetParameterString('structype', 'ball') - msk_pipe[-1].SetParameterString('xradius', '5') - msk_pipe[-1].SetParameterString('yradius', '5') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BinaryMorphologicalOperation')) - msk_pipe[-1].SetParameterInputImage('in', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('filter', 'dilate') - msk_pipe[-1].SetParameterString('structype', 'ball') - msk_pipe[-1].SetParameterString('xradius', '20') - msk_pipe[-1].SetParameterString('yradius', '20') - msk_pipe[-1].Execute() - return msk_pipe - """ - - def _process_mask(self, msks): - msk_pipe = [otb.Registry.CreateApplication('BandMath')] - msk_pipe[-1].AddImageToParameterInputImageList('il', msks[0].GetParameterOutputImage('out')) - # excluding thin cirrus from masking : no im1b1 == 10 below - # excluding cloud shadows here (for opening) : no im1b1 == 3 below - msk_pipe[-1].SetParameterString('exp', 'im1b1==0 || im1b1==1 || im1b1==8 || im1b1==9') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BandMath')) - msk_pipe[-1].AddImageToParameterInputImageList('il', msks[0].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('exp', 'im1b1==2 || im1b1 == 3 || im1b1==7') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BinaryMorphologicalOperation')) - msk_pipe[-1].SetParameterInputImage('in', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('filter', 'opening') - msk_pipe[-1].SetParameterString('structype', 'ball') - msk_pipe[-1].SetParameterString('xradius', '5') - msk_pipe[-1].SetParameterString('yradius', '5') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BandMath')) - msk_pipe[-1].AddImageToParameterInputImageList('il', msk_pipe[-4].GetParameterOutputImage('out')) - msk_pipe[-1].AddImageToParameterInputImageList('il', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('exp', 'im1b1 || im2b1') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('BinaryMorphologicalOperation')) - msk_pipe[-1].SetParameterInputImage('in', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('filter', 'dilate') - msk_pipe[-1].SetParameterString('structype', 'ball') - msk_pipe[-1].SetParameterString('xradius', '20') - msk_pipe[-1].SetParameterString('yradius', '20') - msk_pipe[-1].Execute() - msk_pipe.append(otb.Registry.CreateApplication('Superimpose')) - msk_pipe[-1].SetParameterInputImage('inr', self.pipe[-1].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterInputImage('inm', msk_pipe[-2].GetParameterOutputImage('out')) - msk_pipe[-1].SetParameterString('interpolator', 'nn') - msk_pipe[-1].Execute() - return msk_pipe - - # ---- END SENSOR PROTOTYPE ---- -''' \ No newline at end of file + def __init__(self, fld, input_date_interval=None): + self.pipe = [] + self.files = [] + self.types = [] + self.out_p = [] + self.out_idx = [] + + self.id = str(uuid.uuid4()) + self.folder = os.path.abspath(fld) + self.image_list = self.parse_folder(self.folder) + self.input_dates = [self._img_date(x) for x in self.image_list] + + if input_date_interval is not None: + idx = [i for i in range(len(self.input_dates)) if + input_date_interval[0] <= self.input_dates[i] <= input_date_interval[1]] + self.image_list = [self.image_list[i] for i in idx] + self.input_dates = [self.input_dates[i] for i in idx] + + for img in self.image_list: + self.append(to_otb_pipeline(img), os.path.basename(img), self.REF_TYPE, 'out', is_output=True) + + def __del__(self): + return + + def parse_folder(self, fld): + img_list = [os.path.abspath(x) for x in glob.glob(os.path.join(fld, self.PTRN_dir))] + return sorted(img_list, key=lambda x: self._img_id(x)) + + def compute_features(self, feat_list=['B', 'G', 'R', 'NIR', 'NDVI']): + proc_idx = self.out_idx.copy() + self.out_idx = [] + for k in range(len(proc_idx)): + bm = otb.Registry.CreateApplication('BandMathX') + expr = [] + for f in feat_list: + expr.append(self.FEAT_exp[f]) + expr = '{' + ';'.join(expr) + '}' + bm.SetParameterString('exp', expr) + bm.Execute() + fn = self.files[proc_idx[k]].replace('.tif', '_FEAT.tif') + self.append(bm, fn, self.REF_TYPE, 'out', is_output=True) + + def write_outputs(self, fld, update_pipe=False, compress=False): + out = [] + proc_idx = self.out_idx.copy() + if update_pipe: + self.out_idx = [] + for t in proc_idx: + out_file = os.path.join(fld, self.files[t]) + if compress: + out_file += '?gdal:co:compress=deflate' + if not os.path.exists(os.path.dirname(out_file)): + os.makedirs(os.path.dirname(out_file)) + self.pipe[t].SetParameterString(self.out_p[t], out_file) + self.pipe[t].SetParameterOutputImagePixelType(self.out_p[t], self.types[t]) + self.pipe[t].ExecuteAndWriteOutput() + out.append(out_file) + if update_pipe: + self.append(to_otb_pipeline(out_file), self.files[t], self.types[t], 'out', is_output=True) + return out diff --git a/TimeSeries/s1base.py b/TimeSeries/s1base.py index 22f897513d94957e565d28f8030575a267dd464d..3a53d80936f37c59660546bb6e045536a4abf95e 100644 --- a/TimeSeries/s1base.py +++ b/TimeSeries/s1base.py @@ -113,7 +113,6 @@ class S1GRDPipeline: shutil.rmtree(self.temp_fld) def parse_folder(self, fld, roi_min_surf=0.0): - print(glob.glob(os.path.join(fld, self.PTRN_dir))) img_list = [os.path.abspath(x) for x in glob.glob(os.path.join(fld, self.PTRN_dir)) if os.path.isdir(x) and self._check_roi(x, self.roi, roi_min_surf)]