|
@@ -0,0 +1,314 @@
|
|
|
+#!/bin/sh
|
|
|
+#
|
|
|
+############################################################################
|
|
|
+#
|
|
|
+# MODULE: v.out.gps
|
|
|
+#
|
|
|
+# PURPOSE: Exports a GRASS vector map to a GPS receiver
|
|
|
+# or data file using GpsBabel
|
|
|
+#
|
|
|
+# COPYRIGHT: (c) 2008 Hamish Bowman, and 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.
|
|
|
+#
|
|
|
+# AUTHOR: Hamish Bowman, Dunedin, New Zealand
|
|
|
+#
|
|
|
+#############################################################################
|
|
|
+#
|
|
|
+# REQUIREMENTS:
|
|
|
+# - GpsBabel from http://gpsbabel.sourceforge.net
|
|
|
+# - cs2cs from PROJ.4 (for m.proj) http://proj.osgeo.org
|
|
|
+#
|
|
|
+# - report supported GpsBabel formats:
|
|
|
+# gpsbabel -^2 | tr '\t' ';' | sort -t';' -k3
|
|
|
+#
|
|
|
+#############################################################################
|
|
|
+#
|
|
|
+# How to do it
|
|
|
+# http://www.gdal.org/ogr/drv_gpx.html
|
|
|
+# gpsbabel [options] -i INTYPE -f INFILE -o OUTTYPE -F OUTFILE
|
|
|
+#
|
|
|
+#############################################################################
|
|
|
+
|
|
|
+#%Module
|
|
|
+#% description: Exports a vector map to a GPS receiver or file format supported by GpsBabel.
|
|
|
+#% keywords: vector, export, GPS
|
|
|
+#%End
|
|
|
+#%flag
|
|
|
+#% key: w
|
|
|
+#% description: Export as waypoints
|
|
|
+#%end
|
|
|
+#%flag
|
|
|
+#% key: r
|
|
|
+#% description: Export as routes
|
|
|
+#%end
|
|
|
+#%flag
|
|
|
+#% key: t
|
|
|
+#% description: Export as tracks
|
|
|
+#%end
|
|
|
+############ TODO:
|
|
|
+##%flag
|
|
|
+##% key: z
|
|
|
+##% description: Export altitude from 3D vector's z-coordinate
|
|
|
+##%end
|
|
|
+############
|
|
|
+#%option
|
|
|
+#% key: input
|
|
|
+#% type: string
|
|
|
+#% description: Name of input vector map
|
|
|
+#% gisprompt: old,vector,vector
|
|
|
+#% required: yes
|
|
|
+#%end
|
|
|
+#%option
|
|
|
+#% key: type
|
|
|
+#% type: string
|
|
|
+#% description: Feature type(s)
|
|
|
+#% options: point,centroid,line,boundary
|
|
|
+#% multiple: yes
|
|
|
+#%end
|
|
|
+#%option
|
|
|
+#% key: output
|
|
|
+#% type: string
|
|
|
+#% description: Name for output file or GPS device
|
|
|
+#% gisprompt: new_file,file,output
|
|
|
+#% key_desc: name
|
|
|
+#% required: yes
|
|
|
+#%end
|
|
|
+#%option
|
|
|
+#% key: format
|
|
|
+#% type: string
|
|
|
+#% description: GpsBabel supported output format
|
|
|
+#% answer: gpx
|
|
|
+#%end
|
|
|
+#%option
|
|
|
+#% key: layer
|
|
|
+#% type: integer
|
|
|
+#% label: Layer number
|
|
|
+#% description: A single vector map can be connected to multiple database tables. This number determines which table to use.
|
|
|
+#% answer: 1
|
|
|
+#% required : no
|
|
|
+#% guisection: Subset
|
|
|
+#%end
|
|
|
+#%option
|
|
|
+#% key: where
|
|
|
+#% type: string
|
|
|
+#% label: WHERE conditions of SQL statement without 'where' keyword
|
|
|
+#% description: Example: income < 1000 and inhab >= 10000
|
|
|
+#% required : no
|
|
|
+#% guisection: Subset
|
|
|
+#%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.osgeo.org"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+# check if we will overwrite data
|
|
|
+if [ -e "$GIS_OPT_OUTPUT" ] ; then
|
|
|
+ if [ -z "$GRASS_OVERWRITE" ] || [ "$GRASS_OVERWRITE" -ne 1 ] ; then
|
|
|
+ g.message -e "Output file already exists."
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+#### set temporary files
|
|
|
+TMP="`g.tempfile pid=$$`"
|
|
|
+if [ $? -ne 0 ] || [ -z "$TMP" ] ; then
|
|
|
+ g.message -e "Unable to create temporary files"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+cleanup()
|
|
|
+{
|
|
|
+ g.message -d "Cleaning up ..."
|
|
|
+ \rm -f "$TMP" "$TMP.gpx"
|
|
|
+ # only try to remove map if it exists to avoid ugly warnings
|
|
|
+ g.findfile element=vector file="tmp_vogb_epsg4326_$$" > /dev/null
|
|
|
+ if [ $? -eq 0 ] ; then
|
|
|
+ g.remove vect="tmp_vogb_epsg4326_$$" --quiet
|
|
|
+ fi
|
|
|
+ g.findfile element=vector file="tmp_vogb_extr_$$" > /dev/null
|
|
|
+ if [ $? -eq 0 ] ; then
|
|
|
+ g.remove vect="tmp_vogb_extr_$$" --quiet
|
|
|
+ fi
|
|
|
+}
|
|
|
+
|
|
|
+#### trap ctrl-c so that we can clean up tmp
|
|
|
+trap 'cleanup' 2 3 15
|
|
|
+
|
|
|
+
|
|
|
+#### process command line arguments
|
|
|
+WPT=$GIS_FLAG_W ; RTE=$GIS_FLAG_R ; TRK=$GIS_FLAG_T
|
|
|
+
|
|
|
+if [ $WPT -eq 1 ] && ([ $RTE -eq 1 ] || [ $TRK -eq 1 ]) ; then
|
|
|
+ g.message -e "One feature at a time please."
|
|
|
+ rm -f "${TMP}"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+# logic eludes me at pressent.. [combine with above]
|
|
|
+if [ $RTE -eq 1 ] && [ $TRK -eq 1 ] ; then
|
|
|
+ g.message -e "One feature at a time please."
|
|
|
+ rm -f "${TMP}"
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+if [ $WPT -eq 0 ] && [ $RTE -eq 0 ] && [ $TRK -eq 0 ] ; then
|
|
|
+ g.message -e "No features requested for export."
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+# set some reasonable defaults
|
|
|
+if [ $WPT -eq 1 ] ; then
|
|
|
+ if [ -z "$GIS_OPT_TYPE" ] ; then
|
|
|
+ GIS_OPT_TYPE="point"
|
|
|
+ fi
|
|
|
+else
|
|
|
+ if [ -z "$GIS_OPT_TYPE" ] ; then
|
|
|
+ GIS_OPT_TYPE="line"
|
|
|
+ fi
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+# SQL extract if needed
|
|
|
+if [ -n "$GIS_OPT_WHERE" ] ; then
|
|
|
+
|
|
|
+ v.extract in="$GIS_OPT_INPUT" out="tmp_vogb_extr_$$" \
|
|
|
+ type="$GIS_OPT_TYPE" layer="$GIS_OPT_LAYER" \
|
|
|
+ where="$GIS_OPT_WHERE" --quiet
|
|
|
+
|
|
|
+ if [ $? -ne 0 ] ; then
|
|
|
+ g.message -e "Error executing SQL query"
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ eval `v.info -t map="tmp_vogb_extr_$$"`
|
|
|
+ if [ "$primitives" -eq 0 ] ; then
|
|
|
+ g.message -e "SQL query returned an empty map"
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+ fi
|
|
|
+
|
|
|
+ INMAP="tmp_vogb_extr_$$"
|
|
|
+else
|
|
|
+ INMAP="$GIS_OPT_INPUT"
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+#### set up projection info
|
|
|
+# TODO: check if we are already in ll/WGS84. If so skip m.proj step.
|
|
|
+
|
|
|
+
|
|
|
+# TODO: multi layer will probably fail badly due to sed 's/^ 1 /'
|
|
|
+# output as old GRASS 4 vector ascii and fight with dig_ascii/?
|
|
|
+
|
|
|
+# reproject to lat/lon WGS84
|
|
|
+v.out.ascii in="$INMAP" format=standard | \
|
|
|
+ sed -e 's/^\([PLBCFKA]\)/#\1/' -e 's/^ 1 /# 1 /' | \
|
|
|
+ tail -n +11 | m.proj -od --quiet | \
|
|
|
+ sed -e 's/\t\([-\.0-9]*\) .*/ \1/' \
|
|
|
+ -e 's/^\([-\.0-9]\)/ \1/' \
|
|
|
+ -e 's/^#//' | \
|
|
|
+ v.in.ascii out=tmp_vogb_epsg4326_$$ -n format=standard --quiet
|
|
|
+
|
|
|
+if [ $? -ne 0 ] ; then
|
|
|
+ g.message -e "Error reprojecting data"
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+# export as GPX using v.out.ogr
|
|
|
+if [ $TRK -eq 1 ] ; then
|
|
|
+ LINETYPE="FORCE_GPX_TRACK=YES,"
|
|
|
+elif [ $RTE -eq 1 ] ; then
|
|
|
+ LINETYPE="FORCE_GPX_ROUTE=YES,"
|
|
|
+else
|
|
|
+ LINETYPE=""
|
|
|
+fi
|
|
|
+
|
|
|
+# TODO: cat is being reported as evelation? or is <ele>=element??
|
|
|
+# TODO: fix attribute output. ogr2ogr -sql to rename columns?
|
|
|
+# see http://www.gdal.org/ogr/drv_gpx.html
|
|
|
+
|
|
|
+v.out.ogr in=tmp_vogb_epsg4326_$$ dsn="$TMP.gpx" type="$GIS_OPT_TYPE" \
|
|
|
+ format=GPX lco="${LINETYPE}GPX_USE_EXTENSIONS=YES" --quiet
|
|
|
+
|
|
|
+if [ $? -ne 0 ] ; then
|
|
|
+ g.message -e "Error exporting data"
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+if [ "$GIS_OPT_FORMAT" = gpx ] ; then
|
|
|
+ # short circuit, we have what we came for.
|
|
|
+ mv "$TMP.gpx" "$GIS_OPT_OUTPUT"
|
|
|
+ cleanup
|
|
|
+ g.message -d "Fast exit"
|
|
|
+ exit 0
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+# run gpsbabel
|
|
|
+GTYPE=""
|
|
|
+if [ $WPT -eq 1 ] ; then
|
|
|
+ GTYPE="-w"
|
|
|
+elif [ $TRK -eq 1 ] ; then
|
|
|
+ GTYPE="-t"
|
|
|
+elif [ $RTE -eq 1 ] ; then
|
|
|
+ GTYPE="-r"
|
|
|
+fi
|
|
|
+
|
|
|
+gpsbabel $GTYPE -i gpx -f "$TMP.gpx" \
|
|
|
+ -o "$GIS_OPT_FORMAT" -F "$GIS_OPT_OUTPUT"
|
|
|
+
|
|
|
+if [ $? -ne 0 ] ; then
|
|
|
+ g.message -e "Error running GpsBabel"
|
|
|
+ cleanup
|
|
|
+ exit 1
|
|
|
+fi
|
|
|
+
|
|
|
+
|
|
|
+cleanup
|
|
|
+g.message -v "Done."
|
|
|
+exit
|