#!/bin/sh
#
############################################################################
#
# MODULE:       d.out.gpsdrive
#
# AUTHOR(S):    M. Hamish Bowman
#		Dept. Marine Science, University of Otago, New Zealand
#
# PURPOSE:      Export display monitor to a gpsdrive compatible image
#
# COPYRIGHT:    (c) 2005-2008 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.
#
#############################################################################
#
# GpsDrive: http://www.gpsdrive.de
#
# REQUIREMENTS:
#	- awk
#	- d.info newer than 30 June 2006
#	- pngtopnm and pnmtojpeg from NetPBM  http://netpbm.sourceforge.net
#
#############################################################################
#
# NOTES:
#
#  Output must be 1280x1024,  use PNG or JPEG
#  You can figure out the "scale" factor by meters/pixel * 2817.947378
#    2817 is maybe someones screen dpi converted to pixels/meter??
#
#  At scales wider than say 1:250,000 the curvatute of the Earth really starts
#   to play havoc with GpsDrive's simple projection system if you are using
#   a UTM or other non-lat/lon projection. Best to use output from a lat/lon
#   location in that case. i.e. to avoid distortion, anything more global than
#   1:150k to 1:500k should use "top_*".
#
# Beware  if you are using an image originating from a map projection with
# a significant deviation between true  north  and  the  map  projection's
# local  +y  direction  (known as the Convergence Angle). GpsDrive assumes
# that true north is always directly up! i.e. the Central Meridian of  the
# map projection is located at the map tile's center. For some map projec-
# tions and areas of the country this can be a really bad  assumption  and
# your  map  will be significantly rotated. This effect is most visible at
# map scales covering a large area. This does not affect lat/lon maps.
# The pnmrotate program may help, or gdalwarp to a custom map-centered tmerc.
#
# A series of 1:50,000 maps may not be so bad.
#   This translates to approx a 22.7km x 18.2km image window in the GIS.
#     x_ext=scale*(1280/2817.9)
#  1:75,000 uses a region 34.1km x 27.3km.
#  1:100,000 uses a region  45.4km x 36.3km.
#  1:175,000 uses a region  80km across.
#
# HINTS:
#  first get things ready in a 640x512 window (1/2 scale, same aspect ratio)
#   export GRASS_WIDTH=640
#   export GRASS_HEIGHT=512
#   d.mon x0
#
#############################################################################


#%Module
#%  description: Export display monitor to a GpsDrive compatible backdrop image
#%  keywords: display, export, GPS
#%End
#%option
#% key: output
#% type: string
#% gisprompt: new_file,file,output
#% description: name for new map image (lives in ~/.gpsdrive/maps/)
#% required : yes
#%end
#%flag
#%  key: j
#%  description: Make JPEG instead of PNG image
#%end

if [ -z "$GISBASE" ] ; then
        echo "You must be in GRASS GIS to run this program."
    exit 1
fi

if [ "$1" != "@ARGS_PARSED@" ] ; then
  exec g.parser "$0" "$@"
fi

PROG=`basename "$0"`

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

#### check if we have NetPBM
if [ "$GIS_FLAG_J" -eq 1 ] ; then
  if [ ! -x "`which pngtopnm`" ] || [ ! -x "`which pnmtojpeg`" ] ; then
    g.message -e "NetPBM tools are required for JPEG output"
    exit 1
  fi
fi

# set environment so awk works properly in all languages
unset LC_ALL
LC_NUMERIC=C
export LC_NUMERIC


if [ ! -d "$HOME/.gpsdrive/maps" ] ; then
    mkdir -p "$HOME/.gpsdrive/maps"
fi

# GpsDrive scales maps named top_* as lat/lon (1:1) on-screen
# GpsDrive scales maps named map_* as UTM-like (1:cos(lat) ) on-screen
PROJ=`g.region -p | grep ^proj | cut -f2 -d' '`
if [ "$PROJ" -eq 3 ] ; then
   IS_LATLON=1
   TYPE="top"
else
   IS_LATLON=0
   TYPE="map"
   if [ "$PROJ" -ne 1 ] ; then
      g.message message="GpsDrive assumes northings are not rotated compared "\
"to true-geographic north. If you are using a projection with significant "\
"curvature away from the central meridian, then you will likely end up with "\
'a distorted background map! '\
"Keeping the area small will lessen the error, but not eliminate it. "\
"Consider output from a Lat/Lon location if the convergence angle is "\
"more than a couple of degrees."
      g.region -n

	# TODO: add a flag to correct for convergence angle with pnmrotate
   fi
fi

GRASS_TRUECOLOR=TRUE
export GRASS_TRUECOLOR
GRASS_WIDTH=1280
export GRASS_WIDTH
GRASS_HEIGHT=1024
export GRASS_HEIGHT

# get rid of no or double extension
output="${TYPE}_`basename $GIS_OPT_OUTPUT .png`.png"

GRASS_PNGFILE="$HOME/.gpsdrive/maps/$output"
export GRASS_PNGFILE

# As .jpg output will overwrite .png of the same name, we check,
if [ -e "$GRASS_PNGFILE" ] ; then
    g.message -e "Output image of that name (or base name) already exists."
    exit 1
fi


# Check the current status of the monitor
monitorcheck="`d.mon -p | grep 'No monitor'`"
if  [ -n "$monitorcheck" ] ; then
  g.message "No display monitor selected."
  exit 1
fi

# check to see we have a new enough version of d.info
d.info -b  1> /dev/null 2> /dev/null
if [ $? -ne 0 ] ; then
  g.message -e "Need a newer version of GRASS."
  exit 1
fi

curr_mon=`d.mon -p | awk '{printf "%s", $4}'`

#export display to PNG driver
dsave=`d.save -a`
d.mon start=PNG --quiet
  FRAME_DIMS="`d.info -b | cut -f2- -d' '`"
  eval "$dsave"
d.mon stop=PNG --quiet
#reset
sleep 1
d.mon select="$curr_mon"

if [ "$GIS_FLAG_J" -eq 1 ] ; then
   out_jpeg="`basename $output .png`.jpg"
   cd "$HOME/.gpsdrive/maps/"
   sync  # sleep 1
   pngtopnm "$output" | pnmtojpeg > "$out_jpeg"
   rm -f "$output"
   output="$out_jpeg"
fi

eval `g.region -g`

FRAME_WIDTH="`echo $FRAME_DIMS | awk '{printf("%f", $2 - $1)}'`"
FRAME_HEIGHT="`echo $FRAME_DIMS | awk '{printf("%f", $4 - $3)}'`"

if [ $IS_LATLON -eq 0 ] ; then
   LAT=`g.region -lg | grep 'center_lat' | cut -f2 -d'='`
   LON=`g.region -lg | grep 'center_long' | cut -f2 -d'='`

   M_PER_PIXEL=`echo $e $w $FRAME_WIDTH | awk '{printf("%f", ($1 - $2) / $3)}'`
else
   LAT=`g.region -cg | grep 'northing' | cut -f2 -d'='`
   LON=`g.region -cg | grep 'easting' | cut -f2 -d'='`

   EXTENT=`g.region -eg | grep 'ns_extent' | cut -f2 -d'='`
   M_PER_PIXEL=`echo $EXTENT $FRAME_HEIGHT | awk '{printf("%f", ($1 * 1852*60.) / $2)}'`
fi

SCALE=`echo $M_PER_PIXEL | awk '{printf("%d", 0.5 + ($1 * 2817.947378) )}'`

if [ $IS_LATLON -eq 0 ] && [ "$SCALE" -ge 125000 ] ; then
   g.message -w "Projected input maps may be somewhat inaccurate at this scale. Better to use lat/lon"
fi

echo "$output $LAT $LON $SCALE" >> "$HOME/.gpsdrive/maps/map_koord.txt"

g.message -v "Center lat,lon is [$LAT,$LON],  scale is [1:${SCALE}]"

g.message "Done."
