#!/bin/sh ############################################################################ # # MODULE: d.zoom.keys # AUTHOR(S): Alexander Muriy # (Institute of Environmental Geoscience, Moscow, Russia) # e-mail: amuriy AT gmail DOT com # # PURPOSE: Allows to change the current geographic region settings interactively, with a keyboard. # # COPYRIGHT: (C) 02/2012 Alexander Muriy / GRASS Development Team # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # ############################################################################ #%Module #% description: Allows to change the current geographic region settings interactively, with a keyboard. Use arrow keys to navigate, "-" to make futher, "+" (without "Shift") to make closer. #% keywords: display, zoom #%End #%Option #% key: mon #% type: string #% required: no #% key_desc: name #% description: Name of graphics monitor to select (default is currently selected monitor). #%End #%Option #% key: magn #% type: double #% required: no #% multiple: no #% key_desc: number #% description: Magnification: default is "1" (1/10 of current region). "magn" > 1 gives positive magnification, "magn" < 1 gives negative one. #%End #%Flag #% key: t #% description: Use navigation from terminal #%End #%Flag #% key: x #% description: Use navigation in X-monitor (requires and ) #%End #%Flag #% key: r #% description: Decrease region resolution during navigation #%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 ## set environment so that awk works properly in all languages ## unset LC_ALL export LC_NUMERIC=C ############################################################ cleanup() { rm -f "$TMP*" if [ "$GIS_FLAG_T" -eq 1 ]; then stty "$tty_save" fi if [ "$GIS_FLAG_R" -eq 1 ]; then g.region nsres="$OLD_NSRES" ewres="$OLD_EWRES" d.redraw --q fi } ############################################################ ## what to do in case of user break: exitprocedure() { echo "" echo "User break!" cleanup exit 1 } ## shell check for user break (signal list: trap -l) trap "exitprocedure" 2 3 15 ############################################################ ## check for if [ "$GIS_FLAG_X" -eq 1 ] && [ ! -x "$(which xev)" ] ; then g.message -e " required, please install it first" exit 1 fi ## check for if [ "$GIS_FLAG_X" -eq 1 ] && [ ! -x "$(which xdotool)" ] ; then g.message -e " required, please install it first" exit 1 fi ## check for if [ ! -x "$(which awk)" ] ; then g.message -e " required, please install or first" exit 1 fi ############################################################ ## setup temporary files TMP="$(g.tempfile pid=$$)" if [ "$?" -ne 0 ] || [ -z "$TMP" ] ; then g.message -e "ERROR: Unable to create temporary files." exit 1 fi ############################################################ ## DO IT if [ "$(d.mon -p | cut -f1 -d' ')" != "Currently" ] ; then g.message -e "No active monitors. Please start first" exit 1 fi if [ "$GIS_FLAG_X" -eq 0 ] && [ "$GIS_FLAG_T" -eq 0 ]; then g.message -e "Please select method of navigation: flag \"-t\" from terminal or flag \"-x\" from X-monitor" exit 1 fi if [ "$GIS_FLAG_X" -eq 1 ] && [ "$GIS_FLAG_T" -eq 1 ]; then g.message -e "Please select one method of navigation: flag \"-t\" from terminal or flag \"-x\" from X-monitor" exit 1 fi MAGN_NEGAT=$(echo "$GIS_OPT_MAGN" | grep "-") if [ "$MAGN_NEGAT" ]; then g.message -e "Magnification should be a positive number: default is "1" (1/10 of current region). "magn" > 1 gives positive magnification, "magn" < 1 gives negative one." exit 1 fi ## region stuff if [ "$GIS_FLAG_R" -eq 1 ]; then eval $(g.region -g) OLD_NSRES="$nsres" OLD_EWRES="$ewres" curr_res=$(echo "$nsres" "$ewres" | awk '{x=($1+$2)/2; print x}') tmp_res=$(echo "$curr_res" | awk '{x=$1*3; print x}') g.region res="$tmp_res" fi eval $(g.region -eg) ns_extent_round=$(printf "%.0f\n" $ns_extent) ew_extent_round=$(printf "%.0f\n" $ew_extent) if [ -z "$GIS_OPT_MAGN" ]; then MAGN=1 else MAGN="$GIS_OPT_MAGN" fi east_step=$(echo $ew_extent_round "$MAGN" | awk '{e=($1/10)*$2; print e}') north_step=$(echo $ns_extent_round "$MAGN" | awk '{n=($1/10)*$2; print n}') ## monitors stuff curr_mon=$(d.mon -p | cut -d':' -f2 | sed 's/^ //g') if [ -z "$GIS_OPT_MON" ]; then MON="$curr_mon" else MON="$GIS_OPT_MON" fi NOT_RUN=$(d.mon -L | grep "$MON" | grep "not running") if [ -z "$NOT_RUN" ]; then d.mon select="$MON" else g.message -e "Monitor <"$MON"> is not running. Please run or select it first" exit 1 fi #### navigation in X-monitor if [ "$GIS_FLAG_X" -eq 1 ]; then ### make actions scripts for AWK for ACTIONS in up down left right closer futher; do SCRIPT="${TMP}_"$ACTIONS".sh" echo '#!/bin/sh' > $SCRIPT case "$ACTIONS" in up) echo "g.region n=n-"$north_step" s=s-"$north_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; down) echo "g.region n=n+"$north_step" s=s+"$north_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; left) echo "g.region w=w+"$east_step" e=e+"$east_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; right) echo "g.region w=w-"$east_step" e=e-"$east_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; closer) echo "g.region w=w+"$east_step" e=e-"$east_step" n=n-"$north_step" s=s+"$north_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; futher) echo "g.region w=w-"$east_step" e=e+"$east_step" n=n+"$north_step" s=s-"$north_step"" >> $SCRIPT echo "d.redraw --q" >> $SCRIPT ;; esac done eval $(g.gisenv) GRASS_version=$(g.version -g | grep "version" | cut -d'=' -f2) window_search="GRASS "${GRASS_version}" - Monitor: "${MON}" - Location: "${LOCATION_NAME}"" GRASS_wid=$(xdotool search --title "${window_search}") xdotool windowactivate "${GRASS_wid}" xev -id "${GRASS_wid}" | awk '/keycode/ {print $4; fflush()}' | while read -r xev_code; do awk -v TMP="$TMP" -v xev="${xev_code}" 'NR % 2 { next } { if ($0 == 111) system ("sh "TMP"_up.sh") else if ($0 == 116) system ("sh "TMP"_down.sh") else if ($0 == 113) system ("sh "TMP"_left.sh") else if ($0 == 114) system ("sh "TMP"_right.sh") else if ($0 == 20) system ("sh "TMP"_futher.sh") else if ($0 == 21) system ("sh "TMP"_closer.sh") }' done fi #### navigation in terminal if [ "$GIS_FLAG_T" -eq 1 ]; then tty_save=$(stty -g) get_odx() { od -t o1 | awk '{ for (i=2; i<=NF; i++) printf("%s%s", i==2 ? "" : " ", $i) exit }' } # Grab terminal capabilities tty_cuu1=$(tput cuu1 2>&1 | get_odx) # up arrow tty_kcuu1=$(tput kcuu1 2>&1 | get_odx) tty_cud1=$(tput cud1 2>&1 | get_odx) # down arrow tty_kcud1=$(tput kcud1 2>&1 | get_odx) tty_cub1=$(tput cub1 2>&1 | get_odx) # left arrow tty_kcub1=$(tput kcud1 2>&1 | get_odx) tty_cuf1=$(tput cuf1 2>&1 | get_odx) # right arrow tty_kcuf1=$(tput kcud1 2>&1 | get_odx) # Some terminals send the wrong code for certain arrow keys if [ "$tty_cuu1" = "033 133 101" -o "$tty_kcuu1" = "033 133 101" ]; then tty_cudx="033 133 102" tty_cufx="033 133 103" tty_cubx="033 133 104" fi stty cs8 -icanon -echo min 10 time 1 stty intr '' susp '' while true; do keypress=$(dd bs=10 count=1 2> /dev/null | get_odx) case "$keypress" in "$tty_cuu1"|"$tty_kcuu1") g.region n=n-"$north_step" s=s-"$north_step" d.redraw --q ;; "$tty_cud1"|"$tty_kcud1"|"$tty_cudx") g.region n=n+"$north_step" s=s+"$north_step" d.redraw --q ;; "$tty_cub1"|"$tty_kcub1"|"$tty_cubx") g.region w=w+"$east_step" e=e+"$east_step" d.redraw --q ;; "$tty_cuf1"|"$tty_kcuf1"|"$tty_cufx") g.region w=w-"$east_step" e=e-"$east_step" d.redraw --q ;; 055) g.region w=w-"$east_step" e=e+"$east_step" n=n+"$north_step" s=s-"$north_step" d.redraw --q ;; 075) g.region w=w+"$east_step" e=e-"$east_step" n=n-"$north_step" s=s+"$north_step" d.redraw --q ;; 003) echo "User break!" stty $tty_save; break ;; esac done fi cleanup exit 0