#!/bin/sh
# 
############################################################################
#
# MODULE:      v.in.gpsbabel
#
# PURPOSE:     Import GPS data from a GPS receiver or file into a GRASS
#	       vector map using gpsbabel
#
# COPYRIGHT:   (c) 2000-2007 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.
#
# AUTHORS:     Claudio Porta & Lucio Davide Spano, students of Computer 
#		  Science, University of Pisa (Italy).
#		Commission from Faunalia Pontedera (PI)
#
#               With updates by Markus Neteler and Hamish Bowman
#
#		Based on v.in.garmin for GRASS 6 by Hamish Bowman
#		and v.in.garmin.sh for GRASS 5 by Andreas Lange
#
#############################################################################
#
# REQUIREMENTS:
#      -  gpsbabel from:
#	     http://gpsbabel.sourceforge.net
#      -  unix tools: grep, cat, tac, cut, paste, awk/nawk/gawk, sed
#      -  cs2cs from PROJ.4    http://proj.maptools.org/
#
#      - report supported formats:
#	 gpsbabel -^2 | tr '\t' ';' | sort -t';' -k3
#
#############################################################################

#%Module
#%  description: Import waypoints, routes, and tracks from a GPS receiver or GPS download file into a vector map.
#%  keywords: vector, import, GPS
#%End
#%flag
#%  key: v
#%  description: Verbose mode
#%end
#%flag
#%  key: w
#%  description: Import waypoints
#%end
#%flag
#%  key: r
#%  description: Import routes
#%end
#%flag
#%  key: t
#%  description: Import track
#%end
#%flag
#%  key: p
#%  description: Force vertices of track or route data as points
#%end
#%flag
#%  key: k
#%  description: Do not attempt projection transform from WGS84
#%end
#%option
#% key: input
#% type: string
#% description: Device or file used to import data
#% gisprompt: old_file,file,file
#% answer: /dev/gps
#%end
#%option
#% key: output
#% type: string
#% gisprompt: new,vector,vector
#% description: Name for output vector map (omit for display to stdout)
#% required : no
#%end
#%option
#% key: format
#% type: string
#% description: Format of GPS input data (use gpsbabel supported formats)
#% answer: garmin
#%end
#%option
#% key: proj
#% type: string
#% description: Projection of input data (PROJ.4 style), if not set Lat/Lon WGS84 is assumed
#% required: no
#%end

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

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

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

eval `g.gisenv`
: ${GISBASE?} ${GISDBASE?} ${LOCATION_NAME?} ${MAPSET?}
LOCATION="$GISDBASE"/"$LOCATION_NAME"/"$MAPSET"

PROG=`basename "$0"`

#### check for gpsbabel 
 if [ ! -x "`which gpsbabel`" ] ; then
    g.message -e "The gpsbabel program was not found, please install it first.
                  http://gpsbabel.sourceforge.net"
    exit 1
fi

#### check for cs2cs
if [ ! -x "`which cs2cs`" ] ; then
    g.message -e "The cs2cs program was not found, please install it first.
                   http://proj.maptools.org"
    exit 1
fi

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

#### set temporary files
TEMPFILE="`g.tempfile pid=$$`"
if [ $? -ne 0 ] || [ -z "$TEMPFILE" ] ; then
    g.message -e "Unable to create temporary files"
    exit 1
fi

#### trap ctrl-c so that we can clean up tmp
trap 'rm -f "${TEMPFILE}."*' 2 3 15


#### process command line arguments 
WPT=1 ; RTE=0 ; TRK=0 ; KEEP_WGS84=0; VERBOSE=0


if [ $GIS_FLAG_V -eq 1 ] ; then
    VERBOSE=1
    PROGVERBOSE="-D 1"
fi

if [ -n "$GIS_OPT_OUTPUT" ] ; then
    NAME="$GIS_OPT_OUTPUT"
    if [ $VERBOSE -eq 1 ] ; then
	g.message message="output=$NAME" 
    fi
fi
if [ -n "$GIS_OPT_INPUT" ] ; then
    GPSdevice="$GIS_OPT_INPUT"
    if [ $VERBOSE -eq 1 ] ; then
	g.message message="file=$GIS_OPT_INPUT"
    fi
fi


if [ $GIS_FLAG_W -eq 1 ] && ([ $GIS_FLAG_R -eq 1 ] || [ $GIS_FLAG_T -eq 1 ]) ; then
    g.message -e "One feature at a time please. Use v.patch if you need to combine them."
    rm -f "${TEMPFILE}"
    exit 1
fi
# logic eludes me at pressent..  [combine with above]
if [ $GIS_FLAG_R -eq 1 ] && [ $GIS_FLAG_T -eq 1 ] ; then
    g.message -e "One feature at a time please. Use v.patch if you need to combine them."
    rm -f "${TEMPFILE}"
    exit 1
fi

CREATE_POINTS=0

if [ $GIS_FLAG_W -eq 1 ] ; then
    WPT=1
    CREATE_POINTS=1
elif [ $GIS_FLAG_R -eq 1 ] ; then
    WPT=0
    RTE=1
    CREATE_POINTS=0
elif [ $GIS_FLAG_T -eq 1 ] ; then
    WPT=0
    TRK=1
    CREATE_POINTS=0
fi

if [ $GIS_FLAG_P -eq 1 ] ; then
    CREATE_POINTS=1
fi
if [ $GIS_FLAG_K -eq 1 ] ; then
    KEEP_WGS84=1
fi

if [ $GIS_FLAG_W -eq 0 ] && [ $GIS_FLAG_R -eq 0 ] && [ $GIS_FLAG_T -eq 0 ] ; then
    g.message -w "No features requested for download. Assuming waypoints."
    WPT=1
    CREATE_POINTS=1
fi


#### set up projection info
if [ -n "$GIS_OPT_PROJ" ] ; then
    IN_PROJ="$GIS_OPT_PROJ"
else
    IN_PROJ="+proj=longlat +datum=WGS84"
fi
OUT_PROJ="`g.proj -jf`"
PROJ_TYPE=`g.region -p | grep 'projection' | cut -f2 -d" "`

if [ $PROJ_TYPE -eq 0 ] && [ $KEEP_WGS84 -ne 1 ] ; then
    g.message -e "Cannot project to a XY location."
    rm -f "${TEMPFILE}"
    exit 1
fi

STYLE="$GISBASE/etc/grass_write_ascii.style"

# How to do it
#
# gpsbabel [options] -i INTYPE -f INFILE -o OUTTYPE -F OUTFILE
# gpsbabel [options] -i INTYPE -o OUTTYPE INFILE [OUTFILE]
#
#(GPX file example):
# gpsbabel -w -i gpx -o xcsv,style=grass_write_ascii.style outfile.csv

#### receive data...

if [ $CREATE_POINTS -eq 1 ] ; then
    if [ $WPT -eq 1 ] ; then
	g.message "Loading Waypoints from <$GIS_OPT_INPUT>..." 
	TYPE="-w"
	EXITCODE=$?
    elif [ $RTE -eq 1 ] ; then
	g.message "Loading Routes as points from <$GIS_OPT_INPUT>..." 
	TYPE="-r"
    elif [ $TRK -eq 1 ] ; then
	g.message "Loading Tracks as points from <$GIS_OPT_INPUT>..." 
	TYPE="-t"
    fi

    gpsbabel $TYPE -i $GIS_OPT_FORMAT -f "$GPSdevice" $PROGVERBOSE \
	-o xcsv,style="$STYLE" -F "$TEMPFILE".xcsv
    EXITCODE=$?

    if [ "`wc -l < "${TEMPFILE}.xcsv"`" -eq 0 ] ; then
	g.message -w 'No data! Exiting.'
	rm -f "${TEMPFILE}."*
	exit 0
    fi

else
    if [ $RTE -eq 1 ] ; then
	g.message "Loading Routes from <$GIS_OPT_INPUT>..." 
	TYPE="-r"
	EXITCODE=$?
    elif [ $TRK -eq 1 ] ; then
	g.message "Loading Tracks from <$GIS_OPT_INPUT>..." 
	TYPE="-t"
	EXITCODE=$?
    fi
    gpsbabel $TYPE -i $GIS_OPT_FORMAT -f "$GPSdevice" $PROGVERBOSE \
	-o gpx -F "$TEMPFILE".gpx
    EXITCODE=$?

    if [ $EXITCODE -eq 0 ] && \
       [ "`grep -c '<rte>' "${TEMPFILE}.gpx"`" -eq 0 ] && \
       [ "`grep -c '<trk>' "${TEMPFILE}.gpx"`" -eq 0 ] ; then
	g.message -e 'No data! Exiting.'
	rm -f "${TEMPFILE}."*
	exit 0
    fi
fi

#### check success/failure
if [ $EXITCODE -ne 0 ] ; then
    g.message -e "Error loading data from gpsbabel"
    rm -f "${TEMPFILE}."*
    exit 1
fi


###################################
if [ $CREATE_POINTS -eq 1 ] ; then
###################################

    cat "${TEMPFILE}.xcsv" | cut -f 1,2 -d '|'| tr '|' ' '  > "$TEMPFILE".base
# FIXME: if last field (comments) is empty it causes a not-enough fields error in v.in.ascii
# FIXME: if altitude column is empty (1st attr) v.in.ascii complains as the column type is defined as 'double'
    cat "${TEMPFILE}.xcsv" | tr '+' '|' | cut -f3,4,5,6 -d '|' | \
	sed -e 's/-99999999.000000//' -e 's/|$/|_/' \
	    -e 's/01\/01\/1970|00:00:00 AM/|/' \
	    -e 's/^|/-9999|/'> "$TEMPFILE".attributes


    #### reproject if needed
    if [ "$IN_PROJ" = "$OUT_PROJ" ] || [ $KEEP_WGS84 -eq 1 ] ; then
	g.message "No projection transformation performed" 
	cp "${TEMPFILE}.base" "${TEMPFILE}.P_base"
    else
	g.message "Attempting waypoint projection transform with cs2cs" 
	cs2cs -f %.7f $IN_PROJ +to $OUT_PROJ < "${TEMPFILE}.base" > "${TEMPFILE}.P_base"
	EXITCODE=$?
	# check if transform REALLY worked (e.g. when the grid file is not found)
	BAD_PTS="`grep -c "^\*" "${TEMPFILE}.P_base"`"
	if [ "$BAD_PTS" -gt 0 ] ; then
	    g.message message=""
	    g.message -w "$BAD_PTS point(s) failed reprojection."
	    EXITCODE=1
	fi
	if [ $EXITCODE -ne 0 ] ; then
	    g.message -w "Projection transform failed, retaining WGS84"
	    g.message message=""
	    cp -f "${TEMPFILE}.base" "${TEMPFILE}.P_base"
	fi
    fi

    cat "${TEMPFILE}.P_base" | awk '{print $1 "|" $2}' > "${TEMPFILE}.vertices"

    #### and put back together
    # wpt list:   x|y|<attr1>|...|<attr n>
    paste -d"|" "$TEMPFILE".vertices "$TEMPFILE".attributes > "$TEMPFILE".asc

    #### output or import
    if [ -z "$NAME" ] ; then
	g.message "ASCII file redirected to stdout" 
	cat "${TEMPFILE}.asc" 2> /dev/null
    else
	#### import into new points file
	if [ $WPT -eq 1 ] ; then
	    g.message "Importing Waypoints..."
	elif [ $RTE -eq 1 ] ; then
	    g.message "Importing Routes as points..."
	elif [ $TRK -eq 1 ] ; then
	    g.message "Importing Tracks as points..."
	fi

	v.in.ascii in="${TEMPFILE}.asc" output="$NAME" cat=0 \
	  columns='x double precision, y double precision, altitude double precision, gmt_date varchar(10), gmt_time varchar(11), comments varchar(40)'
	EXITCODE=$?

	# EXITCODE also used at pgm termination below!
	if [ $EXITCODE -ne 0 ] ; then
	    g.message -e "While Importing data with v.in.ascii"
	    rm -f "${TEMPFILE}"*
	    exit 1
	fi
    fi


#####################
else # CREATE_LINES
#####################

    #### prepare line components
    if [ $RTE -eq 1 ] ; then
	
	# this part is quite difficult using gpx... I'll explain all I've done
	# if someone has any suggest please mail!!!!

	# list of bytes where routes finish
	cat "$TEMPFILE.gpx" | grep -n "</rte>" > "$TEMPFILE.bytes"
	# number of routes
	cat "$TEMPFILE.bytes" | grep -c "</rte>" > "$TEMPFILE.var"
	ROUTE_NUMBER=0 
	read ROUTE_NUMBER < "$TEMPFILE.var" # route number to process
	READ_BYTES=0 # offset of bytes already read
	cp "$TEMPFILE.gpx" "$TEMPFILE.gpx2" # file to be "eaten" by head commands in while 
	ROUTE_ID=0 # route identifier

	while [ "$ROUTE_NUMBER" -gt 0 ] ; do
	    head -n 1 "$TEMPFILE.bytes" | cut -f 1 -d ':'> "$TEMPFILE.var"
	    END_BYTE=0
	    read END_BYTE < "$TEMPFILE.var" # this route ends at END_BYTE in $TEMPFILE.gpx file

	    TO_READ=0
	    TO_READ="`expr $END_BYTE - $READ_BYTES`"    # bytes to read from $TEMPFILE.gpx2 file 
	    READ_BYTES="`expr $READ_BYTES + $TO_READ`"  # update readed bytes

	    # list of points in route
	    head -n $TO_READ "$TEMPFILE.gpx2" | grep "<rtept" > "$TEMPFILE.points" 
	    POINTS=0 # number of points in route
	    cat "$TEMPFILE.points" | grep -c "<rtept" > "$TEMPFILE.var"
	    read POINTS < "$TEMPFILE.var"
	    echo "L $POINTS 1" >> "$TEMPFILE.base"
	    # read lat lon data
	    cat "$TEMPFILE.points" | cut -f2 -d'<' | cut -f2,3 -d ' ' | cut -f2,4 -d '"' | tr '"' '\t' > "$TEMPFILE.latlon"
	    cat "$TEMPFILE.latlon" | tr ',' '.' | awk '{printf(" %s %s\n", $2, $1) }' >> "$TEMPFILE.base"
	    # create attribute line
	    head -n $TO_READ "$TEMPFILE.gpx2" | grep -n "<rtept" | head -n 1 | cut -f1 -d ':' > "$TEMPFILE.var"
	    OFFSET=0
	    read OFFSET < "$TEMPFILE.var"
	    head -n $OFFSET "$TEMPFILE.gpx2" > "$TEMPFILE.rte_attr"
	    # read needed attributes
	    ROUTE_ID="`expr $ROUTE_ID + 1`"
	    cat "$TEMPFILE.rte_attr"| grep "<number" | tail -n 1 | cut -f2 -d'<' | cut -f2 -d'>' > "$TEMPFILE.var"
	    NUMBER=0
	    read NUMBER < "$TEMPFILE.var" # read the route number
	    cat "$TEMPFILE.rte_attr"| grep "<name" | tail -n 1 | cut -f2 -d'<' | cut -f2 -d'>' > "$TEMPFILE.var"
	    R_NAME=""
	    read R_NAME < "$TEMPFILE.var" # read the route name

	    OFFSET="`expr $TO_READ - $OFFSET`"
	    head -n $TO_READ "$TEMPFILE.gpx2" | tail -n $OFFSET | grep "<name" | head -n 1 | cut -f2 -d'<' | cut -f2 -d'>' > "$TEMPFILE.var"
	    START_PNT=""
	    read START_PNT < "$TEMPFILE.var" # read the name of start point

	    # check that numberic values don't try and pass an empty string
### variable names don't line up with column names ?!
	    if [ -z "$ROUTE_ID" ] ; then
		ROUTE_ID="NULL"
        	g.message -w "Route $ROUTE_NUMBER: category number was empty. Bug?"
	    fi
	    if [ -z "$NUMBER" ] ; then
		NUMBER="NULL"
		g.message -w "Route $ROUTE_NUMBER: route ID was empty. Bug?"
	    fi

	    echo "$ROUTE_ID|$NUMBER|$R_NAME|$START_PNT" >> "$TEMPFILE.route_atts"

	    ROUTE_NUMBER="`expr $ROUTE_NUMBER - 1`"

	    # eat files
	    tail -n $ROUTE_NUMBER "$TEMPFILE.bytes" > "$TEMPFILE.bytes2"
	    mv "$TEMPFILE.bytes2" "$TEMPFILE.bytes"
	    head -n $TO_READ "$TEMPFILE.gpx2" > "$TEMPFILE.points"
	    B_GPX=0
	    wc -c < "$TEMPFILE.gpx2" > "$TEMPFILE.var"
	    read B_GPX < "$TEMPFILE.var"
	    B_PNT=0
	    wc -c < "$TEMPFILE.points" > "$TEMPFILE.var"
	    read B_PNT < "$TEMPFILE.var"
	    TO_READ="`expr $B_GPX - $B_PNT`"
	    tail -c $TO_READ "$TEMPFILE.gpx2" > "$TEMPFILE.points"
	    mv "$TEMPFILE.points" "$TEMPFILE.gpx2"
	done
	# create attr table: cat(int), id number(int 0-19), name varchar(16+), starting_wpt(varchar 10)
	ATTR_FILE="${TEMPFILE}.route_atts"
	ATTR_COLS='cat int, route_id int, name varchar(40), start_wpt varchar(40)'
    fi

    if [ $TRK -eq 1 ] ; then

	# list of bytes where tracks finish
	cat "$TEMPFILE.gpx" | grep -n "</trkseg>" > "$TEMPFILE.bytes"
	# number of tracks
	cat "$TEMPFILE.bytes" | grep -c "</trkseg>" > "$TEMPFILE.var"
	TRACK_NUMBER=0 
	read TRACK_NUMBER < "$TEMPFILE.var" # route number to process
	READ_BYTES=0 # offset of bytes already read
	cp "$TEMPFILE.gpx" "$TEMPFILE.gpx2" # file to be "eaten" by head commands in while 
	TRACK_ID=0 # track identifier
	while [ "$TRACK_NUMBER" -gt 0 ] ; do
	    head -n 1 "$TEMPFILE.bytes" | cut -f 1 -d ':'> "$TEMPFILE.var"
	    END_BYTE=0
	    read END_BYTE < "$TEMPFILE.var" # this route ends at END_BYTE in $TEMPFILE.gpx file
	    TO_READ=0

	    TO_READ="`expr $END_BYTE - $READ_BYTES`"    # bytes to read from $TEMPFILE.gpx2 file 
	    READ_BYTES="`expr $READ_BYTES + $TO_READ`"  # update readed bytes

	    # list of points in route
	    head -n $TO_READ "$TEMPFILE.gpx2" | grep "<trkpt" > "$TEMPFILE.points" 
	    POINTS=0 # number of points in track 
	    cat "$TEMPFILE.points" | grep -c "<trkpt" > "$TEMPFILE.var"
	    read POINTS < "$TEMPFILE.var"
	    echo "L $POINTS 1" >> "$TEMPFILE.base"
	    # read lat lon data
	    cat "$TEMPFILE.points" | cut -f2 -d'<' | cut -f2,3 -d ' ' | cut -f2,4 -d '"' | tr '"' '\t' > "$TEMPFILE.latlon"
	    cat "$TEMPFILE.latlon" | tr ',' '.' | awk '{printf(" %s %s\n", $2, $1) }' >> "$TEMPFILE.base"
	    # create attribute line
	    head -n $TO_READ "$TEMPFILE.gpx2" | grep -n "<trk" | head -n 1 | cut -f1 -d ':' > "$TEMPFILE.var"
	    OFFSET=0
	    read OFFSET < "$TEMPFILE.var"
	    S_LAT=""
	    head -n 1 "$TEMPFILE.latlon" | cut -f1 > "$TEMPFILE.var"
	    read S_LAT < "$TEMPFILE.var"
	    S_LON=""
	    head -n 1 "$TEMPFILE.latlon" | cut -f2 > "$TEMPFILE.var"
	    read S_LON < "$TEMPFILE.var"
	    E_LAT=""
	    tail -n 1 "$TEMPFILE.latlon" | cut -f1 > "$TEMPFILE.var"
	    read E_LAT < "$TEMPFILE.var"
	    E_LON=""
	    tail -n 1 "$TEMPFILE.latlon" | cut -f2 > "$TEMPFILE.var"
	    read E_LON < "$TEMPFILE.var"

	    OFFSET="`expr $TO_READ - $OFFSET`"

	    head -n $TO_READ "$TEMPFILE.gpx2" | tail -n $OFFSET | grep "<time" > "$TEMPFILE.time"
	    S_TIME=""
	    head -n 1 "$TEMPFILE.time" | cut -f 2 -d'>' | cut -f1 -d'<' > "$TEMPFILE.var"
	    read S_TIME < "$TEMPFILE.var"
	    E_TIME=""
	    tail -n 1 "$TEMPFILE.time" | cut -f 2 -d'>' | cut -f1 -d'<' > "$TEMPFILE.var"
	    read E_TIME < "$TEMPFILE.var"

	    TRACK_ID="`expr $TRACK_ID + 1`"

	    # check that numberic values don't try and pass an empty string
	    if [ -z "$TRACK_ID" ] ; then
		TRACK_ID="NULL"
		g.message -w "Track $TRACK_NUMBER: category number was empty. Bug?"
	    fi
	    if [ -z "$S_LAT" ] ; then
		S_LAT="NULL"
		g.message -w "Track $TRACK_NUMBER:  starting lat was empty. Bug?"
	    fi
	    if [ -z "$S_LON" ] ; then
		S_LON="NULL"
		g.message -w "Track $TRACK_NUMBER:  starting lon was empty. Bug?"
	    fi
	    if [ -z "$E_LAT" ] ; then
		E_LAT="NULL"
		g.message -w "Track $TRACK_NUMBER:  ending lat was empty. Bug?"
	    fi
	    if [ -z "$E_LON" ] ; then
		E_LON="NULL"
		g.message -w "Track $TRACK_NUMBER:  ending lon was empty. Bug?"
	    fi

	    echo "$TRACK_ID|$S_TIME|$S_LAT|$S_LON|$E_TIME|$E_LAT|$E_LON" >> "$TEMPFILE.track_atts"

	    TRACK_NUMBER="`expr $TRACK_NUMBER - 1`"

	    # eat files
	    tail -n $TRACK_NUMBER "$TEMPFILE.bytes" > "$TEMPFILE.bytes2"
	    mv "$TEMPFILE.bytes2" "$TEMPFILE.bytes"
	    head -n $TO_READ "$TEMPFILE.gpx2" > "$TEMPFILE.points"
	    B_GPX=0
	    wc -c < "$TEMPFILE.gpx2" > "$TEMPFILE.var"
	    read B_GPX < "$TEMPFILE.var"
	    B_PNT=0
	    wc -c < "$TEMPFILE.points" > "$TEMPFILE.var"
	    read B_PNT < "$TEMPFILE.var"

	    TO_READ="`expr $B_GPX - $B_PNT`"
	    
	    tail -c $TO_READ "$TEMPFILE.gpx2" > "$TEMPFILE.points"
	    mv "$TEMPFILE.points" "$TEMPFILE.gpx2"
	done

	# create attr table: cat(int), start_time varchar(40), start_lat(double precision), start_lon(double precision), \
	#			end_time varchar(40), end_lat(double precision), end_lon(double precision)
	
	ATTR_FILE="${TEMPFILE}.track_atts"
	ATTR_COLS='cat int, start_time varchar(40), start_lat double precision, start_lon double precision, end_time varchar(40), end_lat double precision, end_lon double precision'
    fi


    #### reproject if needed
    if [ "$IN_PROJ" = "$OUT_PROJ" ] || [ $KEEP_WGS84 -eq 1 ] ; then
	g.message "No projection transformation performed" 
	cat "${TEMPFILE}.base" | awk 'BEGIN {;} $1=="L" { print } ; \
	    $1!="L" { printf(" %s %s\n", $1, $2) } END {;}' > "${TEMPFILE}.P_base"
    else
	g.message "Attempting waypoint projection transform with cs2cs" 
	cs2cs -tL -f %.7f $IN_PROJ +to $OUT_PROJ < "${TEMPFILE}.base" > "${TEMPFILE}.P_mid"
	EXITCODE=$?
	 # check if transform REALLY worked (e.g. grid file not found)
	 BAD_PTS="`grep -c "^\*" "${TEMPFILE}.P_mid"`"
	if [ "$BAD_PTS" -gt 0 ] ; then
	    g.message message=""
	    g.message -w "$BAD_PTS vertices failed reprojection."
	    EXITCODE=1
	fi
	if [ $EXITCODE -ne 0 ] ; then
	    g.message "Projection transform failed, retaining WGS84" 
	    g.message message=""
	    cat "${TEMPFILE}.base" | awk 'BEGIN {;} $1=="L" { print } ; \
		$1!="L" { printf(" %s %s\n", $1, $2) } END {;}' > "${TEMPFILE}.P_base"
	else
	    cat "${TEMPFILE}.P_mid" | awk 'BEGIN {;} $1=="L" { print } ; \
		$1!="L" { printf(" %s %s\n", $1, $2) } END {;}' > "${TEMPFILE}.P_base"
	fi
    fi

    # add category numbers
    cat "${TEMPFILE}.P_base" | awk 'BEGIN { FS=" " ; R=0 } \
	$1=="L" { printf(" 1 %d\nL %d 1\n", R, $2) ; ++R } ; \
	$1!="L" { print } END { printf(" 1 %d\n", R) }' | sed -e '1d' > "${TEMPFILE}.P_baseC"


    #### create digit header
    cat << EOF > "${TEMPFILE}.dig"
ORGANIZATION: GRASSroots organization
DIGIT DATE:   `date "+%Y/%m/%d"`
DIGIT NAME:   $PROG
MAP NAME:     $NAME
MAP DATE:     `date +%Y`
MAP SCALE:    1
OTHER INFO:   Imported by `echo $USER@$HOSTNAME`
ZONE:	 0
MAP THRESH:   0
VERTI:
EOF

    #### merge in vertices
#HB#?? locale test fixed this
    cat "${TEMPFILE}.P_baseC" | tr ',' '.' >> "${TEMPFILE}.dig"

    #### if no name for vector file given, cat to stdout
    if [ -z "$NAME" ] ; then
	g.message "ASCII file redirected to stdout" 
	cat "${TEMPFILE}.dig" 2> /dev/null
    else
	#### import to binary vector file 
	g.message "Importing with v.in.ascii" 
	v.in.ascii format=standard output="$NAME" input="${TEMPFILE}.dig"

	#### check success/failure
	if [ $? -eq 0 ] ; then
	    g.message message="Line vector <$NAME> successfully created."
	else
	    g.message -e message='An error occured on creating <$NAME>, please check!'
	    exit 1
	fi

	## create db links if they don't exist
	db.connect -c
	DRIVER="`db.connect -p | grep '^driver:' | cut -f2 -d:`"
	if [ "$DRIVER" = "dbf" ] && [ ! -d "$LOCATION/dbf/" ] ; then
	    mkdir "$LOCATION/dbf/"
	fi

	g.message "Creating new table.."
	echo "CREATE TABLE $NAME ($ATTR_COLS)" | db.execute

	g.message "Populating table with attributes.."
	# echo "COPY $NAME FROM '$ATTR_FILE'" | db.execute

	# "COPY table FROM 'filename.txt'" does not work for DBF and there is no
	#   db.in.ascii yet, so we use a hack...

### <hack>
	if [ $RTE -eq 1 ] ; then
	    # =>  echo "INSERT INTO $NAME VALUES (2, 1, 'AB', 'B')" | db.execute
	    cat "$ATTR_FILE" | \
	      awk -F'|' '{
		printf("echo \"INSERT INTO $NAME VALUES (%d, %d, ^%s^, ^%s^)\" | db.execute\n", $1, $2, $3, $4) }' \
		    | tr '^' \' > "$ATTR_FILE"_exe
	fi
	if [ $TRK -eq 1 ] ; then
	    # =>  echo "INSERT INTO $NAME VALUES ()" | db.execute
	    cat "$ATTR_FILE" | \
	      awk -F'|' '{
		printf("echo \"INSERT INTO $NAME VALUES (%d, ^%s^, %s, %s, ^%s^, %s, %s)\" | db.execute\n", $1, $2, $3, $4, $5, $6, $7) }' \
		    | tr '^' \' > "$ATTR_FILE"_exe
	fi

	. "$ATTR_FILE"_exe
### </hack>

	g.message "Connecting attribute table to vector file..."
	v.db.connect map="$NAME" table="$NAME"
	EXITCODE=$?
    fi

fi  # if CREATE_POINTS or CREATE_LINES


# list column names
if [ $VERBOSE -eq 1 ] && [ -n "$NAME" ] ; then
    g.message message="<$NAME> columns:"
    db.columns "$NAME"
fi

# write cmd history:
v.support map="$NAME" cmdhist="${CMDLINE}"

#### clean up the mess
rm -f "${TEMPFILE}."* "${TEMPFILE}"

#### end
g.message "Done." 

exit $EXITCODE
