#!/bin/sh ############################################################################ # # MODULE: v.group for GRASS 6 # AUTHOR(S): Cedric Shock # PURPOSE: To group vector data collapsing it to fewer classes # COPYRIGHT: (C) 2006 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. # ############################################################################# # Todos: # Wishes: # This functionality should be more generalized and worked into v.reclass # Rework indentation without using tabs # More g.parser prompts would be awesome (column / layer selection, etc.) # Ultimately this sort of functionality belongs in the categorization in d.vect # Along with this we need a vector legend display. # Bugs # doesn't select type like reclass does # doesn't work with database connections # Usage example # v.group input=ownership output=groupedownership columns=LAND_OWN,LAND_MGR #%Module #% description: Groups and reclassifies vector data #%End #%option #% key: input #% type: string #% gisprompt: old,vector,vector #% description: Name of input vector #% required : yes #%end #%option #% key: output #% type: string #% gisprompt: new,dig,vector #% description: Name of output vector #% required : yes #%end #%option #% key: columns #% type: string #% description: Columns to group on #% required : yes #% multiple: yes #%end ##%option ##% key: type ##% type: string ##% description: Select type ##% options: point,line,boundary,centroid ##% answer: point,line,boundary,centroid ##% multiple: yes ##% required : no ##%end #%option #% key: layer #% type: integer #% description: Layer number #% answer: 1 #% 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 exec g.parser "$0" "$@" fi #### setup temporary file TMP="`g.tempfile pid=$$`" if [ $? -ne 0 ] || [ -z "$TMP" ] ; then echo "ERROR: unable to create temporary files" 1>&2 exit 1 fi #### trap ctrl-c so that we can clean up tmp trap 'rm -f ${TMP}*' 2 3 15 #eval `g.gisenv` #: ${GISBASE?} ${GISDBASE?} ${LOCATION_NAME?} ${MAPSET?} #LOCATION=$GISDBASE/$LOCATION_NAME/$MAPSET echo "Checking for columns:" 1>&2 COL=0 IFS=, for opt in $GIS_OPT_columns ; do ((COL++)) echo -n " $opt :" 1>&2 FOUND="`db.columns table=$GIS_OPT_input | fgrep $opt`" if [ $opt != $FOUND ] ; then echo " not found" 1>&2 echo "ERROR: table $GIS_OPT_input has no column $opt." 1>&2 exit 1 else echo " X" 1>&2 fi columns[$COL]=$opt columnlength[$COL]=2 done echo "Extracting Categories:" 1>&2 echo " select $GIS_OPT_columns from $GIS_OPT_input" 1>&2 DATA="`echo "select $GIS_OPT_columns from $GIS_OPT_input" | db.select -c | sort -u`" echo "Generating Rules:" 1>&2 RULESFILE=$TMP-rules SQLFILE=$TMP-sql echo "# Rules file generated by v.group" > $RULESFILE touch $SQLFILE CAT=0 IFS=" " for line in $DATA; do ((CAT++)) echo "cat $CAT" >> $RULESFILE echo -n "insert into $GIS_OPT_output values ( $CAT " >> $SQLFILE COL=0 IFS="|" for field in $line; do ((COL++)) if [ $COL = 1 ] ; then delimiter="where" else delimiter=" and" fi column=${columns[$COL]} length=${#field} if [ $length -gt ${columnlength[$COL]} ] ; then columnlength[$COL]=$length fi echo -n "$delimiter $column = '$field'" >> $RULESFILE echo -n ", '$field' " >> $SQLFILE done echo >> $RULESFILE echo ")" >> $SQLFILE done echo "Finishing SQL commands:" 1>&2 echo -n "create table $GIS_OPT_output (cat integer" > $TMP-sqlcopy COL=0 IFS=, for opt in $GIS_OPT_columns ; do ((COL++)) length=${columnlength[$COL]} ((length = length * 2)) echo -n ", $opt varchar($length)" >> $TMP-sqlcopy done echo ")" >> $TMP-sqlcopy cat $SQLFILE >> $TMP-sqlcopy mv $TMP-sqlcopy $SQLFILE #cat $RULESFILE #cat $SQLFILE echo "Reclassifying Map:" 1>&2 #echo "v.reclass input=$GIS_OPT_input output=$GIS_OPT_output type=$GIS_OPT_type layer=$GIS_OPT_layer rules=$RULESFILE" # We don't do type; it doesn't work for some reason # type=$GIS_OPT_type v.reclass input=$GIS_OPT_input output=$GIS_OPT_output layer=$GIS_OPT_layer rules=$RULESFILE echo "Creating Table:" 1>&2 IFS=" " SQLCOMMANDS="`cat $SQLFILE`" for cmd in $SQLCOMMANDS; do echo $cmd | db.execute done echo "Connecting Vector to table:" 1>&2 v.db.connect map=$GIS_OPT_output table=$GIS_OPT_output layer=$GIS_OPT_layer echo "Cleaning Up:" 1>&2 ## Clean up tmp rm -f ${TMP}* echo "Done." 1>&2