[GRASS-SVN] r72816 - grass-addons/grass7/imagery/i.sentinel.mask

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jun 13 08:06:30 PDT 2018


Author: Robifag
Date: 2018-06-13 08:06:30 -0700 (Wed, 13 Jun 2018)
New Revision: 72816

Added:
   grass-addons/grass7/imagery/i.sentinel.mask/Makefile
   grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.html
   grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.py
   grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png
   grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png
   grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png
   grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png
Log:
Add the first version of i.sentinel.mask module

Added: grass-addons/grass7/imagery/i.sentinel.mask/Makefile
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/Makefile	                        (rev 0)
+++ grass-addons/grass7/imagery/i.sentinel.mask/Makefile	2018-06-13 15:06:30 UTC (rev 72816)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = i.sentinel.mask
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script

Added: grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.html
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.html	                        (rev 0)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.html	2018-06-13 15:06:30 UTC (rev 72816)
@@ -0,0 +1,94 @@
+<h2>DESCRIPTION</h2>
+<em>i.sentinel.mask</em> allows to automatically identify clouds and their shadows in Sentinel 2 images. 
+<p>
+The implemented procedure consists essentially of values thresholds, comparisons and calculations between bands and they lead to two different 
+rough maps of clouds and shadows which require further improvements and elaborations (e.g. transformation from raster to vector, cleaning geometries,
+ removing small areas, checking topology, etc.) carried out in the different steps of the procedure. 
+
+<table cellspacing="2" cellpadding="2" width="100%" border="0">
+	<tbody>
+		<tr>
+		<td align="center" valign="bottom"><a href="i_sentinel_mask_GWF.png"><img src="i_sentinel_mask_GWF.png" width="100%"></a><br><i>Fig: Module General WorkFlow</i></td>
+		<td align="center" valign="bottom"><a href="i_sentinel_mask_CD.png"><img src="i_sentinel_mask_CD.png" width="100%"></a><br><i>Fig: Cloud detection procedure</i></td>
+		<td align="center" valign="bottom"><a href="i_sentinel_mask_SD.png"><img src="i_sentinel_mask_SD.png" width="100%"></a><br><i>Fig: Shadow detection procedure</i></td>
+		</tr>
+	</tbody>
+</table>
+
+<p>
+The algorithm has been developed starting from rules found in literature (Parmes et. al 2017) and conveniently refined.<br>
+Regarding the detection of shadows, some misclassification can occur. Often shadows and water have in fact similar reflectance 
+values which can lead to erroneous classification of water bodies as shadows. Therefore, in order to increase the accuracy of 
+the final shadow mask, a control check is implemented. Clouds and shadows are spatially intersected in order to remove misclassified areas. 
+This means that all those shadow geometries which do not intersect a cloud geometry are removed.
+
+<div align="center" style="margin: 10px">
+<a href="i_sentinel_mask_CS.png">
+<img src="i_sentinel_mask_CS.png" width="30%">
+</a><br>
+<i>Fig: Module General WorkFlow</i>
+</div>
+<!--center>
+<img src="i_sentinel_mask_CS.png" width="30%">
+<br>
+<i>Fig: Module General WorkFlow</i>
+</center-->
+
+<p>
+All necessary input bands (blue, green, red, nir, nir8a, swir11, swir12) must be imported in GRASS and specified one by one or using a text file.
+The text file has to be written following the syntax below: <em>variable=your_map</em>
+
+<div class="code"><pre>
+blue=<em>your_blue_map</em>
+green=<em>your_green_map</em>
+red=<em>your_red_map</em>
+nir=<em>your_nir_map</em>
+nir8a=<em>your_nir8a_map</em>
+swir11=<em>your_swir11_map</em>
+swir12=<em>your_swir12_map</em>
+</pre></div>
+
+Tha variables names (blue, green, red, nir, nir8a, swir11, swir12) have to be written precisely like in the example above (e.g. not Blue, nor BLUE but blue), 
+no spaces or special characters are permitted.
+
+<p>
+The final outputs are two different vector maps, one for clouds and one for shadows.
+<p>
+The metadata file (MTD_TL.xml) is required only if both masks (cloud and shadow)
+are computed. The module retrieves from this file the sun azimuth and zenith necessary for the shadow mask cleaning phase 
+<em>(see the schema above)</em>
+<p>
+If flag <b>-s</b> is given all selected bands are rescaled using the specified scale factor [<b>scale_fac</b>=<em>integer</em>]. By default the scale factor is set to 10000, 
+the QUANTIFICATION_VALUE from the metadata of Sentinel 2 images.
+<p>
+The module takes the current region settings into accout. To ignore the current region and set it from the whole image, the flag <b>-r</b> has to be given.
+<p>
+The module allows to compute only the cloud mask or both cloud and shadow masks. If flag <b>-c</b> is given, only the cloud procedure will be performed. The computation 
+of cloud mask is mandatory for shadow mask creation. In fact cloud map is used during the cleaning phase of the shadow mask in order to remove misclassifications.
+
+<h2>EXAMPLE</h2>
+<div class="code">
+i.sentinel.mask -r -s input_file=/home/input_bands.txt cloud_mask=cloud_sen2 shadow_mask=shadow_sen2 mtd_file=/home/MTD_TL.xml scale_fac=1000
+</div>
+<p>
+-r to set the computational region to the maximum image extente and -s to rescale the input bands with the specified scale factor (in this case 1000)
+
+<h2>REFERENCE</h2>
+<ul>
+<li>Parmes et. al 2017</li>
+</ul>
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a href="i.sentinel.download.html">i.sentinel.download</a>,
+<a href="i.sentinel.import.html">i.sentinel.import</a>,
+<a href="r.import.html">r.import</a>,
+<a href="r.extenal.html">r.external</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Roberta Fagandini, GSoC 2018 student<br>
+<a href="https://wiki.osgeo.org/wiki/User:Mlennert">Moritz Lennert</a><br> 
+<a href="https://wiki.osgeo.org/wiki/User:Robertomarzocchi">Roberto Marzocchi</a>

Added: grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.py
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.py	                        (rev 0)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i.sentinel.mask.py	2018-06-13 15:06:30 UTC (rev 72816)
@@ -0,0 +1,549 @@
+#!/usr/bin/env python 
+# coding=utf-8
+#
+############################################################################
+#
+# MODULE:    i.sentinel.mask
+# AUTHOR(S):    Roberta Fagandini, Moritz Lennert, Roberto Marzocchi
+# PURPOSE:    Creates clouds and shadows masks for Sentinel-2 images
+#
+# COPYRIGHT:    (C) 2018 by the GRASS Development Team
+#
+#        This program is free software under the GNU General Public
+#        License (>=v2). Read the file COPYING that comes with GRASS
+#        for details.
+#
+#############################################################################
+
+#%Module
+#% description: Creates clouds and shadows masks for Sentinel-2 images
+#% keywords: imagery
+#% keywords: sentinel 
+#% keywords: cloud detection
+#% keywords: shadow
+#% keywords: reflectance
+#%End
+#%option
+#% key: input_file
+#% type: string
+#% gisprompt: old,file,file
+#% description: name of the .txt file with listed input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: blue
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: green
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: red
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: nir
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: nir8a
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: swir11
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option
+#% key: swir12
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input bands
+#% required : no
+#% multiple: no
+#% guisection: Required
+#%end
+#%option 
+#% key: cloud_mask
+#% type: string
+#% gisprompt: new,vector,vector
+#% description: name of output vector cloud mask
+#% required : yes
+#% guisection: Output
+#%end
+#%option 
+#% key: shadow_mask
+#% type: string
+#% gisprompt: new,vector,vector
+#% description: name of output vector shadow mask
+#% required : no
+#% guisection: Output
+#%end
+#%option
+#% key: mtd_file
+#% type: string
+#% gisprompt: old,file,file
+#% description: name of the image metadata file (MTD_TL.xml)
+#% required : no
+#% multiple: no
+#% guisection: Metadata
+#%end
+#%option
+#% key: scale_fac
+#% type: integer
+#% description: rescale factor
+#% required : no
+#% answer: 10000
+#% guisection: Rescale
+#%end
+#%flag
+#% key: r
+#% description: Set computational region to maximum image extent
+#%end
+#%flag
+#% key: t
+#% description: Do not delete temporary files
+#%end
+#%flag
+#% key: s
+#% description: Rescale input bands
+#% guisection: Rescale
+#%end
+#%flag
+#% key: c
+#% description: Compute only the cloud mask
+#%end
+
+import grass.script as gscript
+import math
+import os
+import sys
+import shutil
+import re
+import glob
+import numpy
+import time
+import atexit
+import xml.etree.ElementTree as et
+
+
+def main ():
+
+
+    #import bands atmospherically corrected using arcsi (scale factor 1000 instead of 10000)
+    #############################################
+    # INPUT
+    #############################################
+    #temporary map names
+    global tmp, t, mapset
+    tmp = {}
+    mapset = gscript.gisenv()['MAPSET']
+    mapset2 = '@{}'.format(mapset)
+    processid = os.getpid()
+    processid = str(processid)
+    tmp["cloud_def"] = "cloud_def"+ processid
+    tmp["shadow_temp"] = "shadow_temp"+ processid
+    tmp["cloud_v"] = "cloud_v_" + processid
+    tmp["shadow_temp_v"] = "shadow_temp_v_" + processid
+    tmp["shadow_temp_mask"] = "shadow_temp_mask_" + processid
+    tmp["centroid"] = "centroid_" + processid
+    tmp["dissolve"] = "dissolve_" + processid
+    tmp["delcat"] = "delcat_" + processid
+    tmp["addcat"] = "addcat_" + processid
+    tmp["cl_shift"] = "cl_shift_" + processid
+    tmp["overlay"] = "overlay_" + processid
+    
+    #check temporary map names are not existing maps
+    for key, value in tmp.items():
+        if gscript.find_file(value,
+            element = 'vector',
+            mapset = mapset)['file']:
+                gscript.fatal(("Temporary vector map <{}> already exists.").format(value))
+        if gscript.find_file(value,
+            element = 'cell',
+            mapset = mapset)['file']:
+                gscript.fatal(("Temporary raster map <{}> already exists.").format(value))
+
+    #input file
+    mtd_file = options['mtd_file']
+    bands = {} 
+    if options['input_file']=='':
+        bands['blue'] = options['blue']
+        bands['green'] = options['green']
+        bands['red'] = options['red']
+        bands['nir'] = options['nir']
+        bands['nir8a'] = options['nir8a']
+        bands['swir11'] = options['swir11']
+        bands['swir12'] = options['swir12']
+    else:
+        input_file = options['input_file']
+        for line in file(input_file):
+            a = line.split('=')
+            if len(a) != 2 or a[0] not in ['blue', 'green', 'red', 'nir', 'nir8a', 'swir11', 'swir12' ]:
+                gscript.fatal("Syntax error in the txt file. See the manual for further information about the right syntax.")
+            a[1] = a[1].strip()
+            bands[a[0]] = a[1]
+    d = 'double'
+    f_bands = {}
+    scale_fac = options['scale_fac']
+    cloud_clean_T = 50000
+    shadow_clean_T = 10000
+    raster_max = {}
+    cloud_mask = options['cloud_mask']
+    shadow_mask = options['shadow_mask']
+
+    if bands['blue'] == '' or bands['green'] == '' or bands['red'] == '' or bands['nir'] == '' or bands['nir8a'] == '' or bands['swir11'] == '' or bands['swir12'] == '':
+        gscript.fatal(("All input bands (blue, green, red, nir, nir8a, swir11, swir12) are required"))
+
+    for key, value in bands.items():
+        if not gscript.find_file(value,
+            element = 'cell',
+            mapset = mapset)['file']:
+                gscript.fatal(("Raster map <{}> not found.").format(value))
+
+    if not flags["c"]:
+        if options['mtd_file']== '':
+            gscript.fatal("Metadata file is required for shadow mask computation. Please specified it")
+        if options['shadow_mask']=='':
+            gscript.fatal("Output name is required for shadow mask. Please specified it")
+
+    if flags["r"]:
+        gscript.use_temp_region()
+        gscript.run_command('g.region',
+            rast=bands.values(),
+            flags='a')
+        gscript.message(_("--- The computational region has been temporarily set to image max extent ---"))
+    else:
+        gscript.warning(_("All subsequent operations will be limited to the current computational region"))
+
+    if flags["s"]:
+        gscript.message(_('--- Start rescaling bands ---'))
+        for key, b in bands.items():
+            gscript.message(_(b))
+            b = gscript.find_file(b, element = 'cell')['name']
+            gscript.mapcalc('{r} = 1.0 * ({b})/{scale_fac}'.format(
+                r=("{}_{}".format(b, d)),
+                b=b,
+                scale_fac=scale_fac))
+            f_bands[key] = "{}_{}".format(b, d)
+        gscript.message(_(f_bands.values()))
+        gscript.message(_('--- All bands have been rescaled ---'))
+    else:
+        gscript.warning(_('Any rescale factor has been applied'))
+        for key, b in bands.items():
+            if gscript.raster_info(b)['datatype'] != "DCELL":
+                gscript.fatal("Raster maps must be double")
+            else:
+                f_bands = bands
+
+    gscript.message(_('--- Start computing maximum values of bands ---'))
+    for key, fb in f_bands.items():
+        gscript.message(_(fb))
+        stats = gscript.parse_command('r.univar', flags='g', map=fb)
+        raster_max[key] = (float(stats['max']))
+    gscript.message(_('--- Computed maximum value: {} ---'.format(raster_max.values())))
+    gscript.message(_('--- Statistics have been computed! ---'))
+
+    #### start of Clouds detection  (some rules from litterature)###
+    gscript.message(_('--- Start clouds detection procedure ---'))
+    gscript.message(_('--- Computing cloud mask... ---'))
+    first_rule = '(({} > (0.08*{})) && ({} > (0.08*{})) && ({} > (0.08*{})))'.format(
+        f_bands['blue'],
+        raster_max['blue'],
+        f_bands['green'],
+        raster_max['green'],
+        f_bands['red'],
+        raster_max['red'])
+    second_rule = '(({} < ((0.08*{})*1.5)) && ({} > {}*1.3))'.format(
+        f_bands['red'],
+        raster_max['red'],
+        f_bands['red'],
+        f_bands['swir12'])
+    third_rule = '(({} < (0.1*{})) && ({} < (0.1*{})))'.format(
+        f_bands['swir11'],
+        raster_max['swir11'],
+        f_bands['swir12'],
+        raster_max['swir12'])
+    fourth_rule = '(if({} == max({}, 2 * {}, 2 * {}, 2 * {})))'.format(
+        f_bands['nir8a'],
+        f_bands['nir8a'],
+        f_bands['blue'],
+        f_bands['green'],
+        f_bands['red'])
+    fifth_rule = '({} > 0.2)'.format(f_bands['blue'])
+    cloud_rules = '({} == 1) && ({} == 0) && ({} == 0) && ({} == 0) && ({} == 1)'.format(
+        first_rule,
+        second_rule,
+        third_rule,
+        fourth_rule,
+        fifth_rule)
+    expr_c = '{} = if({}, 0, null( ))'.format(
+        tmp["cloud_def"],
+        cloud_rules)
+    gscript.mapcalc(expr_c, overwrite=True)
+    gscript.message(_('--- Converting raster cloud mask into vector map ---'))
+    gscript.run_command('r.to.vect',
+        input=tmp["cloud_def"],
+        output=tmp["cloud_v"],
+        type='area',
+        flags='s')
+    gscript.message(_('--- Cleaning geometries ---'))
+    gscript.run_command('v.clean',
+        input=tmp["cloud_v"],
+        output=cloud_mask,
+        tool='rmarea',
+        threshold=cloud_clean_T)
+    gscript.message(_('--- Finish cloud detection procedure ---'))
+    ### end of Clouds detection ####
+
+    if not flags["c"]:
+        ### start of shadows detection ###
+        gscript.message(_('--- Start shadows detection procedure ---'))
+        gscript.message(_('--- Computing shadow mask... ---'))
+        sixth_rule = '((({} > {}) && ({} < {}) && ({} < 0.1) && ({} < 0.1)) \
+        || (({} < {}) && ({} < {}) && ({} < 0.1) && ({} < 0.1) && ({} < 0.1)))'.format(
+            f_bands['blue'],
+            f_bands['swir12'],
+            f_bands['blue'],
+            f_bands['nir'],
+            f_bands['blue'],
+            f_bands['swir12'],
+            f_bands['blue'],
+            f_bands['swir12'],
+            f_bands['blue'],
+            f_bands['nir'],
+            f_bands['blue'],
+            f_bands['swir12'],
+            f_bands['nir'])
+        seventh_rule = '({} - {})'.format(
+            f_bands['green'],
+            f_bands['blue'])
+        shadow_rules = '(({} == 1) && ({} < 0.007))'.format(
+            sixth_rule, 
+            seventh_rule)
+        expr_s = '{} = if({}, 0, null( ))'.format(
+            tmp["shadow_temp"],
+            shadow_rules)
+        gscript.mapcalc( expr_s, overwrite=True)
+        gscript.message(_('--- Converting raster shadow mask into vector map ---'))
+        gscript.run_command('r.to.vect',
+            input=tmp["shadow_temp"],
+            output=tmp["shadow_temp_v"],
+            type='area',
+            flags='s',
+            overwrite=True)
+        gscript.message(_('--- Cleaning geometries ---'))
+        gscript.run_command('v.clean',
+            input=tmp["shadow_temp_v"],
+            output=tmp["shadow_temp_mask"],
+            tool='rmarea',
+            threshold=shadow_clean_T)
+        gscript.message(_('--- Finish Shadows detection procedure ---'))
+        ### end of shadows detection ###
+
+        #####################################################################
+        # START shadows cleaning Procedure (remove shadows misclassification)
+        #####################################################################
+        ### start shadow mask preparation ###
+
+        gscript.message(_('--- Start removing misclassification from the shadow mask ---'))
+        gscript.message(_('--- Data preparation... ---'))
+        gscript.run_command('v.centroids',
+            input=tmp["shadow_temp_mask"],
+            output=tmp["centroid"],
+            quiet=True)
+        gscript.run_command('v.db.droptable',
+            map=tmp["centroid"],
+            flags='f')
+        gscript.run_command('v.db.addtable',
+            map=tmp["centroid"],
+            columns='value')
+        gscript.run_command('v.db.update',
+            map=tmp["centroid"],
+            layer=1,
+            column='value',
+            value=1)
+        gscript.run_command('v.dissolve',
+            input=tmp["centroid"],
+            column='value',
+            output=tmp["dissolve"],
+            quiet=True)
+        gscript.run_command('v.category',
+            input=tmp["dissolve"],
+            type='point,line,boundary,centroid,area,face,kernel',
+            output=tmp["delcat"],
+            option='del',
+            cat=-1,
+            quiet=True)
+        gscript.run_command('v.category',
+            input=tmp["delcat"],
+            type='centroid,area',
+            output=tmp["addcat"],
+            option='add',
+            quiet=True)
+        gscript.run_command('v.db.droptable',
+            map=tmp["addcat"],
+            flags='f')
+        gscript.run_command('v.db.addtable',
+            map=tmp["addcat"],
+            columns='value')
+
+        ### end shadow mask preparation ###
+        ### start cloud mask preparation ###
+
+        gscript.run_command('v.db.droptable',
+            map=cloud_mask,
+            flags='f')
+        gscript.run_command('v.db.addtable',
+            map=cloud_mask,
+            columns='value')
+
+        ### end cloud mask preparation ###
+        ### shift cloud mask using dE e dN ###
+        ### start reading mean sun zenith and azimuth from xml file to compute dE and dN automatically ###
+        gscript.message(_('--- Reading mean sun zenith and azimuth from MTD_TL.xml file to compute clouds shift ---'))
+        xml_tree = et.parse(mtd_file)
+        root = xml_tree.getroot()
+        ZA = []
+
+        for elem in root[1]:
+            for subelem in elem[1]:
+                ZA.append (subelem.text)
+        z = float(ZA[0])
+        a = float(ZA[1])
+        gscript.message(_('--- the mean sun Zenith is: {:.3f} deg ---'.format(z)))
+        gscript.message(_('--- the mean sun Azimuth is: {:.3f} deg ---'.format(a)))
+
+        ### stop reading mean sun zenith and azimuth from xml file to compute dE and dN automatically ###
+        ### start computing the east and north shift for clouds and the overlapping area between clouds and shadows at steps of 100m ###
+        gscript.message(_('--- Start computing the east and north clouds shift at steps of 100m of clouds height---'))
+        H = 1000
+        dH = 100
+        HH = []
+        dE = []
+        dN = []
+        AA = []
+        while H <= 4000:
+            z_deg_to_rad = math.radians(z)
+            tan_Z = math.tan(z_deg_to_rad)
+            a_deg_to_rad = math.radians(a)
+            cos_A = math.cos(a_deg_to_rad)
+            sin_A = math.sin(a_deg_to_rad)
+
+            E_shift = (-H * tan_Z * sin_A)
+            N_shift = (-H * tan_Z * cos_A)
+            dE.append (E_shift)
+            dN.append (N_shift)
+
+            HH.append(H)
+            H = H + dH
+
+            gscript.run_command('v.transform',
+                input=cloud_mask,
+                output=tmp["cl_shift"],
+                xshift=E_shift,
+                yshift=N_shift,
+                overwrite=True,
+                quiet=True)
+            gscript.run_command('v.overlay',
+                ainput=tmp["addcat"],
+                binput=tmp["cl_shift"],
+                operator='and',
+                output=tmp["overlay"],
+                overwrite=True,
+                quiet=True)
+            gscript.run_command('v.db.addcolumn',
+                map=tmp["overlay"],
+                columns='area double')
+            area = gscript.read_command('v.to.db',
+                map=tmp["overlay"],
+                option='area',
+                columns='area',
+                flags='c')
+            area2 = gscript.parse_key_val(area, sep='|')
+            AA.append(float(area2['total area']))
+
+        # find the maximum overlapping area between clouds and shadows#
+        index_maxAA = numpy.argmax(AA)
+
+        # clouds are shifted using the clouds height corresponding to the maximum overlapping area then are intersect with shadows#
+        gscript.run_command('v.transform',
+            input=cloud_mask,
+            output=tmp["cl_shift"],
+            xshift=dE[index_maxAA],
+            yshift=dN[index_maxAA],
+            overwrite=True,
+            quiet=True)
+        gscript.run_command('v.select',
+            ainput=tmp["addcat"],
+            atype='point,line,boundary,centroid,area',
+            binput=tmp["cl_shift"],
+            btype='point,line,boundary,centroid,area',
+            output=shadow_mask,
+            operator='intersects',
+            quiet=True)
+
+        gscript.message(_('--- the estimated clouds height is: {} m ---'.format(HH[index_maxAA])))
+        gscript.message(_('--- the estimated east shift is: {:.2f} m ---'.format(dE[index_maxAA])))
+        gscript.message(_('--- the estimated north shift is: {:.2f} m ---'.format(dN[index_maxAA])))
+    else:
+        gscript.warning(_('No shadow mask will be computed'))
+
+def cleanup():
+    if flags["r"]:
+        gscript.del_temp_region()
+    gscript.message(_('--- The computational region has been reset to the previous one---'))
+    if flags["t"]:
+        gscript.message(_('--- No temporary files have been deleted ---'))
+    else:
+        for key, value in tmp.items():
+            if gscript.find_file(value, element = 'vector', mapset = mapset)['file']:
+                gscript.run_command("g.remove",
+                    flags="f",
+                    type='vector',
+                    name=",".join([tmp[m] for m in tmp.keys()]),
+                    quiet=True)
+            if gscript.find_file(value, element = 'cell', mapset = mapset)['file']:
+                gscript.run_command("g.remove",
+                    flags="f",
+                    type='raster',
+                    name=",".join([tmp[m] for m in tmp.keys()]),
+                    quiet=True)
+            
+if __name__ == "__main__":
+    options, flags = gscript.parser()
+    atexit.register(cleanup)
+    main()
+

Added: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png
===================================================================
(Binary files differ)

Index: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png	2018-06-13 15:05:18 UTC (rev 72815)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png	2018-06-13 15:06:30 UTC (rev 72816)

Property changes on: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CD.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png
===================================================================
(Binary files differ)

Index: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png	2018-06-13 15:05:18 UTC (rev 72815)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png	2018-06-13 15:06:30 UTC (rev 72816)

Property changes on: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_CS.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png
===================================================================
(Binary files differ)

Index: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png	2018-06-13 15:05:18 UTC (rev 72815)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png	2018-06-13 15:06:30 UTC (rev 72816)

Property changes on: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_GWF.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property
Added: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png
===================================================================
(Binary files differ)

Index: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png
===================================================================
--- grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png	2018-06-13 15:05:18 UTC (rev 72815)
+++ grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png	2018-06-13 15:06:30 UTC (rev 72816)

Property changes on: grass-addons/grass7/imagery/i.sentinel.mask/i_sentinel_mask_SD.png
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/octet-stream
\ No newline at end of property


More information about the grass-commit mailing list