#!/bin/sh

############################################################################
#
# MODULE:	i.fusion.brovey
# AUTHOR(S):	Markus Neteler. <neteler itc it>
# PURPOSE:	Brovey transform to merge
#                 - LANDSAT-7 MS (2, 4, 5) and pan (high res)
#                 - SPOT MS and pan (high res)
#                 - QuickBird MS and pan (high res)
#
# COPYRIGHT:	(C) 2002-2008 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.
#
# REFERENCES:
#             (?) Roller, N.E.G. and Cox, S., 1980. Comparison of Landsat MSS
#                and merged MSS/RBV data for analysis of natural vegetation.
#                Proc. of the 14th International Symposium on Remote Sensing
#                of Environment, San Jose, Costa Rica, 23-30 April, pp. 1001-1007.
#
#               for LANDSAT 5: see Pohl, C 1996 and others
#
# TODO:         add overwrite test at beginning of the script
#############################################################################

#%Module
#%  description: Brovey transform to merge multispectral and high-res panchromatic channels
#%  keywords: imagery, fusion, Brovey
#%End
#%Flag
#%  key: l
#%  description: LANDSAT sensor
#%  guisection: Sensor
#%END
#%Flag
#%  key: q
#%  description: QuickBird sensor
#%  guisection: Sensor
#%END
#%Flag
#%  key: s
#%  description: SPOT sensor
#%  guisection: Sensor
#%END
#%option
#% key: ms1
#% type: string
#% gisprompt: old,cell,raster
#% description: Name of input raster map (green: tm2 | qbird_green | spot1)
#% required : yes
#%end
#%option
#% key: ms2
#% type: string
#% gisprompt: old,cell,raster
#% description: Name of input raster map (NIR: tm4 | qbird_nir | spot2)
#% required : yes
#%end
#%option
#% key: ms3
#% type: string
#% gisprompt: old,cell,raster
#% description: Name of input raster map (MIR; tm5 | qbird_red | spot3)
#% required : yes
#%end
#%option
#% key: pan
#% type: string
#% gisprompt: old,cell,raster
#% description: Name of input raster map (etmpan | qbird_pan | spotpan)
#% required : yes
#%end
#%option
#% key: outputprefix
#% type: string
#% gisprompt: new,cell,raster
#% description: Name for output raster map prefix (e.g. 'brov')
#% required : yes
#%end


if test "$GISBASE" = ""; then
   echo "You must be in GRASS GIS to run this program." >&2
   exit 1
fi

# save command line
if [ "$1" != "@ARGS_PARSED@" ] ; then
    CMDLINE=`basename "$0"`
    for arg in "$@" ; do
        CMDLINE="$CMDLINE \"$arg\""
    done
    export CMDLINE
    exec g.parser "$0" "$@"
fi


cleanup()
{
   #remove temporary region file
   unset WIND_OVERRIDE
   g.remove region="i.fusion.brovey.$TMPPID" --quiet
}

# what to do in case of user break:
exitprocedure()
{
   g.message -e message='User break!'
   cleanup
   exit 1
}

# shell check for user break (signal list: trap -l)
trap "exitprocedure" 2 3 15



#### check if we have awk
if [ ! -x "`which awk`" ] ; then
    g.message -e "awk required, please install awk or gawk first" 
    exit 1
fi

# setting environment, so that awk works properly in all languages
unset LC_ALL
LC_NUMERIC=C
export LC_NUMERIC

TMPPID=$$

if [ $GIS_FLAG_S -eq 0 -a $GIS_FLAG_L -eq 0 -a $GIS_FLAG_Q -eq 0 ] ; then
   g.message -e "Please select a flag to specify the satellite sensor"
   exit 1
fi

#get PAN resolution:
PANRES=`r.info "$GIS_OPT_PAN" | grep Res | tr -s ' ' ' ' | cut -d':' -f4 | cut -d' ' -f2 | tr '\n' ' '  | awk '{printf "%f\n", ($1+$2) / 2.}'`
if [ $? -ne 0 ] ; then
   g.message -e "An error occurred while parsing r.info output"
   exit 1
fi

# clone current region
g.region save="i.fusion.brovey.$TMPPID"

g.message -v message="Using resolution from PAN: $PANRES"
WIND_OVERRIDE="i.fusion.brovey.$TMPPID"
export WIND_OVERRIDE
g.region res="$PANRES" -a

g.message -v "Performing Brovey transformation..."

# The formula was originally developed for LANDSAT-TM5 and SPOT, 
# but it also works well with LANDSAT-TM7
# LANDSAT formula:
#  r.mapcalc "brov.red=1. *  tm.5 / (tm.2 + tm.4 + tm.5) * etmpan"
#  r.mapcalc "brov.green=1. * tm.4 /(tm.2 + tm.4 + tm.5) * etmpan"
#  r.mapcalc "brov.blue=1. * tm.2 / (tm.2 + tm.4 + tm.5) * etmpan"
#
# SPOT formula:
# r.mapcalc "brov.red= 1.  * spot.ms.3 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
# r.mapcalc "brov.green=1. * spot.ms.2 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
# r.mapcalc "brov.blue= 1. * spot.ms.1 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
# note: for RGB composite then revert brov.red and brov.green!

g.message message="Calculating <$GIS_OPT_OUTPUTPREFIX.red>... (step 1/4)"
r.mapcalc "\"$GIS_OPT_OUTPUTPREFIX.red\" = 1. * \"$GIS_OPT_MS3\" / (\"$GIS_OPT_MS1\" + \"$GIS_OPT_MS2\" + \"$GIS_OPT_MS3\") * \"$GIS_OPT_PAN\""
if [ $? -ne 0 ] ; then
   g.message -e "An error occurred while running r.mapcalc"
   cleanup
   exit 1
fi

g.message message="Calculating <$GIS_OPT_OUTPUTPREFIX.green>... (step 2/4)"
r.mapcalc "\"$GIS_OPT_OUTPUTPREFIX.green\" = 1. * \"$GIS_OPT_MS2\" / (\"$GIS_OPT_MS1\" + \"$GIS_OPT_MS2\" + \"$GIS_OPT_MS3\") * \"$GIS_OPT_PAN\""
if [ $? -ne 0 ] ; then
   g.message -e "An error occurred while running r.mapcalc"
   cleanup
   exit 1
fi

g.message message="Calculating <$GIS_OPT_OUTPUTPREFIX.blue>... (step 3/4)"
r.mapcalc "\"$GIS_OPT_OUTPUTPREFIX.blue\" = 1. * \"$GIS_OPT_MS1\" / (\"$GIS_OPT_MS1\" + \"$GIS_OPT_MS2\" + \"$GIS_OPT_MS3\") * \"$GIS_OPT_PAN\""
if [ $? -ne 0 ] ; then
   g.message -e "An error occurred while running r.mapcalc"
   cleanup
   exit 1
fi

# Maybe?
#r.colors   $GIS_OPT_OUTPUTPREFIX.red col=grey
#r.colors   $GIS_OPT_OUTPUTPREFIX.green col=grey
#r.colors   $GIS_OPT_OUTPUTPREFIX.blue col=grey
#to blue-ish, therefore we modify
#r.colors $GIS_OPT_OUTPUTPREFIX.blue col=rules << EOF
#5 0 0 0
#20 200 200 200
#40 230 230 230
#67 255 255 255
#EOF

if [ $GIS_FLAG_S -eq 1 ] ; then
   #apect table is nice for SPOT:
   g.message message="Assigning color tables for SPOT... (step 4/4)"
   r.colors "$GIS_OPT_OUTPUTPREFIX.blue" col=aspect
   r.colors "$GIS_OPT_OUTPUTPREFIX.green" col=aspect
   r.colors "$GIS_OPT_OUTPUTPREFIX.red" col=aspect
   g.message "Fixing output names..."
   g.rename "$GIS_OPT_OUTPUTPREFIX.green","$GIS_OPT_OUTPUTPREFIX.$TMPPID" --quiet
   g.rename "$GIS_OPT_OUTPUTPREFIX.red","$GIS_OPT_OUTPUTPREFIX.green" --quiet
   g.rename "$GIS_OPT_OUTPUTPREFIX.$TMPPID","$GIS_OPT_OUTPUTPREFIX.red" --quiet
else
   #aspect table is nice for LANDSAT and QuickBird:
   g.message message="Assigning color tables for LANDSAT or QuickBird... (step 4/4)"
   r.colors "$GIS_OPT_OUTPUTPREFIX.blue" col=aspect
   r.colors "$GIS_OPT_OUTPUTPREFIX.green" col=aspect
   r.colors "$GIS_OPT_OUTPUTPREFIX.red" col=aspect
fi

g.message -v "Restoring region settings."
cleanup

g.message "Following pan-sharpened output maps have been generated:"
echo "$GIS_OPT_OUTPUTPREFIX.red"
echo "$GIS_OPT_OUTPUTPREFIX.green"
echo "$GIS_OPT_OUTPUTPREFIX.blue"

g.message -v "To visualize output, run:"
g.message -v message="g.region -p rast=$GIS_OPT_OUTPUTPREFIX.red ; d.erase"
g.message -v message="d.rgb r=$GIS_OPT_OUTPUTPREFIX.red g=$GIS_OPT_OUTPUTPREFIX.green b=$GIS_OPT_OUTPUTPREFIX.blue"
g.message -v "If desired, combine channels with 'r.composite' to a single map."

# write cmd history:
r.support "$GIS_OPT_OUTPUTPREFIX.red" history="${CMDLINE}"
r.support "$GIS_OPT_OUTPUTPREFIX.green" history="${CMDLINE}"
r.support "$GIS_OPT_OUTPUTPREFIX.blue" history="${CMDLINE}"
