From ullah at grass.itc.it Mon Oct 1 20:06:28 2007
From: ullah at grass.itc.it (ullah@grass.itc.it)
Date: Mon Oct 1 20:06:29 2007
Subject: [grass-addons] r1118 - trunk/grassaddons/LandDyn/r.landscape.evol
Message-ID: <200710011806.l91I6SK3023572@grass.itc.it>
Author: ullah
Date: 2007-10-01 20:06:22 +0200 (Mon, 01 Oct 2007)
New Revision: 1118
Modified:
trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol
Log:
updated statsout option to actually work...
Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol
===================================================================
--- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-30 20:23:45 UTC (rev 1117)
+++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-10-01 18:06:22 UTC (rev 1118)
@@ -775,15 +775,15 @@
g.remove --quiet rast=$tmperosion,$tmpdep
- if [ -e $GIS_OPT_statsout ]; then
+ if [ -z $GIS_OPT_statsout ]; then
- txtout=$GIS_OPT_statsout
+ mapset=`eval g.gisenv get=MAPSET`
+ txtout=$mapset"_"$prefx"_lsevol_stats.txt"
else
+
+ txtout=$GIS_OPT_statsout
- mapset=`eval g.gisenv get=MAPSET`
- txtout=$mapset"_"$prefx"_lsevol_stats.txt"
-
fi
echo "outputing stats to textfile: $txtout"
From ullah at grass.itc.it Wed Oct 3 22:16:54 2007
From: ullah at grass.itc.it (ullah@grass.itc.it)
Date: Wed Oct 3 22:16:55 2007
Subject: [grass-addons] r1119 - in trunk/grassaddons/LandDyn: . r.cfactor
Message-ID: <200710032016.l93KGsD9002627@grass.itc.it>
Author: ullah
Date: 2007-10-03 22:16:46 +0200 (Wed, 03 Oct 2007)
New Revision: 1119
Added:
trunk/grassaddons/LandDyn/r.cfactor/
trunk/grassaddons/LandDyn/r.cfactor/r.cfactor
trunk/grassaddons/LandDyn/r.cfactor/rules/
Log:
Added the r.cfactor module, and example rules test files needed to run it.
Added: trunk/grassaddons/LandDyn/r.cfactor/r.cfactor
===================================================================
--- trunk/grassaddons/LandDyn/r.cfactor/r.cfactor (rev 0)
+++ trunk/grassaddons/LandDyn/r.cfactor/r.cfactor 2007-10-03 20:16:46 UTC (rev 1119)
@@ -0,0 +1,110 @@
+#!/bin/sh
+#
+############################################################################
+#
+# MODULE: r.cfactor
+# AUTHOR(S): Isaac Ullah, Michael Barton, Arizona State University
+# PURPOSE: Converts a map of landcover values to a c-factor map based
+# on a set of reclass rules
+# ACKNOWLEDGEMENTS: National Science Foundation Grant #BCS0410269
+# COPYRIGHT: (C) 2007 by Isaac Ullah, Michael Barton, Arizona State University
+# This program is free software under the GNU General Public
+# License (>=v2). Read the file COPYING that comes with GRASS
+# for details.
+#
+#############################################################################
+
+
+#%Module
+#% description: Converts a map of landcover values to a c-factor map based on a set of reclass rules
+#%END
+
+#%option
+#% key: inmap
+#% type: string
+#% gisprompt: old,cell,raster
+#% description: input landcover map (integer values aligned with reclass rules)
+#% required : yes
+#%END
+
+#%option
+#% key: outcfact
+#% type: string
+#% gisprompt: string
+#% description: c_factor output map name
+#% answer: year1_cfactor
+#% required : yes
+#%END
+
+#%option
+#% key: cfact_rules
+#% type: string
+#% gisprompt: string
+#% description: path to recode rules file for c-factor map
+#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_recode_rules.txt
+#% required : yes
+#%END
+
+#%option
+#% key: cfact_color
+#% type: string
+#% gisprompt: string
+#% description: path to color rules file for c-factor map
+#% answer: /usr/local/grass-6.3.cvs/scripts/rules/cfactor_colors.txt
+#% required : yes
+#%END
+
+
+
+if [ -z "$GISBASE" ] ; then
+ echo "You must be in GRASS GIS to run this program." >&2
+ exit 1
+fi
+
+if [ "$1" != "@ARGS_PARSED@" ] ; then
+ exec g.parser "$0" "$@"
+fi
+
+
+
+#setting up variables for use later on
+
+inmap=$GIS_OPT_inmap
+
+outcfact=$GIS_OPT_outcfact
+
+cfact_rules=$GIS_OPT_cfact_rules
+
+cfact_color=$GIS_OPT_cfact_color
+
+#setting initial conditions of map area
+
+g.region rast=$inmap
+
+r.mask --quiet input=$inmap maskcats=*
+
+#creating c-factor map and setting colors
+
+ cat $cfact_rules | r.recode input=$inmap output=$outcfact
+
+ r.colors map=$outcfact rules=$cfact_color
+
+
+
+
+echo ""
+echo "*************************"
+echo " Cleaning up"
+echo "*************************"
+echo ""
+
+
+g.remove --quiet rast=MASK
+
+
+
+echo ""
+echo "DONE!"
+echo ""
+echo ""
+
Property changes on: trunk/grassaddons/LandDyn/r.cfactor/r.cfactor
___________________________________________________________________
Name: svn:executable
+ *
From landa at grass.itc.it Thu Oct 4 15:28:13 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 4 15:28:15 2007
Subject: [grass-addons] r1120 - in trunk/grassaddons/gui/screenshots: .
digitization general
Message-ID: <200710041328.l94DSDab016166@grass.itc.it>
Author: landa
Date: 2007-10-04 15:28:10 +0200 (Thu, 04 Oct 2007)
New Revision: 1120
Added:
trunk/grassaddons/gui/screenshots/digitization/
trunk/grassaddons/gui/screenshots/digitization/digit-01.png
trunk/grassaddons/gui/screenshots/digitization/digit-02.png
trunk/grassaddons/gui/screenshots/digitization/digit-03.png
trunk/grassaddons/gui/screenshots/digitization/digit-attributes.png
trunk/grassaddons/gui/screenshots/digitization/digit-gism.png
trunk/grassaddons/gui/screenshots/digitization/digit-mapdisplay.png
trunk/grassaddons/gui/screenshots/digitization/digit-move.png
trunk/grassaddons/gui/screenshots/digitization/digit-new-feature.png
trunk/grassaddons/gui/screenshots/digitization/digit-settings-1.png
trunk/grassaddons/gui/screenshots/digitization/digit-settings.png
trunk/grassaddons/gui/screenshots/general/
trunk/grassaddons/gui/screenshots/general/aui-toolbars.png
trunk/grassaddons/gui/screenshots/general/dbmanager-01.png
trunk/grassaddons/gui/screenshots/general/gism-0.png
trunk/grassaddons/gui/screenshots/general/mapdisplay-0.png
trunk/grassaddons/gui/screenshots/general/wxgrass-2007-03-mac.png
trunk/grassaddons/gui/screenshots/general/wxgrass-2007-05-linux.png
Removed:
trunk/grassaddons/gui/screenshots/aui-toolbars.png
trunk/grassaddons/gui/screenshots/dbmanager-01.png
trunk/grassaddons/gui/screenshots/digit-01.png
trunk/grassaddons/gui/screenshots/digit-02.png
trunk/grassaddons/gui/screenshots/digit-03.png
trunk/grassaddons/gui/screenshots/digit-attributes.png
trunk/grassaddons/gui/screenshots/digit-gism.png
trunk/grassaddons/gui/screenshots/digit-mapdisplay.png
trunk/grassaddons/gui/screenshots/digit-move.png
trunk/grassaddons/gui/screenshots/digit-new-feature.png
trunk/grassaddons/gui/screenshots/digit-settings-1.png
trunk/grassaddons/gui/screenshots/digit-settings.png
trunk/grassaddons/gui/screenshots/gism-0.png
trunk/grassaddons/gui/screenshots/mapdisplay-0.png
trunk/grassaddons/gui/screenshots/wxgrass-2007-03-mac.png
trunk/grassaddons/gui/screenshots/wxgrass-2007-05-linux.png
Log:
reorganization, sections added
Deleted: trunk/grassaddons/gui/screenshots/aui-toolbars.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/dbmanager-01.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-01.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-02.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-03.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-attributes.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-gism.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-mapdisplay.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-move.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-new-feature.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-settings-1.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/digit-settings.png
===================================================================
(Binary files differ)
Added: trunk/grassaddons/gui/screenshots/digitization/digit-01.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-01.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-02.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-02.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-03.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-03.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-attributes.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-attributes.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-gism.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-gism.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-mapdisplay.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-mapdisplay.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-move.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-move.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-new-feature.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-new-feature.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-settings-1.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-settings-1.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/digitization/digit-settings.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/digitization/digit-settings.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/aui-toolbars.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/aui-toolbars.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/dbmanager-01.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/dbmanager-01.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/gism-0.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/gism-0.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/mapdisplay-0.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/mapdisplay-0.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/wxgrass-2007-03-mac.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/wxgrass-2007-03-mac.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/screenshots/general/wxgrass-2007-05-linux.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/screenshots/general/wxgrass-2007-05-linux.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Deleted: trunk/grassaddons/gui/screenshots/gism-0.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/mapdisplay-0.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/wxgrass-2007-03-mac.png
===================================================================
(Binary files differ)
Deleted: trunk/grassaddons/gui/screenshots/wxgrass-2007-05-linux.png
===================================================================
(Binary files differ)
From ullah at grass.itc.it Fri Oct 5 00:02:56 2007
From: ullah at grass.itc.it (ullah@grass.itc.it)
Date: Fri Oct 5 00:02:58 2007
Subject: [grass-addons] r1121 -
trunk/grassaddons/LandDyn/devs_landcover_scripts/rules
Message-ID: <200710042202.l94M2uq3023429@grass.itc.it>
Author: ullah
Date: 2007-10-05 00:02:50 +0200 (Fri, 05 Oct 2007)
New Revision: 1121
Modified:
trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt
Log:
updated rules text file
Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt
===================================================================
--- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt 2007-10-04 13:28:10 UTC (rev 1120)
+++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_recode_rules.txt 2007-10-04 22:02:50 UTC (rev 1121)
@@ -1,7 +1,7 @@
-0:2:0.8:0.6
-3:7:0.6:0.3
-8:12:0.3:0.1
-13:18:0.1:0.08
-19:37:0.08:0.06
-38:50:0.06:0.05
+0:2:0.1:0.08
+3:7:0.08:0.05
+8:12:0.05:0.03
+13:18:0.03:0.01
+19:37:0.01:0.008
+38:50:0.008:0.005
end
From ullah at grass.itc.it Fri Oct 5 00:04:14 2007
From: ullah at grass.itc.it (ullah@grass.itc.it)
Date: Fri Oct 5 00:04:15 2007
Subject: [grass-addons] r1122 - trunk/grassaddons/LandDyn
Message-ID: <200710042204.l94M4E76023449@grass.itc.it>
Author: ullah
Date: 2007-10-05 00:04:08 +0200 (Fri, 05 Oct 2007)
New Revision: 1122
Removed:
trunk/grassaddons/LandDyn/r.cfactor/
Log:
got rid of eroneous script....
From landa at grass.itc.it Fri Oct 5 10:40:53 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 5 10:40:54 2007
Subject: [grass-addons] r1123 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710050840.l958eroi031079@grass.itc.it>
Author: landa
Date: 2007-10-05 10:40:52 +0200 (Fri, 05 Oct 2007)
New Revision: 1123
Modified:
trunk/grassaddons/gui/gui_modules/gcmd.py
trunk/grassaddons/gui/gui_modules/menuform.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
Log:
Minor fixes, use default parameters (menuform).
Modified: trunk/grassaddons/gui/gui_modules/gcmd.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-04 22:04:08 UTC (rev 1122)
+++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-05 08:40:52 UTC (rev 1123)
@@ -88,8 +88,9 @@
# set message formatting
#
message_format = os.getenv("GRASS_MESSAGE_FORMAT")
- os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
-
+ # os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
+ os.environ["GRASS_MESSAGE_FORMAT"] = "txt"
+
#
# run command ...
#
@@ -123,14 +124,15 @@
#
# read stderr
# ...
- self.messages = []
- self.errors = []
- self.warnings = []
- try:
- self.__ProcessMessages() # -> messages, errors, warnings
- except EndOfCommand:
- pass
+ # self.messages = []
+ # self.errors = []
+ # self.warnings = []
+ # try:
+ # self.__ProcessMessages() # -> messages, errors, warnings
+ # except EndOfCommand:
+ # pass
+
if self.module:
if wait:
self.module.wait()
@@ -138,9 +140,10 @@
# failed?
if dlgMsg and self.returncode != 0:
+ errs = self.ReadErrOutput()
if dlgMsg == 'gui': # GUI dialog
dlg = wx.MessageDialog(None,
- ("Execution failed: '%s'") % (' '.join(self.cmd)),
+ ("Execution failed: '%s'\n\nDetails:\n%s") % (' '.join(self.cmd), '\n'.join(errs)),
("Error"), wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
@@ -181,21 +184,32 @@
else:
self.messages.append(content)
- def ReadStdOutput(self):
- """Read standard output and return list
+ def __ReadOutput(self, stream):
+ """Read stream and return list of lines
Note: Remove '\n' from output (TODO: '\r\n' ??)
"""
lineList = []
while True:
- line = self.module_stdout.readline()
+ line = stream.readline()
if not line:
break
line = line.replace('\n', '')
lineList.append(line)
return lineList
+
+ def ReadStdOutput(self):
+ """Read standard output and return list"""
+ return self.__ReadOutput(self.module_stdout)
+
+ def ReadErrOutput(self):
+ """Read standard error output and return list"""
+
+ return self.__ReadOutput(self.module_stderr)
+
+
# testing ...
if __name__ == "__main__":
SEP = "-----------------------------------------------------------------------------"
Modified: trunk/grassaddons/gui/gui_modules/menuform.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-04 22:04:08 UTC (rev 1122)
+++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-05 08:40:52 UTC (rev 1123)
@@ -81,6 +81,7 @@
sys.path.append(imagepath)
import select
+import gcmd
try:
import subprocess
except:
@@ -228,10 +229,13 @@
cmd += [ '-' + flag['name'] ]
for p in self.params:
if p.get('value','') == '' and p.get('required','no') != 'no':
- cmd += [ '%s=%s' % ( p['name'], _('') ) ]
- errStr += _("Parameter %s (%s) is missing\n") % ( p['name'], p['description'] )
- errors += 1
- if p.get('value','') != '' and p['value'] != p.get('default','') :
+ if p.get('default', '') != '':
+ cmd += [ '%s=%s' % ( p['name'], p['default'] ) ]
+ else:
+ cmd += [ '%s=%s' % ( p['name'], _('') ) ]
+ errStr += _("Parameter %s (%s) is missing.\n") % ( p['name'], p['description'] )
+ errors += 1
+ elif p.get('value','') != '' and p['value'] != p.get('default','') :
# Output only values that have been set, and different from defaults
cmd += [ '%s=%s' % ( p['name'], p['value'] ) ]
if errors and not ignoreErrors:
@@ -474,7 +478,6 @@
if findALink is None and findImgLink is None:
contents.append( l )
self.SetPage( "".join( contents ) )
- print "#", contents
self.Ok = True
except: # The Manual file was not found
self.Ok = False
@@ -606,7 +609,7 @@
constrained_size = self.notebookpanel.GetSize()
self.notebookpanel.SetSize( (constrained_size[0],constrained_size[1]+80) ) # 80 takes the tabbar into account
self.notebookpanel.Layout()
-
+
# for too long descriptions
self.description = StaticWrapText (parent=self, label=self.task.description)
topsizer.Add (item=self.description, proportion=1, border=5,
@@ -642,7 +645,7 @@
"""Run the command"""
cmd = self.createCmd()
- if cmd == []:
+ if cmd == [] or cmd == None:
return
# change page if needed
@@ -659,14 +662,15 @@
print >> sys.stderr, "parent window is: %s" % (str(self.parent))
# Send any other command to the shell.
else:
- try:
- retcode = subprocess.call(cmd, shell=True)
- if retcode < 0:
- print >>sys.stderr, "Child was terminated by signal", -retcode
- elif retcode > 0:
- print >>sys.stderr, "Child returned", retcode
- except OSError, e:
- print >>sys.stderr, "Execution failed:", e
+ runCmd = gcmd.Command(cmd)
+ # try:
+ # retcode = subprocess.call(cmd, shell=True)
+ # if retcode < 0:
+ # print >>sys.stderr, "Child was terminated by signal", -retcode
+ # elif retcode > 0:
+ # print >>sys.stderr, "Child returned", retcode
+ # except OSError, e:
+ # print >>sys.stderr, "Execution failed:", e
def OnCopy(self, event):
"""Copy the command"""
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-04 22:04:08 UTC (rev 1122)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-05 08:40:52 UTC (rev 1123)
@@ -172,7 +172,7 @@
trgif = Icons["addrnum"].GetBitmap(bmpsize)
self.rnum_icon = il.Add(trgif)
- trgif = Icons["elvect"].GetBitmap(bmpsize)
+ trgif = Icons["addvect"].GetBitmap(bmpsize)
self.vect_icon = il.Add(trgif)
trgif = Icons["addthematic"].GetBitmap(bmpsize)
From ullah at grass.itc.it Fri Oct 5 19:07:38 2007
From: ullah at grass.itc.it (ullah@grass.itc.it)
Date: Fri Oct 5 19:07:39 2007
Subject: [grass-addons] r1124 -
trunk/grassaddons/LandDyn/devs_landcover_scripts/rules
Message-ID: <200710051707.l95H7cOr004943@grass.itc.it>
Author: ullah
Date: 2007-10-05 19:07:32 +0200 (Fri, 05 Oct 2007)
New Revision: 1124
Modified:
trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt
Log:
updated cfactor color rules file to match updated cfactor recode rules values
Modified: trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt
===================================================================
--- trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt 2007-10-05 08:40:52 UTC (rev 1123)
+++ trunk/grassaddons/LandDyn/devs_landcover_scripts/rules/cfactor_colors.txt 2007-10-05 17:07:32 UTC (rev 1124)
@@ -1,6 +1,6 @@
-0.8 grey
-0.5 red
-0.3 orange
-0.1 brown
-0.08 yellow
-0.05 green
+0.1 grey
+0.05 red
+0.03 orange
+0.01 brown
+0.008 yellow
+0.005 green
From landa at grass.itc.it Sun Oct 7 11:02:28 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Sun Oct 7 11:02:31 2007
Subject: [grass-addons] r1125 - in trunk/grassaddons/gui: display_driver
gui_modules
Message-ID: <200710070902.l9792Sau009537@grass.itc.it>
Author: landa
Date: 2007-10-07 11:02:21 +0200 (Sun, 07 Oct 2007)
New Revision: 1125
Modified:
trunk/grassaddons/gui/display_driver/driver.cpp
trunk/grassaddons/gui/display_driver/driver.h
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/gcmd.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/toolbars.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
Log:
Digitization tool: various fixes, driver optimalization
Modified: trunk/grassaddons/gui/display_driver/driver.cpp
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-07 09:02:21 UTC (rev 1125)
@@ -31,7 +31,6 @@
G_gisinit(""); /* GRASS functions */
mapInfo = NULL;
- dcId = 1;
dc = (wxPseudoDC *) device;
@@ -39,7 +38,7 @@
pointsScreen = new wxList();
cats = Vect_new_cats_struct();
- topology.recorded = true;
+ drawSegments = false;
}
/**
@@ -90,14 +89,10 @@
BOUND_BOX mapBox;
struct ilist *listLines;
- // initialize
- dcId = 1;
- ids.clear();
+ // ids.clear();
listLines = Vect_new_list();
- if (force) {
- ResetTopology();
- }
+ ResetTopology();
/* nlines = Vect_get_num_lines(mapInfo); */
@@ -131,22 +126,16 @@
#endif
bool inBox;
- for (int line = 1; line <= Vect_get_num_lines(mapInfo); line++) {
- if (Vect_val_in_list(listLines, line))
- inBox = true;
- else
- inBox = false;
- DrawLine(line, inBox);
+ dc->BeginDrawing();
+ for (int i = 0; i < listLines->n_values; i++) {
+ DrawLine(listLines->value[i]);
}
+ dc->EndDrawing();
#ifdef DEBUG
PrintIds();
#endif
- if (force) {
- topology.recorded = true;
- }
-
Vect_destroy_list(listLines);
return listLines->n_values;
@@ -156,39 +145,44 @@
\brief Draw selected vector objects to the device
\param[in] line id
- \param[in] inBox line inside of current region?
\return 1 on success
\return -1 on failure (vector object is dead, etc.)
*/
-int DisplayDriver::DrawLine(int line, bool inBox)
+int DisplayDriver::DrawLine(int line)
{
if (!dc || !Vect_line_alive (mapInfo, line))
return -1;
+ int dcId; // 0 | 1 | segment id
int type; // line type
- int x, y, z; // screen coordinates
+ double x, y, z; // screen coordinates
bool draw; // draw object ?
+ wxPen *pen;
+
// read line
type = Vect_read_line (mapInfo, points, cats, line);
// add ids
// -> node1, line1, vertex1, line2, ..., node2
- struct lineDesc desc = {points->n_points, dcId};
- ids[line] = desc;
+ // struct lineDesc desc = {points->n_points, dcId};
+ // ids[line] = desc;
// update id for next line
- dcId += points->n_points * 2 - 1;
+ // dcId += points->n_points * 2 - 1;
if (IsSelected(line)) { // line selected ?
- dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID));
+ pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
draw = true;
+ dcId = 1;
+ topology.highlight++;
}
- else if (!topology.recorded) { // determine color of vector object
+ else {
+ dcId = 0;
if (type & GV_LINES) {
switch (type) {
case GV_LINE:
- dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID));
- topology.line.push_back(line);
+ pen = new wxPen(settings.line.color, settings.lineWidth, wxSOLID);
+ topology.line++;
draw = settings.line.enabled;
break;
case GV_BOUNDARY:
@@ -196,18 +190,18 @@
Vect_get_line_areas(mapInfo, line,
&left, &right);
if (left == 0 && right == 0) {
- dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID));
- topology.boundaryNo.push_back(line);
+ pen = new wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID);
+ topology.boundaryNo++;
draw = settings.boundaryNo.enabled;
}
else if (left > 0 && right > 0) {
- dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID));
- topology.boundaryTwo.push_back(line);
+ pen = new wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID);
+ topology.boundaryTwo++;
draw = settings.boundaryTwo.enabled;
}
else {
- dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID));
- topology.boundaryOne.push_back(line);
+ pen = new wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID);
+ topology.boundaryOne++;
draw = settings.boundaryOne.enabled;
}
break;
@@ -218,33 +212,33 @@
}
else if (type & GV_POINTS) {
if (type == GV_POINT && settings.point.enabled) {
- dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID));
- topology.point.push_back(line);
+ pen = new wxPen(settings.point.color, settings.lineWidth, wxSOLID);
+ topology.point++;
draw = settings.point.enabled;
}
else if (type == GV_CENTROID) {
int cret = Vect_get_centroid_area(mapInfo, line);
if (cret > 0) { // -> area
draw = settings.centroidIn.enabled;
- dc->SetPen(wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID));
- topology.centroidIn.push_back(line);
+ pen = new wxPen(settings.centroidIn.color, settings.lineWidth, wxSOLID);
+ topology.centroidIn++;
}
else if (cret == 0) {
draw = settings.centroidOut.enabled;
- dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID));
- topology.centroidOut.push_back(line);
+ pen = new wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID);
+ topology.centroidOut++;
}
else {
draw = settings.centroidDup.enabled;
- dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID));
- topology.centroidDup.push_back(line);
+ pen = new wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID);
+ topology.centroidDup++;
}
}
}
}
-
+
// draw object
- if (inBox && draw) {
+ if (draw) {
// clear screen points & convert EN -> xy
pointsScreen->Clear();
for (int i = 0; i < points->n_points; i++) {
@@ -253,30 +247,47 @@
pointsScreen->Append((wxObject*) new wxPoint(x, y)); /* TODO: 3D */
}
+ dc->SetId(dcId); /* 0 | 1 (selected) */
+ dc->SetPen(*pen);
+
if (type & GV_POINTS) {
DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData());
}
else {
- long int startId = ids[line].startId + 1;
-
- for (int i = 0; i < pointsScreen->GetCount() - 1; startId += 2) {
+ // long int startId = ids[line].startId + 1;
+ if (dcId > 0 && drawSegments) {
+ dcId = 2; // first segment
+ for (int i = 0; i < pointsScreen->GetCount() - 1; dcId += 2) {
wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData();
-
+
// set bounds for line
// wxRect rect (*point_beg, *point_end);
// dc->SetIdBounds(startId, rect);
- // draw line if needed
- dc->SetId(startId);
+ dc->SetId(dcId); // set unique id & set bbox for each segment
+ dc->SetPen(*pen);
+ wxRect rect (*point_beg, *point_end);
+ dc->SetIdBounds(dcId, rect);
dc->DrawLine(point_beg->x, point_beg->y,
point_end->x, point_end->y);
+ }
}
+ else {
+ wxPoint points[pointsScreen->GetCount()];
+ for (int i = 0; i < pointsScreen->GetCount(); i++) {
+ wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData();
+ points[i] = *point_beg;
+ }
+ dc->DrawLines(pointsScreen->GetCount(), points);
+ }
DrawLineVerteces(line); // draw vertices
DrawLineNodes(line); // draw nodes
}
}
+ delete pen;
+
return 1;
}
@@ -292,31 +303,50 @@
*/
int DisplayDriver::DrawLineVerteces(int line)
{
- long int id;
+ int dcId;
wxPoint *point;
+ wxPen *pen;
- if (!settings.vertex.enabled)
+ if (!IsSelected(line) && !drawSegments && !settings.vertex.enabled)
return -1;
// determine color
if (!IsSelected(line)) {
- dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID));
- topology.vertex.push_back(line);
+ pen = new wxPen(settings.vertex.color, settings.lineWidth, wxSOLID);
+ dcId = 0;
}
else {
- dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID));
+ pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
+ if (drawSegments) {
+ dcId = 3; // first vertex
+ }
+ else {
+ dcId = 1;
+ dc->SetId(dcId);
+ }
}
- // set id
- id = ids[line].startId + 2;
- for (int i = 1; i < pointsScreen->GetCount() - 1; i++, id += 2) {
+ dc->SetId(dcId); /* 0 | 1 (selected) */
+ dc->SetPen(*pen);
+
+ for (int i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
point = (wxPoint*) pointsScreen->Item(i)->GetData();
- //wxRect rect (*point, *point);
- //dc->SetIdBounds(id, rect);
- dc->SetId(id);
- DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
+
+ if (drawSegments) {
+ dc->SetId(dcId);
+ dc->SetPen(*pen);
+ wxRect rect (*point, *point);
+ dc->SetIdBounds(dcId, rect);
+ }
+
+ if (settings.vertex.enabled) {
+ DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData());
+ topology.vertex++;
+ }
}
+ delete pen;
+
return pointsScreen->GetCount() - 2;
}
@@ -330,13 +360,15 @@
*/
int DisplayDriver::DrawLineNodes(int line)
{
+ int dcId;
int node;
- long int id;
double east, north, depth;
- int x, y, z;
+ double x, y, z;
int nodes [2];
bool draw;
-
+
+ wxPen *pen;
+
// draw nodes??
if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled)
return -1;
@@ -356,38 +388,48 @@
// determine color
if (IsSelected(line)) {
- dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID));
+ pen = new wxPen(settings.highlight, settings.lineWidth, wxSOLID);
draw = true;
+ if (!drawSegments) {
+ dcId = 1;
+ }
+ else {
+ // node1, line1, vertex1, line2, vertex2, ..., node2
+ if (i == 0) // first node
+ dcId = 1;
+ else // last node
+ dcId = 2 * points->n_points - 1;
+ }
}
- else if (!topology.recorded) {
+ else {
+ dcId = 0;
if (Vect_get_node_n_lines(mapInfo, node) == 1) {
- dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID));
- topology.nodeOne.push_back(line);
+ pen = new wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID);
+ topology.nodeOne++;
draw = settings.nodeOne.enabled;
}
else {
- dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID));
- topology.nodeTwo.push_back(line);
+ pen = new wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID);
+ topology.nodeTwo++;
draw = settings.nodeTwo.enabled;
}
}
- // node1, line1, vertex1, line2, vertex2, ..., node2
- if (i == 0) // first node
- id = dcId - points->n_points * 2 + 1;
- else // last node
- id = dcId - 1;
-
wxPoint point(x, y);
- // wxRect rect (point, point);
- // dc->SetIdBounds(id, rect);
+ if (IsSelected(line) && drawSegments) {
+ wxRect rect (point, point);
+ dc->SetIdBounds(dcId, rect);
+ }
// draw node if needed
if (draw) {
- dc->SetId(id);
+ dc->SetId(dcId);
+ dc->SetPen(*pen);
DrawCross(line, &point);
}
}
+
+ delete pen;
return 1;
}
@@ -472,10 +514,23 @@
\return
*/
void DisplayDriver::Cell2Pixel(double east, double north, double depth,
- int *x, int *y, int *z)
+ double *x, double *y, double *z)
{
+ double n, w;
+ /*
*x = int((east - region.map_west) / region.map_res);
*y = int((region.map_north - north) / region.map_res);
+ */
+ w = region.center_easting - (region.map_width / 2) * region.map_res;
+ n = region.center_northing + (region.map_height / 2) * region.map_res;
+
+ /*
+ *x = int((east - w) / region.map_res);
+ *y = int((n - north) / region.map_res);
+ */
+ *x = (east - w) / region.map_res;
+ *y = (n - north) / region.map_res;
+
*z = 0;
return;
@@ -537,7 +592,6 @@
dc->DrawLine(point->x - size, point->y, point->x + size, point->y);
dc->DrawLine(point->x, point->y - size, point->x, point->y + size);
-
return 1;
}
@@ -611,47 +665,51 @@
*/
void DisplayDriver::PrintIds()
{
- for (ids_map::const_iterator i = ids.begin(), e = ids.end();
- i != e; ++i) {
- std::cerr << "line=" << i->first << ": "
- << "npoints=" << i->second.npoints
- << " startId=" << i->second.startId
- << std::endl;
- }
+ /*
+ for (ids_map::const_iterator i = ids.begin(), e = ids.end();
+ i != e; ++i) {
+ std::cerr << "line=" << i->first << ": "
+ << "npoints=" << i->second.npoints
+ << " startId=" << i->second.startId
+ << std::endl;
+ }
+ */
- std::cerr << std::endl << "topology.recorded: " << topology.recorded << std::endl;
- std::cerr << "topology.point: " << topology.point.size() << std::endl;
- std::cerr << "topology.line: " << topology.line.size() << std::endl;
+ std::cerr << "topology.highlight: " << topology.highlight << std::endl;
- std::cerr << "topology.boundaryNo: " << topology.boundaryNo.size() << std::endl;
- std::cerr << "topology.boundaryOne: " << topology.boundaryOne.size() << std::endl;
- std::cerr << "topology.boundaryTwo: " << topology.boundaryTwo.size() << std::endl;
+ std::cerr << "topology.point: " << topology.point << std::endl;
+ std::cerr << "topology.line: " << topology.line << std::endl;
- std::cerr << "topology.centroidIn: " << topology.centroidIn.size() << std::endl;
- std::cerr << "topology.centroidOut: " << topology.centroidOut.size() << std::endl;
- std::cerr << "topology.centroidDup: " << topology.centroidDup.size() << std::endl;
+ std::cerr << "topology.boundaryNo: " << topology.boundaryNo << std::endl;
+ std::cerr << "topology.boundaryOne: " << topology.boundaryOne << std::endl;
+ std::cerr << "topology.boundaryTwo: " << topology.boundaryTwo << std::endl;
- std::cerr << "topology.nodeOne: " << topology.nodeOne.size() << std::endl;
- std::cerr << "topology.nodeTwo: " << topology.nodeTwo.size() << std::endl;
+ std::cerr << "topology.centroidIn: " << topology.centroidIn << std::endl;
+ std::cerr << "topology.centroidOut: " << topology.centroidOut << std::endl;
+ std::cerr << "topology.centroidDup: " << topology.centroidDup << std::endl;
- std::cerr << "topology.vertex: " << topology.vertex.size() << std::endl;
+ std::cerr << "topology.nodeOne: " << topology.nodeOne << std::endl;
+ std::cerr << "topology.nodeTwo: " << topology.nodeTwo << std::endl;
- std::cerr << std::endl << "nprimitives: "
- << topology.point.size() +
- topology.line.size() +
- topology.boundaryNo.size() +
- topology.boundaryOne.size() +
- topology.boundaryTwo.size() +
- topology.centroidIn.size() * 2 +
- topology.centroidOut.size() * 2 +
- topology.centroidDup.size() * 2 +
- topology.nodeOne.size() * 2 +
- topology.nodeTwo.size() * 2 +
- topology.vertex.size() * 2 << std::endl;
+ std::cerr << "topology.vertex: " << topology.vertex << std::endl;
+ std::cerr << std::endl << "nobjects: "
+ << topology.point * 2 + // cross
+ topology.line +
+ topology.boundaryNo +
+ topology.boundaryOne +
+ topology.boundaryTwo +
+ topology.centroidIn * 2 +
+ topology.centroidOut * 2 +
+ topology.centroidDup * 2 +
+ topology.nodeOne * 2 +
+ topology.nodeTwo * 2 +
+ topology.vertex * 2 << std::endl;
+
+ std::cerr << "selected: ";
for (std::vector::const_iterator i = selected.begin(), e = selected.end();
i != e; ++i)
- std::cerr << "selected: " << *i << " ";
+ std::cerr << *i << " ";
std::cerr << std::endl;
return;
@@ -723,15 +781,26 @@
\return point on line if line found
*/
std::vector DisplayDriver::SelectLineByPoint(double x, double y, double thresh,
- int onlyType)
+ int type)
{
long int line;
- int type;
+ int ftype;
double px, py, pz;
std::vector p;
+
+ if (type == -1) {
+ ftype = GV_POINTS | GV_LINES;
+ }
+ else if (type == 0) {
+ ftype = GV_POINTS;
+ }
+ else if (type == 1) {
+ ftype = GV_LINES;
+ }
+
line = Vect_find_line(mapInfo, x, y, 0.0,
- GV_POINTS | GV_LINES, thresh, 0, 0);
+ ftype, thresh, 0, 0);
if (line > 0) {
selected.push_back(line);
@@ -743,6 +812,8 @@
p.push_back(py);
}
+ drawSegments = true;
+
return p;
}
@@ -777,6 +848,7 @@
void DisplayDriver::Unselect()
{
selected.clear();
+ drawSegments = false;
return;
}
@@ -796,6 +868,20 @@
std::vector dc_ids;
long int line;
+
+ if (!drawSegments) {
+ dc_ids.push_back(1);
+ }
+ else {
+ int npoints;
+ Vect_read_line(mapInfo, points, NULL, selected[0]);
+ npoints = points->n_points;
+ for (int i = 1; i < 2 * npoints; i++) {
+ dc_ids.push_back(i);
+ }
+ }
+
+ /*
for(std::vector::const_iterator i = selected.begin(), e = selected.end();
i != e; ++i) {
line = *i;
@@ -821,6 +907,7 @@
}
}
}
+ */
return dc_ids;
}
@@ -851,22 +938,24 @@
*/
std::vector DisplayDriver::GetSelectedVertex(double x, double y)
{
- struct lineDesc *desc; // line desription
-
+ int startId;
int line, type;
int Gid, DCid;
- int vx, vy, vz; // vertex screen coordinates
+ double vx, vy, vz; // vertex screen coordinates
double dist, minDist;
std::vector returnId;
// only one object can be selected
- if (selected.size() != 1)
+ if (selected.size() != 1 || !drawSegments)
return returnId;
+ startId = 1;
line = selected[0];
-
+
+ std::cerr << line << std::endl;
+
type = Vect_read_line (mapInfo, points, cats, line);
// find the closest vertex (x, y)
@@ -886,10 +975,11 @@
}
}
- desc = &(ids[line]);
+ // desc = &(ids[line]);
// translate id
- DCid = Gid * 2 + desc->startId;
+ // DCid = Gid * 2 + desc->startId;
+ DCid = Gid * 2 + 1;
// add selected vertex
returnId.push_back(DCid);
@@ -897,9 +987,8 @@
&vx, &vy, &vz);
wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
dc->SetIdBounds(DCid, rect);
-
// left vertex
- if (DCid == desc->startId) {
+ if (DCid == startId) {
returnId.push_back(-1);
}
else {
@@ -911,7 +1000,7 @@
}
// right vertex
- if (DCid == (desc->npoints - 1) * 2 + desc->startId) {
+ if (DCid == (points->n_points - 1) * 2 + startId) {
returnId.push_back(-1);
}
else {
@@ -932,23 +1021,23 @@
*/
void DisplayDriver::ResetTopology()
{
- topology.recorded = false;
-
- topology.point.clear();
- topology.line.clear();
+ topology.highlight = 0;
- topology.boundaryNo.clear();
- topology.boundaryOne.clear();
- topology.boundaryTwo.clear();
+ topology.point = 0;
+ topology.line = 0;
- topology.centroidIn.clear();
- topology.centroidOut.clear();
- topology.centroidDup.clear();
+ topology.boundaryNo = 0;
+ topology.boundaryOne = 0;
+ topology.boundaryTwo = 0;
- topology.nodeOne.clear();
- topology.nodeTwo.clear();
+ topology.centroidIn = 0;
+ topology.centroidOut = 0;
+ topology.centroidDup = 0;
- topology.vertex.clear();
+ topology.nodeOne = 0;
+ topology.nodeTwo = 0;
+
+ topology.vertex = 0;
return;
}
Modified: trunk/grassaddons/gui/display_driver/driver.h
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.h 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/display_driver/driver.h 2007-10-07 09:02:21 UTC (rev 1125)
@@ -33,18 +33,29 @@
{
private:
wxPseudoDC *dc; // device content
- long int dcId; // wxDC id starting
+ /* disabled due to expensive calling dc->SetId()
+ *
+ * currently all objects are drawn without id
+ *
+ * only selected lines with id '1'
+ *
+ * segments with unique id (starting with '1')
+ * are drawn only when line was selected using SelectLineByPoint()
+ */
+ /*
struct lineDesc {
int npoints;
long int startId;
};
-
+
typedef std::map ids_map;
-
+
ids_map ids; // gId : {dcIds, ...}
+ */
std::vector selected; // list of selected features (gId)
+ bool drawSegments; // draw segments of selected line
struct Map_info *mapInfo;
struct line_pnts *points; // east, north, depth
@@ -74,7 +85,7 @@
struct _settings {
wxColor highlight;
-
+
symbol point;
symbol line;
@@ -96,31 +107,31 @@
} settings;
struct _topology {
- std::vector point;
- std::vector line;
+ long int highlight;
- std::vector boundaryNo;
- std::vector boundaryOne;
- std::vector boundaryTwo;
+ long int point;
+ long int line;
- std::vector centroidIn;
- std::vector centroidOut;
- std::vector centroidDup;
+ long int boundaryNo;
+ long int boundaryOne;
+ long int boundaryTwo;
- std::vector nodeOne;
- std::vector nodeTwo;
+ long int centroidIn;
+ long int centroidOut;
+ long int centroidDup;
- std::vector vertex;
+ long int nodeOne;
+ long int nodeTwo;
- bool recorded; // topology already recorded
+ long int vertex;
} topology;
void Cell2Pixel (double east, double north, double depth,
- int *x, int *y, int *z);
+ double *x, double *y, double *z);
int DrawCross(int line, const wxPoint *point, int size=5);
- int DrawLine(int line, bool inBox);
+ int DrawLine(int line);
int DrawLineVerteces(int line);
int DrawLineNodes(int line);
@@ -144,7 +155,7 @@
/* select */
int SelectLinesByBox(double x1, double y1, double x2, double y2);
std::vector SelectLineByPoint(double x, double y, double thresh,
- int onlyType);
+ int type);
void Unselect();
std::vector GetSelected(bool grassId);
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-07 09:02:21 UTC (rev 1125)
@@ -50,6 +50,8 @@
except:
print >> sys.stderr, "Digitization tool is disabled.\n" \
"Under development...\n"
+
+USEVEDIT = True
class AbstractDigit:
"""
@@ -72,8 +74,8 @@
self.settings["symbolPoint"] = (True, (0, 0, 0, 255)) # black
self.settings["symbolLine"] = (True, (0, 0, 0, 255)) # black
self.settings["symbolBoundaryNo"] = (True, (126, 126, 126, 255)) # grey
- self.settings["symbolBoundaryOne"] = (True, (255, 135, 0, 255)) # orange
- self.settings["symbolBoundaryTwo"] = (True, (0, 255, 0, 255)) # green
+ self.settings["symbolBoundaryOne"] = (True, (0, 255, 0, 255)) # green
+ self.settings["symbolBoundaryTwo"] = (True, (255, 135, 0, 255)) # orange
self.settings["symbolCentroidIn"] = (True, (0, 0, 255, 255)) # blue
self.settings["symbolCentroidOut"] = (True, (165, 42, 42, 255)) # brown
self.settings["symbolCentroidDup"] = (True, (156, 62, 206, 255)) # violet
@@ -85,7 +87,7 @@
self.settings["lineWidth"] = (2, "screen pixels")
# snapping
- self.settings["snapping"] = (20, "screen pixels") # value, unit
+ self.settings["snapping"] = (10, "screen pixels") # value, unit
self.settings["snapToVertex"] = False
# digitize new record
@@ -98,8 +100,6 @@
self.driver = CDisplayDriver(self, mapwindow)
- self.threshold = self.driver.GetThreshold()
-
def SetCategoryNextToUse(self):
"""Find maximum category number in the map layer
and update Digit.settings['category']
@@ -180,7 +180,7 @@
Debug.msg (4, "Vline.AddPoint(): input=%s" % addstring)
- self._AddFeature (map=map, input=addstring, flags=['-s'])
+ self._AddFeature (map=map, input=addstring)
def AddLine (self, map, type, coords):
"""
@@ -194,10 +194,10 @@
if type == "boundary":
key = "B"
- flags = ['-c', '-s'] # close boundaries
+ flags = ['-c'] # close boundaries
else:
key = "L"
- flags = ['-s']
+ flags = []
addstring="""%s %d 1\n""" % (key, len(coords))
for point in coords:
@@ -216,7 +216,7 @@
self._AddFeature (map=map, input=addstring, flags=flags)
- def _AddFeature (self, map, input, flags):
+ def _AddFeature (self, map, input, flags=[]):
"""
General method which adds feature to the vector map
"""
@@ -224,7 +224,8 @@
command = ["v.edit", "-n", "--q",
"map=%s" % map,
"tool=add",
- "thresh=%f" % self.threshold]
+ "thresh=%f" % self.driver.GetThreshold(),
+ "snap=node"]
# additional flags
for flag in flags:
@@ -283,15 +284,17 @@
Debug.msg(4, "Digit.MoveSelectedLines(): ids=%s, move=%s" % \
(ids, move))
- command = ["v.edit", "--q", "-s", # snap
+ command = ["v.edit", "--q",
"map=%s" % self.map,
"tool=%s" % tool,
"ids=%s" % ids,
"move=%f,%f" % (float(move[0]),float(move[1])),
- "thresh=%f" % self.threshold]
+ "thresh=%f" % self.driver.GetThreshold(),
+ "snap=node"]
if tool == "vertexmove":
command.append("coords=%f,%f" % (float(coords[0]), float(coords[1])))
+ command.append("-1") # modify only first selected
# run the command
vedit = cmd.Command(cmd=command)
@@ -314,7 +317,7 @@
"tool=break",
"ids=%s" % line,
"coords=%f,%f" % (float(coords[0]),float(coords[1])),
- "thresh=%f" % self.threshold]
+ "thresh=%f" % self.driver.GetThreshold()]
# run the command
vedit = cmd.Command(cmd=command)
@@ -344,7 +347,7 @@
"tool=%s" % action,
"ids=%s" % line,
"coords=%f,%f" % (float(coords[0]),float(coords[1])),
- "thresh=%f" % self.threshold]
+ "thresh=%f" % self.driver.GetThreshold()]
# run the command
vedit = cmd.Command(cmd=command)
@@ -379,21 +382,56 @@
'ids=%s' % line])
# add line
- self.AddLine(self.map, "line", coords)
+ if len(coords) > 0:
+ self.AddLine(self.map, "line", coords)
+ # reload map (needed for v.edit)
+ self.driver.ReloadMap()
+
class VDigit(AbstractDigit):
"""
Prototype of digitization class based on v.digit reimplementation
Under development (wxWidgets C/C++ background)
"""
- pass
+ def __init__(self, mapwindow, settings=None):
+ AbstractDigit.__init__(self, mapwindow, settings)
-class Digit(VEdit):
- """Default digit class"""
- def __init__(self, mapwindow):
- VEdit.__init__(self, mapwindow)
+ try:
+ from grass6_wxdriver import DigitClass
+ self.digit = DigitClass()
+ except:
+ self.digit = None
+ def DeleteSelectedLines(self):
+ """Delete selected vector features from the vector map"""
+
+ selected = self.driver.GetSelected() # grassId
+
+ if len(selected) <= 0:
+ return False
+
+ ids = ",".join(["%d" % v for v in selected])
+
+ Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \
+ ids)
+
+ self.digit.DeleteSelectedLines()
+ #self.driver.DrawUpdatedLines()
+
+ return True
+
+if USEVEDIT:
+ class Digit(VEdit):
+ """Default digit class"""
+ def __init__(self, mapwindow):
+ VEdit.__init__(self, mapwindow)
+else:
+ class Digit(VDigit):
+ """Default digit class"""
+ def __init__(self, mapwindow):
+ VDigit.__init__(self, mapwindow)
+
class AbstractDisplayDriver:
"""Abstract classs for display driver"""
def __init__(self, parent, mapwindow):
@@ -434,6 +472,8 @@
def __init__(self, parent, mapwindow):
AbstractDisplayDriver.__init__(self, parent, mapwindow)
+ self.mapWindow = mapwindow
+
# initialize wx display driver
try:
self.__display = DisplayDriver(mapwindow.pdcVector)
@@ -477,11 +517,10 @@
return nlines
- def SelectLinesByBox(self, begin, end, onlyType=None):
+ def SelectLinesByBox(self, begin, end, type=None):
"""Select vector features by given bounding box.
- Number of selected features can be decreased by 'onlyType'
- ('None' for no types)
+ If type is given, only vector features of given type are selected.
"""
x1, y1 = begin
@@ -493,14 +532,22 @@
return nselected
- def SelectLineByPoint(self, point, onlyType=None):
- """Select vector feature by coordinates of click point.
- Number of selected features can be decreased by 'onlyType'
- ('None' for all types)"""
+ def SelectLineByPoint(self, point, type=None):
+ """Select vector feature by coordinates of click point (in given threshold).
+ If type is given, only vector features of given type are selected.
+ """
+
+ ftype = -1 # all types
+ if type:
+ if type == "point":
+ ftype = 0
+ else:
+ ftype = 1 # line
+
pointOnLine = self.__display.SelectLineByPoint(point[0], point[1],
- float(self.parent.threshold),
- -1);
+ self.GetThreshold(),
+ ftype);
if len(pointOnLine) > 0:
Debug.msg(4, "CDisplayDriver.SelectLineByPoint(): pointOnLine=%f,%f" % \
@@ -780,8 +827,8 @@
vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.EXPAND)
self.mapUnits = self.parent.MapWindow.Map.ProjInfo()['units']
self.snappingInfo = wx.StaticText(parent=panel, id=wx.ID_ANY,
- label=_("Note: snapping threshold is %.1f %s") % \
- (self.parent.digit.threshold,
+ label=_("Snapping threshold is currently %.1f %s") % \
+ (self.parent.digit.driver.GetThreshold(),
self.mapUnits))
vertexSizer.Add(item=self.snappingInfo, proportion=0,
flag=wx.ALL | wx.EXPAND, border=1)
@@ -891,7 +938,7 @@
"""Change snapping value - update static text"""
value = self.snappingValue.GetValue()
threshold = self.parent.digit.driver.GetThreshold(value)
- self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % \
+ self.snappingInfo.SetLabel(_("Snapping threshold is currently %.1f %s") % \
(threshold,
self.mapUnits))
Modified: trunk/grassaddons/gui/gui_modules/gcmd.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-07 09:02:21 UTC (rev 1125)
@@ -149,9 +149,8 @@
dlg.Destroy()
else: # otherwise 'txt'
print >> sys.stderr, "Execution failed: '%s'" % (' '.join(self.cmd))
- print >> sys.stderr, "Details:"
- for err in self.errors:
- print >> sys.stderr, " %s" % err
+ print >> sys.stderr, "Details:\n%s" % '\n'.join(errs)
+
else:
self.returncode = None # running ?
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-07 09:02:21 UTC (rev 1125)
@@ -523,6 +523,8 @@
digitToolbar.layerSelectedID != None:
# set region
self.parent.digit.driver.UpdateRegion()
+ # re-calculate threshold for digitization tool
+ self.parent.digit.driver.GetThreshold()
# draw map
self.pdcVector.Clear()
self.pdcVector.RemoveAll()
@@ -997,12 +999,12 @@
if digitToolbar.action in ["moveVertex", "editLine"]:
if len(driver.GetSelected()) == 0:
# -> move vertex (select by point)
- nselected = driver.SelectLineByPoint(pos1, onlyType="line")
+ nselected = driver.SelectLineByPoint(pos1, type="line")
elif digitToolbar.action == "copyCats":
if not hasattr(self, "copyCatsIds"):
# collect categories
- nselected = driver.SelectLineByPoint(pos1, onlyType="line")
+ nselected = driver.SelectLineByPoint(pos1, type="line")
if nselected:
qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \
self.Map.width)
@@ -1035,25 +1037,28 @@
"copyCats", "editLine"]:
# -> move line || move vertex
self.UpdateMap(render=False)
+
# get pseudoDC id of objects which should be redrawn
if digitToolbar.action == "moveLine":
# -> move line
self.moveIds = driver.GetSelected(grassId=False)
+
elif digitToolbar.action == "moveVertex":
# -> move vertex
self.moveIds = driver.GetSelectedVertex(pos1)
+
elif digitToolbar.action == "editLine":
# -> edit line
ids = driver.GetSelected(grassId=False)
for id in ids:
- if id % 2: # only verteces
- self.moveIds.append(id)
+ if id % 2: # vertex
+ self.moveIds.append(id)
else:
self.UpdateMap(render=False, renderVector=False)
elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]:
pointOnLine = driver.SelectLineByPoint(pos1,
- onlyType="line")
+ type="line")
if pointOnLine:
self.UpdateMap(render=False) # highlight object
if digitToolbar.action in ["splitLine", "addVertex"]:
@@ -1213,20 +1218,24 @@
elif digit.action in ["moveLine", "moveVertex"] and \
hasattr(self, "moveBegin"):
# move vector feature
- move = [self.Distance((0,0), (self.moveBegin[0], 0))[0],
- self.Distance((0,0), (0, self.moveBegin[1]))[0]] # TODO d.measure
+ # move = [self.Distance((0,0), (self.moveBegin[0], 0))[0],
+ # self.Distance((0,0), (0, self.moveBegin[1]))[0]] # TODO d.measure
# ES -> EN
- if self.moveBegin[0] < 0.0:
- move[0] *= -1.0
- if self.moveBegin[1] > 0.0:
- move[1] *= -1.0
+ # if self.moveBegin[0] < 0.0:
+ # move[0] *= -1.0
+ # if self.moveBegin[1] > 0.0:
+ # move[1] *= -1.0
+ pTo = self.Pixel2Cell(event.GetPositionTuple())
+ pFrom = self.Pixel2Cell(self.moveCoords)
+ move = (pTo[0]-pFrom[0], pTo[1]-pFrom[1])
+
if digit.action == "moveLine":
# move line
self.parent.digit.MoveSelectedLines(move)
elif digit.action == "moveVertex":
# move vertex
- self.parent.digit.MoveSelectedVertex(self.Pixel2Cell(self.moveCoords),
+ self.parent.digit.MoveSelectedVertex(pFrom,
move)
else: # edit line
pass
@@ -1441,9 +1450,6 @@
def Cell2Pixel(self, (east, north)):
"""
Convert real word coordinates to image coordinates
-
- Input : float east, float north
- Output: int x, int y
"""
try:
@@ -1460,9 +1466,12 @@
w = self.Map.region["center_easting"] - (self.Map.width / 2) * res
n = self.Map.region["center_northing"] + (self.Map.height / 2) * res
- x = int((east - w) / res)
- y = int((n - north) / res)
+ # x = int((east - w) / res)
+ # y = int((n - north) / res)
+ x = (east - w) / res
+ y = (n - north) / res
+
return (x, y)
def Zoom(self, begin, end, zoomtype):
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-07 09:02:21 UTC (rev 1125)
@@ -337,6 +337,7 @@
self.action = "addLine"
self.type = "line"
self.parent.MapWindow.mouse['box'] = 'line'
+ self.parent.MapWindow.polycoords = [] # reset temp line
def OnAddBoundary(self, event):
"""Add boundary to the vector map layer"""
@@ -344,6 +345,7 @@
self.action = "addLine"
self.type = "boundary"
self.parent.MapWindow.mouse['box'] = 'line'
+ self.parent.MapWindow.polycoords = [] # reset temp line
def OnAddCentroid(self, event):
"""Add centroid to the vector map layer"""
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-05 17:07:32 UTC (rev 1124)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-07 09:02:21 UTC (rev 1125)
@@ -11,9 +11,9 @@
for GIS map layer management, command console, and command parsing.
AUTHORS: The GRASS Development Team
- Michael Barton (Arizona State University) &
+ Michael Barton (Arizona State University)
Jachym Cepicky (Mendel University of Agriculture)
- Martin Landa
+ Martin Landa
COPYRIGHT: (C) 2007 by the GRASS Development Team
This program is free software under the GNU General Public
@@ -283,7 +283,8 @@
(digit and digit.layerSelectedID != None and \
digit.layers[digit.layerSelectedID] == layer):
self.popupMenu.Enable (self.popupID5, False)
- self.popupMenu.Enable (self.popupID6, True)
+ if layer.GetMapset() == grassenv.env["MAPSET"]:
+ self.popupMenu.Enable (self.popupID6, True)
# raster
elif mltype and mltype == "raster":
From neteler at grass.itc.it Mon Oct 8 21:47:15 2007
From: neteler at grass.itc.it (neteler@grass.itc.it)
Date: Mon Oct 8 21:47:15 2007
Subject: [grass-addons] r1126 - in trunk/grassaddons: . IPCC
Message-ID: <200710081947.l98JlELf004234@grass.itc.it>
Author: neteler
Date: 2007-10-08 21:47:10 +0200 (Mon, 08 Oct 2007)
New Revision: 1126
Added:
trunk/grassaddons/IPCC/
trunk/grassaddons/IPCC/README
trunk/grassaddons/IPCC/gcm2grass.pl
Log:
Script to read SRES scenarios from IPCC into GRASS
Added: trunk/grassaddons/IPCC/README
===================================================================
--- trunk/grassaddons/IPCC/README (rev 0)
+++ trunk/grassaddons/IPCC/README 2007-10-08 19:47:10 UTC (rev 1126)
@@ -0,0 +1,19 @@
+SCRIPT TO READ SRES scenarios from IPCC
+
+Authors: Radim Blazek and Marta Benito Garz?n
+
+Converts Global Circulation Model (GCM) Climate Change Scenarios
+from GCM ascii format to 12 GRASS raster files (1 for each month)
+and changes longitude from 0-360
+
+Data
+ http://www.ipcc-data.org/sres/gcm_data.html
+
+Reference:
+ M. Benito Garz?n, R. Blazek, M. Neteler, R. Sanchez de Dios, H. Sainz
+ Ollero, and C. Furlanello, 2006: Predicting habitat suitability with
+ Machine Learning models: the potential area of Pinus sylvestris L. in
+ the Iberian Peninsula. Ecological Modelling,
+ 197(3-4):383-393. doi:10.1016/j.ecolmodel.2006.03.015
+ http://www.uam.es/proyectosinv/Mclim/pdf/MBenito_EcoMod.pdf
+
Added: trunk/grassaddons/IPCC/gcm2grass.pl
===================================================================
--- trunk/grassaddons/IPCC/gcm2grass.pl (rev 0)
+++ trunk/grassaddons/IPCC/gcm2grass.pl 2007-10-08 19:47:10 UTC (rev 1126)
@@ -0,0 +1,133 @@
+#!/usr/bin/perl
+#
+# Authors: Radim Blazek and Marta Benito Garz?n
+#
+# Converts GCM ascii format to 12 GRASS raster files (1 for each month)
+# and changes longitude from 0-360
+# http://www.ipcc-data.org/sres/gcm_data.html
+#
+# Reference:
+# M. Benito Garz?n, R. Blazek, M. Neteler, R. Sanchez de Dios, H. Sainz
+# Ollero, and C. Furlanello, 2006: Predicting habitat suitability with
+# Machine Learning models: the potential area of Pinus sylvestris L. in
+# the Iberian Peninsula. Ecological Modelling,
+# 197(3-4):383-393. doi:10.1016/j.ecolmodel.2006.03.015
+# http://www.uam.es/proyectosinv/Mclim/pdf/MBenito_EcoMod.pdf
+#
+##################
+
+for($i=0; $i<=$#ARGV; $i++){
+ if( $ARGV[$i] =~ /input=(.+)/){ $input = $1; }
+ elsif( $ARGV[$i] =~ /output=(.+)/){ $output = $1; }
+}
+
+if ( length($input) == 0 || length($output) == 0 ) {
+ die "File not specified\nParameters:\n input=\n output=\n";
+}
+
+open(IN, "<$input") or die "Cannot open input: $input";
+
+
+while ( $r = ){
+ chomp $r;
+
+ # Header 1
+ $r = lc ($r);
+ if ( !($r =~ /ipcc data distribution centre results/) ) { die "Wrong input: $r\n"; }
+
+ # Header 2
+ $r = ; chomp $r;
+ $r = lc ($r);
+ if ( !($r =~ /grid is/) ) { die "Wrong input: $r\n"; }
+ ($t, $t, $cols, $t, $rows, $t, $t, $month ) = split / +/, $r;
+ $month = lc ( $month );
+ $rows = int ($rows);
+ $cols = int($cols);
+ print "Cols = $cols Rows = $rows Month = $month\n";
+
+ # Header 3
+ $r = ; chomp $r;
+ $r = lc ($r);
+ if ( !($r =~ /mean change values/) ) { die "Wrong input: $r\n"; }
+
+ # Header 4
+ $r = ; chomp $r;
+
+ # Header 5
+ $r = ; chomp $r;
+
+ # Header 6
+ $r = ; chomp $r;
+ $r = lc ($r);
+ if ( !($r =~ /missing/) ) { die "Wrong input: $r\n"; }
+ $r =~ /.* ([^ ]+)/;
+ $null = $1;
+ print "Null = $null\n";
+
+$outfile = $output . $month;
+ print "Output file = $outfile\n";
+ open ( OUT, ">$outfile") or die "Cannot open $outfile";
+ print OUT "north: 90N\n";
+ print OUT "south: 90S\n";
+ print OUT "west: 180W\n";
+ print OUT "east: 180E\n";
+ print OUT "rows: $rows\n";
+ print OUT "cols: $cols\n";
+ print OUT "null: $null\n";
+ print OUT "type: float\n";
+
+ $ncels = $cols * $rows;
+ $nread = 0;
+
+ $col = $row = 0;
+ while ( $r = ){
+ chomp $r;
+ $r =~ s/^ +//;
+ $r =~ s/ +/ /g;
+
+ @value = split / /, $r;
+ $n = $#value;
+ $nread += $n + 1;
+
+ #print OUT "$r\n";
+
+ for ( $i = 0; $i <= $n; $i++ ) {
+ #print "$row $col $value[$i]\n";
+ $all[$row][$col] = $value[$i];
+
+ $col++;
+ if ( $col == $cols ) {
+ $col = 0;
+ $row++;
+ }
+ }
+
+ if ( $nread >= $ncels ) {
+ for ( $r = 0; $r < $rows; $r++ ) {
+ $start = $cols/2;
+ #print "start = $start\n";
+ for ( $c = $start; $c < $cols; $c++ ) {
+ #print "$r $c $all[$r][$c]\n";
+ print OUT "$all[$r][$c] ";
+ }
+ for ( $c = 0; $c < $cols/2; $c++ ) {
+ #print "$r $c $all[$r][$c]\n";
+ print OUT "$all[$r][$c] ";
+ }
+ print OUT "\n";
+ }
+ close (OUT);
+ last;
+ }
+ }
+
+ print "\n";
+}
+close(IN);
+
+
+
+
+
+
+
Property changes on: trunk/grassaddons/IPCC/gcm2grass.pl
___________________________________________________________________
Name: svn:executable
+ *
From neteler at grass.itc.it Tue Oct 9 10:32:49 2007
From: neteler at grass.itc.it (neteler@grass.itc.it)
Date: Tue Oct 9 10:32:50 2007
Subject: [grass-addons] r1127 - trunk/grassaddons/IPCC
Message-ID: <200710090832.l998WnwI012939@grass.itc.it>
Author: neteler
Date: 2007-10-09 10:32:47 +0200 (Tue, 09 Oct 2007)
New Revision: 1127
Modified:
trunk/grassaddons/IPCC/gcm2grass.pl
Log:
fix author
Modified: trunk/grassaddons/IPCC/gcm2grass.pl
===================================================================
--- trunk/grassaddons/IPCC/gcm2grass.pl 2007-10-08 19:47:10 UTC (rev 1126)
+++ trunk/grassaddons/IPCC/gcm2grass.pl 2007-10-09 08:32:47 UTC (rev 1127)
@@ -1,6 +1,6 @@
#!/usr/bin/perl
#
-# Authors: Radim Blazek and Marta Benito Garz?n
+# Author: Radim Blazek, ITC-irst, 2005
#
# Converts GCM ascii format to 12 GRASS raster files (1 for each month)
# and changes longitude from 0-360
From landa at grass.itc.it Tue Oct 9 11:44:19 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Tue Oct 9 11:44:21 2007
Subject: [grass-addons] r1128 - in trunk/grassaddons/gui: display_driver
gui_modules icons icons/silk
Message-ID: <200710090944.l999iJGV014026@grass.itc.it>
Author: landa
Date: 2007-10-09 11:44:10 +0200 (Tue, 09 Oct 2007)
New Revision: 1128
Added:
trunk/grassaddons/gui/icons/silk/plugin.png
Modified:
trunk/grassaddons/gui/display_driver/driver.h
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/toolbars.py
trunk/grassaddons/gui/icons/icon.py
trunk/grassaddons/gui/icons/silk/__init__.py
Log:
Digitization tool: additional tools implemented (flip, connect, merge, copy). Copy from backround map need to be finished.
Modified: trunk/grassaddons/gui/display_driver/driver.h
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.h 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/display_driver/driver.h 2007-10-09 09:44:10 UTC (rev 1128)
@@ -27,7 +27,7 @@
#include
}
-#define DEBUG
+// #define DEBUG
class DisplayDriver
{
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-09 09:44:10 UTC (rev 1128)
@@ -39,7 +39,7 @@
import wx.lib.colourselect as csel
import wx.lib.mixins.listctrl as listmix
-import gcmd as cmd
+import gcmd
import dbm
from debug import Debug as Debug
import select
@@ -69,7 +69,7 @@
if not settings:
self.settings = {}
# symbology
- self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white
+# self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white
self.settings["symbolHighlight"] = (None, (255, 255, 0, 255)) #yellow
self.settings["symbolPoint"] = (True, (0, 0, 0, 255)) # black
self.settings["symbolLine"] = (True, (0, 0, 0, 255)) # black
@@ -89,6 +89,7 @@
# snapping
self.settings["snapping"] = (10, "screen pixels") # value, unit
self.settings["snapToVertex"] = False
+ self.settings["backgroundMap"] = 'a1@martin'
# digitize new record
self.settings["addRecord"] = True
@@ -110,7 +111,7 @@
self.settings['category'] = 1
if self.map:
- categoryCmd = cmd.Command(cmd=["v.category", "-g", "--q",
+ categoryCmd = gcmd.Command(cmd=["v.category", "-g", "--q",
"input=%s" % self.map,
"option=report",
"layer=%d" % self.settings["layer"]])
@@ -212,7 +213,7 @@
Debug.msg (3, "Vline.AddLine(): type=%s, layer=%d, cat=%d coords=%s" % \
(key, coords))
- Debug.msg (4, "Vline.AddLine(): input=%s" % addstring)
+ Debug.msg (4, "VEdit.AddLine(): input=%s" % addstring)
self._AddFeature (map=map, input=addstring, flags=flags)
@@ -220,19 +221,31 @@
"""
General method which adds feature to the vector map
"""
-
+
+ if self.settings['snapping'][0] <= 0:
+ snap = "no"
+ else:
+ if self.settings['snapToVertex']:
+ snap = "vertex"
+ else:
+ snap = "node"
+
command = ["v.edit", "-n", "--q",
"map=%s" % map,
"tool=add",
"thresh=%f" % self.driver.GetThreshold(),
- "snap=node"]
+ "snap=%s" % snap]
+ if self.settings['backgroundMap'] != '':
+ command.append("bgmap=%s" % self.settings['backgroundMap'])
+
# additional flags
for flag in flags:
command.append(flag)
# run the command
- vedit = cmd.Command(cmd=command, stdin=input)
+ Debug.msg(4, "VEdit._AddFeature(): input=%s" % input)
+ vedit = gcmd.Command(cmd=command, stdin=input)
# reload map (needed for v.edit)
self.driver.ReloadMap()
@@ -256,7 +269,7 @@
"ids=%s" % ids]
# run the command
- vedit = cmd.Command(cmd=command)
+ vedit = gcmd.Command(cmd=command)
# reload map (needed for v.edit)
self.driver.ReloadMap()
@@ -284,20 +297,29 @@
Debug.msg(4, "Digit.MoveSelectedLines(): ids=%s, move=%s" % \
(ids, move))
+ if self.settings['snapping'][0] <= 0:
+ snap = "no"
+ else:
+ if self.settings['snapToVertex']:
+ snap = "vertex"
+ else:
+ snap = "node"
+
+
command = ["v.edit", "--q",
"map=%s" % self.map,
"tool=%s" % tool,
"ids=%s" % ids,
"move=%f,%f" % (float(move[0]),float(move[1])),
"thresh=%f" % self.driver.GetThreshold(),
- "snap=node"]
+ "snap=%s" % snap]
if tool == "vertexmove":
command.append("coords=%f,%f" % (float(coords[0]), float(coords[1])))
command.append("-1") # modify only first selected
# run the command
- vedit = cmd.Command(cmd=command)
+ vedit = gcmd.Command(cmd=command)
# reload map (needed for v.edit)
self.driver.ReloadMap()
@@ -320,7 +342,7 @@
"thresh=%f" % self.driver.GetThreshold()]
# run the command
- vedit = cmd.Command(cmd=command)
+ vedit = gcmd.Command(cmd=command)
# redraw map
self.driver.ReloadMap()
@@ -350,7 +372,7 @@
"thresh=%f" % self.driver.GetThreshold()]
# run the command
- vedit = cmd.Command(cmd=command)
+ vedit = gcmd.Command(cmd=command)
# reload map (needed for v.edit)
self.driver.ReloadMap()
@@ -363,7 +385,7 @@
return False
# collect cats
- cmd.Command(['v.edit',
+ gcmd.Command(['v.edit',
'--q',
'map=%s' % self.map,
'tool=catadd',
@@ -375,7 +397,7 @@
def EditLine(self, line, coords):
"""Edit existing line"""
# remove line
- vEditDelete = cmd.Command(['v.edit',
+ vEditDelete = gcmd.Command(['v.edit',
'--q',
'map=%s' % self.map,
'tool=delete',
@@ -388,6 +410,110 @@
# reload map (needed for v.edit)
self.driver.ReloadMap()
+ def __ModifyLines(self, tool):
+ """General method to modify selected lines"""
+
+ ids = self.driver.GetSelected()
+
+ if len(ids) <= 0:
+ return False
+
+ vEdit = ['v.edit',
+ '--q',
+ 'map=%s' % self.map,
+ 'tool=%s' % tool,
+ 'ids=%s' % ",".join(["%d" % v for v in ids])]
+
+ if tool in ['snap', 'connect']:
+ vEdit.append("thresh=%f" % self.driver.GetThreshold())
+
+ runCmd = gcmd.Command(vEdit)
+
+ # reload map (needed for v.edit)
+ self.driver.ReloadMap()
+
+ return True
+
+ def FlipLine(self):
+ """Flip selected lines"""
+
+ return self.__ModifyLines('flip')
+
+ def MergeLine(self):
+ """Merge selected lines"""
+
+ return self.__ModifyLines('merge')
+
+ def SnapLine(self):
+ """Snap selected lines"""
+
+ return self.__ModifyLines('snap')
+
+ def ConnectLine(self):
+ """Connect selected lines"""
+
+ return self.__ModifyLines('connect')
+
+ def CopyLine(self, ids=None):
+ """Copy features from (background) vector map"""
+
+ if not ids:
+ ids = self.driver.GetSelected()
+
+ if len(ids) <= 0:
+ return False
+
+ vEdit = ['v.edit',
+ '--q',
+ 'map=%s' % self.map,
+ 'tool=copy',
+ 'ids=%s' % ",".join(["%d" % v for v in ids])]
+
+ if self.settings['backgroundMap'] != '':
+ vEdit.append('bgmap=%s' % self.settings['backgroundMap'])
+
+ runCmd = gcmd.Command(vEdit)
+
+ # reload map (needed for v.edit)
+ self.driver.ReloadMap()
+
+ return True
+
+ def SelectLinesFromBackgroundMap(self, pos1, pos2):
+ """Select features from background map
+
+ pos1, pos2: bounding box defifinition
+ """
+
+ if self.settings['backgroundMap'] == '':
+ Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): []")
+ return []
+
+ print "#", pos1, pos2
+ x1, y1 = pos1
+ x2, y2 = pos2
+
+ vEditCmd = gcmd.Command(['v.edit',
+ '--q',
+ 'map=%s' % self.map,
+ 'tool=select',
+ # 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
+ 'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
+ (x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
+
+ try:
+ output = vEditCmd.ReadStdOutput()[0][0]
+ print "#", output
+ ids = output.split(',') #first line & item in list
+ ids = map(int, ids) # str -> int
+ except:
+ return []
+
+ Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): %s" % \
+ ",".join(["%d" % v for v in ids]))
+
+ return ids
+
class VDigit(AbstractDigit):
"""
Prototype of digitization class based on v.digit reimplementation
@@ -803,7 +929,7 @@
text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Snapping threshold"))
self.snappingValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1),
initial=self.parent.digit.settings["snapping"][0],
- min=1, max=1e6)
+ min=0, max=1e6)
self.snappingValue.Bind(wx.EVT_SPINCTRL, self.OnChangeSnappingValue)
self.snappingUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1),
choices=["screen pixels", "map units"])
@@ -815,7 +941,9 @@
# background map
text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Backgroud vector map"))
self.backgroundMap = select.Select(parent=panel, id=wx.ID_ANY, size=(200,-1),
- type="vector")
+ type="vector")
+ self.backgroundMap.SetValue(self.parent.digit.settings["backgroundMap"])
+ self.backgroundMap.Bind(wx.EVT_TEXT, self.OnChangeBackgroundMap)
flexSizer2.Add(text, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL)
flexSizer2.Add(self.backgroundMap, proportion=1, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
#flexSizer.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
@@ -899,7 +1027,7 @@
"""
return (
- ("Background", "symbolBackground"),
+ # ("Background", "symbolBackground"),
("Highlight", "symbolHighlight"),
("Point", "symbolPoint"),
("Line", "symbolLine"),
@@ -961,6 +1089,12 @@
event.Skip()
+ def OnChangeBackgroundMap(self, event):
+ """Change background map"""
+ map = self.backgroundMap.GetValue()
+
+ self.parent.digit.settings['backgroundMap'] = map
+
def OnOK(self, event):
"""Button 'OK' clicked"""
self.UpdateSettings()
@@ -1239,7 +1373,7 @@
Return True line found or False if not found"""
- cmdWhat = cmd.Command(cmd=['v.what',
+ cmdWhat = gcmd.Command(cmd=['v.what',
'--q',
'map=%s' % self.map,
'east_north=%f,%f' % \
@@ -1296,7 +1430,7 @@
'cats=%s' % catList,
'id=%d' % self.line]
- cmd.Command(vEditCmd)
+ gcmd.Command(vEditCmd)
self.cats_orig = copy.deepcopy(self.cats)
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-09 09:44:10 UTC (rev 1128)
@@ -58,7 +58,7 @@
import menuform
import select
import disp_print
-import gcmd as cmd
+import gcmd
import dbm
import defaultfont as defaultfont
import histogram as histogram
@@ -212,10 +212,12 @@
# platforms at initialization, but little harm done.
self.OnSize(None)
- # create a PseudoDC for map decorations like scales and legends
+ # create PseudoDC used for background map, map decorations like scales and legends
self.pdc = wx.PseudoDC()
# used for digitization tool
self.pdcVector = None
+ # pseudoDC for temporal objects (select box, measurement tool, etc.)
+ self.pdcTmp = wx.PseudoDC()
# will store an off screen empty bitmap for saving to file
self._Buffer = ''
@@ -395,6 +397,9 @@
if self.pdcVector:
self.pdcVector.DrawToDCClipped(dc, rgn)
+ # draw temporal object on the foreground
+ self.pdcTmp.DrawToDCClipped(dc, rgn)
+
def OnSize(self, event):
"""
Scale map image so that it is
@@ -496,10 +501,12 @@
self.resize = False
#
- # clear pseudodc
+ # clear pseudoDcs
#
self.pdc.Clear()
self.pdc.RemoveAll()
+ self.pdcTmp.Clear()
+ self.pdcTmp.RemoveAll()
#
@@ -551,7 +558,7 @@
self.resize = False
#
- # render region border
+ # render region border (to self.pdcTmp)
#
if hasattr(self, "regionCoords"):
reg = self.Map.GetWindow()
@@ -564,7 +571,7 @@
self.regionCoords.append(c2p((reg['west'],reg['south'])))
self.regionCoords.append(c2p((reg['west'],reg['north'])))
# draw region extent
- self.DrawLines(polycoords=self.regionCoords)
+ self.DrawLines(pdc=self.pdcTmp, polycoords=self.regionCoords)
#
# update statusbar
@@ -638,22 +645,25 @@
self.RefreshRect(r, False)
self.lastpos = (event.GetX(),event.GetY())
- def MouseDraw(self):
+ def MouseDraw(self, pdc=None):
"""
Mouse zoom rectangles and lines
"""
+ if not pdc:
+ return
+
Debug.msg (5, "BufferedWindow.MouseDraw(): use=%s, box=%s" % \
(self.mouse['use'], self.mouse['box']))
if self.mouse['box'] == "box":
boxid = wx.ID_NEW
mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \
self.mouse['end'][0], self.mouse['end'][1]]
- r = self.pdc.GetIdBounds(boxid)
+ r = pdc.GetIdBounds(boxid)
r.Inflate(4,4)
- self.pdc.ClearId(boxid)
+ pdc.ClearId(boxid)
self.RefreshRect(r, False)
- self.pdc.SetId(boxid)
- self.Draw(self.pdc, drawid=boxid, pdctype='box', coords=mousecoords)
+ pdc.SetId(boxid)
+ self.Draw(pdc, drawid=boxid, pdctype='box', coords=mousecoords)
elif self.mouse['box'] == "line":
self.lineid = wx.ID_NEW
mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \
@@ -665,19 +675,19 @@
r = wx.Rect(x1,y1,x2-x1,y2-y1)
r.Inflate(4,4)
try:
- self.pdc.ClearId(self.lineid)
+ pdc.ClearId(self.lineid)
except:
pass
self.RefreshRect(r, False)
- self.pdc.SetId(self.lineid)
+ pdc.SetId(self.lineid)
- self.Draw(self.pdc, drawid=self.lineid, pdctype='line', coords=mousecoords)
+ self.Draw(pdc, drawid=self.lineid, pdctype='line', coords=mousecoords)
def DrawLines(self, pdc=None, polycoords=None):
"""Draw polylines in PseudoDC"""
if not pdc:
- pdc = self.pdc
+ return
if not polycoords:
polycoords = self.polycoords
@@ -760,7 +770,7 @@
# dragging anything else - rubber band box or line
else:
self.mouse['end'] = event.GetPositionTuple()[:]
- self.MouseDraw()
+ self.MouseDraw(pdc=self.pdcTmp)
# double click
elif event.ButtonDClick():
@@ -799,7 +809,7 @@
self.mouse['end'] = self.mouse['begin']
self.polycoords.append(self.mouse['begin'])
- self.ClearLines()
+ self.ClearLines(pdc=self.pdcTmp)
else:
self.mouse['begin'] = self.mouse['end']
@@ -853,7 +863,7 @@
for sql in addRecordDlg.GetSQLString():
sqlfile.file.write(sql + ";\n")
sqlfile.file.flush()
- executeCommand = cmd.Command(cmd=["db.execute",
+ executeCommand = gcmd.Command(cmd=["db.execute",
"--q",
"input=%s" % sqlfile.name])
@@ -861,7 +871,7 @@
# add new point to the line
self.polycoords.append(event.GetPositionTuple()[:])
self.mouse['begin'] = self.polycoords[-1]
- self.DrawLines()
+ self.DrawLines(pdc=self.pdcTmp)
elif digitToolbar.action == "editLine" and hasattr(self, "moveIds"):
coords=self.polycoords[-2:]
@@ -872,7 +882,7 @@
idNode = wx.NewId()
self.pdcVector.SetIdBounds(idNode, (coords[1][0], coords[1][1],
coords[1][0], coords[1][1]))
- self.moveIds.insert(-1, idNode)
+ self.moveIds.append(idNode)
elif digitToolbar.action == "deleteLine":
pass
@@ -912,7 +922,7 @@
for sql in sqlCommands:
sqlfile.file.write(sql + ";\n")
sqlfile.file.flush()
- executeCommand = cmd.Command(cmd=["db.execute",
+ executeCommand = gcmd.Command(cmd=["db.execute",
"--q",
"input=%s" % sqlfile.name])
else: # displayCategories
@@ -941,6 +951,8 @@
else:
self.copyCatsIds = []
self.mouse['box'] = 'box'
+ elif digitToolbar.action == "copyLine":
+ self.copyIds = None
else:
# get decoration id
self.lastpos = self.mouse['begin']
@@ -980,7 +992,7 @@
try:
self.polycoords.append(self.mouse['end'])
self.pdc.ClearId(self.lineid)
- self.DrawLines()
+ self.DrawLines(pdc=self.pdcTmp)
except:
pass
@@ -993,12 +1005,14 @@
pos2 = self.Pixel2Cell(self.mouse['end'])
if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex",
- "copyCats", "editLine"]:
+ "copyCats", "editLine", "flipLine",
+ "mergeLine", "snapLine", "connectLine"]:
nselected = 0
# -> delete line || move line || move vertex
if digitToolbar.action in ["moveVertex", "editLine"]:
if len(driver.GetSelected()) == 0:
# -> move vertex (select by point)
+ # return vertex coordinates (tuple)
nselected = driver.SelectLineByPoint(pos1, type="line")
elif digitToolbar.action == "copyCats":
@@ -1008,7 +1022,7 @@
if nselected:
qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \
self.Map.width)
- vWhat = cmd.Command(['v.what',
+ vWhat = gcmd.Command(['v.what',
'--q',
'map=%s' % self.parent.digit.map,
'east_north=%f,%f' % \
@@ -1022,12 +1036,13 @@
else:
# collect ids
driver.Unselect()
+ # return number of selected features
nselected = driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
self.copyCatsIds = driver.GetSelected()
else:
- # -> moveLine || deleteLine (select by box)
+ # -> moveLine || deleteLine, etc. (select by box)
nselected = driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
@@ -1049,10 +1064,15 @@
elif digitToolbar.action == "editLine":
# -> edit line
+ # get id of selected vertex (last or first node)
+ selVertex = driver.GetSelectedVertex(pos1)[0]
ids = driver.GetSelected(grassId=False)
for id in ids:
if id % 2: # vertex
- self.moveIds.append(id)
+ self.moveIds.append(id)
+ if selVertex < ids[-1] / 2:
+ # choose first or last node of line
+ self.moveIds.reverse()
else:
self.UpdateMap(render=False, renderVector=False)
@@ -1071,7 +1091,19 @@
self.pdcVector.RemoveId(id)
self.DrawCross(pdc=self.pdcVector, coords=(x, y),
size=5)
+ elif digitToolbar.action == "copyLine":
+ if self.parent.digit.settings['backgroundMap'] == '':
+ # no background map -> copy from current vector map layer
+ nselected = driver.SelectLinesByBox(pos1, pos2)
+ if nselected > 0:
+ # highlight selected features
+ self.UpdateMap(render=False)
+ else:
+ # copy features from background map
+ self.copyIds = self.parent.digit.SelectLinesFromBackgroundMap(pos1, pos2)
+ self.UpdateMap(render=False, renderVector=False)
+
elif self.dragid != None:
# end drag of overlay decoration
self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
@@ -1091,7 +1123,7 @@
if self.mouse["use"] == "measure":
# measure
- self.ClearLines()
+ self.ClearLines(pdc=self.pdcTmp)
self.polycoords = []
self.mouse['use'] = 'pointer'
self.mouse['box'] = 'point'
@@ -1207,7 +1239,7 @@
for sql in addRecordDlg.GetSQLString():
sqlfile.file.write(sql + ";\n")
sqlfile.file.flush()
- executeCommand = cmd.Command(cmd=["db.execute",
+ executeCommand = gcmd.Command(cmd=["db.execute",
"--q",
"input=%s" % sqlfile.name])
# clean up saved positions
@@ -1263,13 +1295,24 @@
elif digit.action == "editLine" and hasattr(self, "moveBegin"):
line = self.parent.digit.driver.GetSelected()
coords = []
- for id in self.moveIds[0:-1]:
+ for id in self.moveIds: # avoid last point
x, y = self.pdcVector.GetIdBounds(id)[0:2]
coords.append(self.Pixel2Cell((x, y)))
self.parent.digit.EditLine(line, coords)
del self.moveBegin
del self.moveCoords
del self.moveIds
+ elif digit.action == "flipLine":
+ self.parent.digit.FlipLine()
+ elif digit.action == "mergeLine":
+ self.parent.digit.MergeLine()
+ elif digit.action == "snapLine":
+ self.parent.digit.SnapLine()
+ elif digit.action == "connectLine":
+ self.parent.digit.ConnectLine()
+ elif digit.action == "copyLine":
+ self.parent.digit.CopyLine(self.copyIds)
+ del self.copyIds
if digit.action != "addLine":
self.parent.digit.driver.Unselect()
@@ -1296,16 +1339,20 @@
if digit.action == "editLine" and len(self.moveIds) > 0:
# remove last vertex & line
- self.pdcVector.RemoveId(self.moveIds[-1])
+ self.pdcVector.RemoveId(self.moveIds[-1]) # remove last vertex
+ if self.moveIds[-1] > self.moveIds[-2]:
+ self.pdcVector.RemoveId(self.moveIds[-1] - 1) # remove last segment
+ else:
+ self.pdcVector.RemoveId(self.moveIds[-1] + 1) # remove last segment
self.moveIds.pop()
- self.pdcVector.RemoveId(self.moveIds[-1] -1)
- self.ClearLines()
+ self.ClearLines(pdc=self.pdcTmp)
self.UpdateMap(render=False, renderVector=False)
- self.DrawLines()
+ self.DrawLines(pdc=self.pdcTmp)
elif digit.action in ["deleteLine", "moveLine", "splitLine",
"addVertex", "removeVertex", "moveVertex",
- "copyCats"]:
+ "copyCats", "flipLine", "mergeLine",
+ "snapLine", "connectLine", "copyLine"]:
# varios tools -> unselected selected features
self.parent.digit.driver.Unselect()
if digit.action in ["moveLine", "moveVertex", "editLine"] and \
@@ -1320,6 +1367,9 @@
del self.copyCatsIds
except:
pass
+ elif digit.action == "copyLine":
+ del self.copyIds
+
self.UpdateMap(render=False) # render map
def OnMouseMoving(self, event):
@@ -1333,7 +1383,7 @@
digit.type in ["line", "boundary"]:
if len(self.polycoords) > 0:
# draw mouse moving
- self.MouseDraw()
+ self.MouseDraw(self.pdcTmp)
elif digit.action in ["moveLine", "moveVertex", "editLine"] \
and hasattr(self, "moveBegin"):
dx = self.mouse['end'][0] - self.mouse['begin'][0]
@@ -1367,19 +1417,19 @@
self.polycoords.append((x, y))
else: # edit line
# self.pdcVector.TranslateId(self.moveIds[-1], dx, dy)
- self.pdcVector.RemoveId(self.moveIds[-1]) # last vertex
- self.pdcVector.RemoveId(self.moveIds[-1] - 1) # line
+ # self.pdcVector.RemoveId(self.moveIds[-1]) # last vertex
+ # self.pdcVector.RemoveId(self.moveIds[-1] - 1) # line
try:
- if self.moveIds[-2] > 0: # previous vertex
- x, y = self.pdcVector.GetIdBounds(self.moveIds[-2])[0:2]
+ if self.moveIds[-1] > 0: # previous vertex
+ x, y = self.pdcVector.GetIdBounds(self.moveIds[-1])[0:2]
self.polycoords.append((x, y))
self.polycoords.append(self.mouse['end'])
except: # no line
self.pdcVector.RemoveId(self.moveIds[-1])
self.moveIds = []
- self.ClearLines()
- self.DrawLines()
+ self.ClearLines(pdc=self.pdcTmp)
+ self.DrawLines(pdc=self.pdcTmp)
self.Refresh() # TODO: use RefreshRect()
self.mouse['begin'] = self.mouse['end']
@@ -1392,7 +1442,7 @@
"""
if not pdc:
- pdc = self.pdc
+ return
exit = True
@@ -1587,7 +1637,7 @@
return
# get map extents using g.region and update display
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.returncode == 0:
output = p.module_stdout.read().split('\n')
@@ -1633,7 +1683,7 @@
"rows=%f" % new['rows'],
"cols=%f" % new['cols']]
- p = cmd.Command(cmdRegion)
+ p = gcmd.Command(cmdRegion)
if tmpreg:
os.environ["GRASS_REGION"] = tmpreg
@@ -1657,7 +1707,7 @@
wind = dlg.wind
- p = cmd.Command (["g.region", "-ugp", "region=%s" % wind])
+ p = gcmd.Command (["g.region", "-ugp", "region=%s" % wind])
if p.returncode == 0:
output = p.module_stdout.read().split('\n')
@@ -1723,7 +1773,7 @@
tmpreg = os.getenv("GRASS_REGION")
os.unsetenv("GRASS_REGION")
- p = cmd.Command(cmdRegion)
+ p = gcmd.Command(cmdRegion)
if tmpreg:
os.environ["GRASS_REGION"] = tmpreg
@@ -1817,7 +1867,7 @@
# Add statusbar
#
self.statusbar = self.CreateStatusBar(number=3, style=0)
- self.statusbar.SetStatusWidths([-2, -5, -1])
+ self.statusbar.SetStatusWidths([-5, -2, -1])
self.toggleStatus = wx.Choice(self.statusbar, wx.ID_ANY,
choices = ["Coordinates",
"Extent",
@@ -1848,7 +1898,7 @@
# "%s,%s" % (None, None)]
# for i in range(len(map_frame_statusbar_fields)):
# self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i)
- self.statusbar.SetStatusText("None,None", 1)
+ self.statusbar.SetStatusText("None,None", 0)
self.StatusbarReposition() # reposition checkbox
#
@@ -2012,7 +2062,7 @@
# update statusbar if required
e, n = self.MapWindow.Pixel2Cell(event.GetPositionTuple())
if self.statusText == "Coordinates":
- self.statusbar.SetStatusText("%.2f,%.2f" % (e, n), 1)
+ self.statusbar.SetStatusText("%.2f,%.2f" % (e, n), 0)
event.Skip()
@@ -2100,7 +2150,7 @@
self.Map.getRegion()
self.Map.getResolution()
self.UpdateMap()
-# event.Skip()
+ # event.Skip()
def OnAlignRegion(self, event):
"""
@@ -2110,7 +2160,7 @@
self.Map.alignRegion = True
else:
self.Map.alignRegion = False
-# event.Skip()
+ # event.Skip()
def OnToggleRender(self, event):
"""Enable/disable auto-rendering"""
@@ -2135,17 +2185,17 @@
self.statusText = event.GetString()
if self.statusText == "Coordinates":
- self.statusbar.SetStatusText("None,None", 1)
+ self.statusbar.SetStatusText("None,None", 0)
self.showRegion.Hide()
elif self.statusText == "Extent":
self.statusbar.SetStatusText("%.2f-%.2f,%.2f-%.2f" %
(self.Map.region["w"], self.Map.region["e"],
- self.Map.region["n"], self.Map.region["s"]), 1)
+ self.Map.region["n"], self.Map.region["s"]), 0)
self.showRegion.Show()
elif self.statusText == "Geometry":
self.statusbar.SetStatusText("rows=%d;cols=%d;nsres=%.2f;ewres=%.2f" %
(self.Map.region["rows"], self.Map.region["cols"],
- self.Map.region["nsres"], self.Map.region["ewres"]), 1)
+ self.Map.region["nsres"], self.Map.region["ewres"]), 0)
self.showRegion.Hide()
else:
self.statusbar.SetStatusText("", 1)
@@ -2153,12 +2203,12 @@
def StatusbarReposition(self):
"""Reposition checkbox in statusbar"""
# reposition checkbox
- widgets = {0: self.toggleStatus,
- 1: self.showRegion,
+ widgets = {0: self.showRegion,
+ 1: self.toggleStatus,
2: self.autoRender}
for idx, win in widgets.iteritems():
rect = self.statusbar.GetFieldRect(idx)
- if idx == 1: # show region
+ if idx == 0: # show region
wWin, hWin = win.GetBestSize()
x, y = rect.x + rect.width - wWin, rect.y-1
w, h = wWin, rect.height+2
@@ -2210,15 +2260,15 @@
point = wx.GetMousePosition()
printmenu = wx.Menu()
# Add items to the menu
- setup = wx.MenuItem(printmenu, -1,'Page setup')
+ setup = wx.MenuItem(printmenu, wx.ID_ANY,'Page setup')
printmenu.AppendItem(setup)
self.Bind(wx.EVT_MENU, self.printopt.OnPageSetup, setup)
- preview = wx.MenuItem(printmenu, -1,'Print preview')
+ preview = wx.MenuItem(printmenu, wx.ID_ANY,'Print preview')
printmenu.AppendItem(preview)
self.Bind(wx.EVT_MENU, self.printopt.OnPrintPreview, preview)
- doprint = wx.MenuItem(printmenu, -1,'Print display')
+ doprint = wx.MenuItem(printmenu, wx.ID_ANY,'Print display')
printmenu.AppendItem(doprint)
self.Bind(wx.EVT_MENU, self.printopt.OnDoPrint, doprint)
@@ -2330,17 +2380,17 @@
point = wx.GetMousePosition()
toolsmenu = wx.Menu()
# Add items to the menu
- measure = wx.MenuItem(toolsmenu, -1, Icons["measure"].GetLabel())
+ measure = wx.MenuItem(toolsmenu, wx.ID_ANY, Icons["measure"].GetLabel())
measure.SetBitmap(Icons["measure"].GetBitmap(self.iconsize))
toolsmenu.AppendItem(measure)
self.Bind(wx.EVT_MENU, self.OnMeasure, measure)
- profile = wx.MenuItem(toolsmenu, -1, Icons["profile"].GetLabel())
+ profile = wx.MenuItem(toolsmenu, wx.ID_ANY, Icons["profile"].GetLabel())
profile.SetBitmap(Icons["profile"].GetBitmap(self.iconsize))
toolsmenu.AppendItem(profile)
self.Bind(wx.EVT_MENU, self.Profile, profile)
- histogram = wx.MenuItem(toolsmenu, -1, Icons["histogram"].GetLabel())
+ histogram = wx.MenuItem(toolsmenu, wx.ID_ANY, Icons["histogram"].GetLabel())
histogram.SetBitmap(Icons["histogram"].GetBitmap(self.iconsize))
toolsmenu.AppendItem(histogram)
self.Bind(wx.EVT_MENU, self.Histogram, histogram)
@@ -2487,17 +2537,17 @@
point = wx.GetMousePosition()
decmenu = wx.Menu()
# Add items to the menu
- addscale = wx.MenuItem(decmenu, -1, Icons["addbarscale"].GetLabel())
+ addscale = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addbarscale"].GetLabel())
addscale.SetBitmap(Icons["addbarscale"].GetBitmap(self.iconsize))
decmenu.AppendItem(addscale)
self.Bind(wx.EVT_MENU, self.AddBarscale, addscale)
- AddLegend = wx.MenuItem(decmenu, -1, Icons["addlegend"].GetLabel())
+ AddLegend = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addlegend"].GetLabel())
AddLegend.SetBitmap(Icons["addlegend"].GetBitmap(self.iconsize))
decmenu.AppendItem(AddLegend)
self.Bind(wx.EVT_MENU, self.AddLegend, AddLegend)
- addtext = wx.MenuItem(decmenu, -1, Icons["addtext"].GetLabel())
+ addtext = wx.MenuItem(decmenu, wx.ID_ANY, Icons["addtext"].GetLabel())
addtext.SetBitmap(Icons["addtext"].GetBitmap(self.iconsize))
decmenu.AppendItem(addtext)
self.Bind(wx.EVT_MENU, self.AddText, addtext)
@@ -2698,28 +2748,28 @@
def OnZoomMenu(self, event):
"""
- Decorations overlay menu
+ Zoom menu
"""
point = wx.GetMousePosition()
zoommenu = wx.Menu()
# Add items to the menu
- zoommap = wx.MenuItem(zoommenu, -1,'Zoom to selected map')
+ zoommap = wx.MenuItem(zoommenu, wx.ID_ANY,'Zoom to selected map')
zoommenu.AppendItem(zoommap)
self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToMap, zoommap)
- zoomwind = wx.MenuItem(zoommenu, -1,'Zoom to computational region (set with g.region)')
+ zoomwind = wx.MenuItem(zoommenu, wx.ID_ANY,'Zoom to computational region (set with g.region)')
zoommenu.AppendItem(zoomwind)
self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToWind, zoomwind)
- savewind = wx.MenuItem(zoommenu, -1,'Set computational region from display')
+ savewind = wx.MenuItem(zoommenu, wx.ID_ANY,'Set computational region from display')
zoommenu.AppendItem(savewind)
self.Bind(wx.EVT_MENU, self.MapWindow.DisplayToWind, savewind)
- zoomsaved = wx.MenuItem(zoommenu, -1,'Zoom to saved region')
+ zoomsaved = wx.MenuItem(zoommenu, wx.ID_ANY,'Zoom to saved region')
zoommenu.AppendItem(zoomsaved)
self.Bind(wx.EVT_MENU, self.MapWindow.ZoomToSaved, zoomsaved)
- savezoom = wx.MenuItem(zoommenu, -1,'Save display geometry to named region')
+ savezoom = wx.MenuItem(zoommenu, wx.ID_ANY,'Save display geometry to named region')
zoommenu.AppendItem(savezoom)
self.Bind(wx.EVT_MENU, self.MapWindow.SaveDisplayRegion, savezoom)
@@ -2767,11 +2817,11 @@
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
box = wx.BoxSizer(wx.HORIZONTAL)
- label = wx.StaticText(self, -1, ("Drag %s with mouse in pointer mode\nto position. Double-click to change options" % ctrltxt))
+ label = wx.StaticText(self, wx.ID_ANY, ("Drag %s with mouse in pointer mode\nto position. Double-click to change options" % ctrltxt))
box.Add(label, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
- line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
+ line = wx.StaticLine(self, wx.ID_ANY, size=(20,-1), style=wx.LI_HORIZONTAL)
sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
btnsizer = wx.StdDialogButtonSizer()
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-09 09:44:10 UTC (rev 1128)
@@ -280,6 +280,7 @@
self.addPoint = self.addLine = self.addBoundary = self.addCentroid = None
self.moveVertex = self.addVertex = self.removeVertex = None
self.splitLine = self.editLine = self.moveLine = self.deleteLine = None
+ self.additioanlTools = None
return ((self.addPoint, "digAddPoint", Icons["digAddPoint"].GetBitmap(),
wx.ITEM_RADIO, Icons["digAddPoint"].GetLabel(), Icons["digAddPoint"].GetDesc(),
@@ -322,7 +323,11 @@
self.OnCopyCats),
(self.displayAttr, "digDispAttr", Icons["digDispAttr"].GetBitmap(),
wx.ITEM_RADIO, Icons["digDispAttr"].GetLabel(), Icons["digDispAttr"].GetDesc(),
- self.OnDisplayAttr))
+ self.OnDisplayAttr),
+ (self.additioanlTools, "digAdditionalTools", Icons["digAdditionalTools"].GetBitmap(),
+ wx.ITEM_NORMAL, Icons["digAdditionalTools"].GetLabel(),
+ Icons["digAdditionalTools"].GetDesc(),
+ self.OnAdditionalToolMenu))
def OnAddPoint(self, event):
"""Add point to the vector map Laier"""
@@ -432,6 +437,66 @@
DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"),
style=wx.DEFAULT_DIALOG_STYLE).Show()
+ def OnAdditionalToolMenu(self, event):
+ """Menu for additional tools"""
+ point = wx.GetMousePosition()
+ toolMenu = wx.Menu()
+ # Add items to the menu
+ copy = wx.MenuItem(toolMenu, wx.ID_ANY, 'Copy features from (background) vector map')
+ toolMenu.AppendItem(copy)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopy, copy)
+
+ flip = wx.MenuItem(toolMenu, wx.ID_ANY, 'Flip selected lines/boudaries')
+ toolMenu.AppendItem(flip)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnFlip, flip)
+
+ merge = wx.MenuItem(toolMenu, wx.ID_ANY, 'Merge selected lines/boundaries')
+ toolMenu.AppendItem(merge)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnMerge, merge)
+
+ snap = wx.MenuItem(toolMenu, wx.ID_ANY, 'Snap selected lines/boundaries')
+ toolMenu.AppendItem(snap)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnSnap, snap)
+
+ connect = wx.MenuItem(toolMenu, wx.ID_ANY, 'Connect selected two lines/boundaries')
+ toolMenu.AppendItem(connect)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnConnect, connect)
+
+ # Popup the menu. If an item is selected then its handler
+ # will be called before PopupMenu returns.
+ self.parent.MapWindow.PopupMenu(toolMenu)
+ toolMenu.Destroy()
+
+ def OnCopy(self, event):
+ """Copy selected features from (background) vector map"""
+ Debug.msg(2, "Digittoolbar.OnCopy():")
+ self.action="copyLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
+ def OnFlip(self, event):
+ """Flip selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnFlip():")
+ self.action="flipLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
+ def OnMerge(self, event):
+ """Merge selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnMerge():")
+ self.action="mergeLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
+ def OnSnap(self, event):
+ """Snap selected features"""
+ Debug.msg(2, "Digittoolbar.OnSnap():")
+ self.action="snapLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
+ def OnConnect(self, event):
+ """Connect selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnConnect():")
+ self.action="connectLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
def OnSelectMap (self, event):
"""
Select vector map layer for editing
@@ -473,7 +538,8 @@
self.mapcontent.ChangeLayerActive(mapLayer, False)
# change cursor
- self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
+ if self.parent.MapWindow.mouse['use'] == 'pointer':
+ self.parent.MapWindow.SetCursor(self.parent.cursors["cross"])
# create pseudoDC for drawing the map
self.parent.MapWindow.pdcVector = wx.PseudoDC()
Modified: trunk/grassaddons/gui/icons/icon.py
===================================================================
--- trunk/grassaddons/gui/icons/icon.py 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/icons/icon.py 2007-10-09 09:44:10 UTC (rev 1128)
@@ -61,6 +61,7 @@
"digDispAttr" : 'display.attributes.gif',
## general
"digSettings" : 'settings.gif',
+ "digAdditionalTools" : wx.ART_ERROR,
"digExit" : 'exit.gif',
# gis manager
"newdisplay" : 'gui-startmon.gif',
@@ -242,15 +243,15 @@
"digAddVertex": MetaIcon (img=icons_img["digAddVertex"], label="Add new vertex",
desc="Left: Select; Middle: Unselect; Right: Confirm"),
"digCopyCats": MetaIcon (img=icons_img["digCopyCats"], label="Copy categories",
- desc="Not implemented yet"),
+ desc="Left: Select; Middle: Unselect; Right: Confirm"),
"digDeleteLine": MetaIcon (img=icons_img["digDeleteLine"], label="Delete line",
desc="Left: Select; Middle: Unselect; Right: Confirm"),
"digDispAttr": MetaIcon (img=icons_img["digDispAttr"], label="Display/update attributes",
- desc="Display attributes of given feature"),
+ desc="Left: Select"),
"digDispCats": MetaIcon (img=icons_img["digDispCats"], label="Display/update categories",
- desc="Not implemented yet"),
+ desc="Left: Select"),
"digEditLine": MetaIcon (img=icons_img["digEditLine"], label="Edit line",
- desc="Not implemented yet"),
+ desc="Left: new point; Middle: undo last point; Right: close line"),
"digMoveLine": MetaIcon (img=icons_img["digMoveLine"], label="Move line",
desc="Left: Select; Middle: Unselect; Right: Confirm"),
"digMoveVertex": MetaIcon (img=icons_img["digMoveVertex"], label="Move vertex",
@@ -262,6 +263,9 @@
"digSplitLine": MetaIcon (img=icons_img["digSplitLine"], label="Split line",
desc="Left: Select; Middle: Unselect; Right: Confirm"),
"digExit" : MetaIcon (img=icons_img["digExit"], label="Quit digitization tool"),
+ "digAdditionalTools" : MetaIcon (img=icons_img["digAdditionalTools"], label="Additional tools " \
+ "(copy, flip, connect, etc.)",
+ desc="Left: Select; Middle: Unselect; Right: Confirm"),
# analyze raster
"analyze" : MetaIcon (img=icons_img["analyze"], label="Analyze map"),
"measure" : MetaIcon (img=icons_img["measure"], label="Measure distance"),
Modified: trunk/grassaddons/gui/icons/silk/__init__.py
===================================================================
--- trunk/grassaddons/gui/icons/silk/__init__.py 2007-10-09 08:32:47 UTC (rev 1127)
+++ trunk/grassaddons/gui/icons/silk/__init__.py 2007-10-09 09:44:10 UTC (rev 1128)
@@ -53,6 +53,7 @@
"digDispAttr" : 'table.png',
## general
"digSettings" : 'color_swatch.png',
+ "digAdditionalTools" : 'plugin.png',
"digExit" : 'door_in.png',
# gis manager
"newdisplay" : 'application_add.png',
Added: trunk/grassaddons/gui/icons/silk/plugin.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/icons/silk/plugin.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
From neteler at grass.itc.it Tue Oct 9 12:33:54 2007
From: neteler at grass.itc.it (neteler@grass.itc.it)
Date: Tue Oct 9 12:33:58 2007
Subject: [grass-addons] r1129 - in trunk/grassaddons: . r.sun_horizon
r.sun_horizon/r.horizon r.sun_horizon/r.sun2
Message-ID: <200710091033.l99AXsA9014200@grass.itc.it>
Author: neteler
Date: 2007-10-09 12:33:54 +0200 (Tue, 09 Oct 2007)
New Revision: 1129
Added:
trunk/grassaddons/r.sun_horizon/
trunk/grassaddons/r.sun_horizon/r.horizon/
trunk/grassaddons/r.sun_horizon/r.horizon/Makefile
trunk/grassaddons/r.sun_horizon/r.horizon/TODO
trunk/grassaddons/r.sun_horizon/r.horizon/description.html
trunk/grassaddons/r.sun_horizon/r.horizon/local_proto.h
trunk/grassaddons/r.sun_horizon/r.horizon/main.c
trunk/grassaddons/r.sun_horizon/r.sun2/
trunk/grassaddons/r.sun_horizon/r.sun2/Makefile
trunk/grassaddons/r.sun_horizon/r.sun2/README
trunk/grassaddons/r.sun_horizon/r.sun2/TODO
trunk/grassaddons/r.sun_horizon/r.sun2/description.html
trunk/grassaddons/r.sun_horizon/r.sun2/local_proto.h
trunk/grassaddons/r.sun_horizon/r.sun2/main.c
trunk/grassaddons/r.sun_horizon/r.sun2/rsunglobals.h
trunk/grassaddons/r.sun_horizon/r.sun2/rsunlib.c
trunk/grassaddons/r.sun_horizon/r.sun2/sunradstruct.h
Log:
new r.sun/r.horizon from JRC
Added: trunk/grassaddons/r.sun_horizon/r.horizon/Makefile
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.horizon/Makefile (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.horizon/Makefile 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.horizon
+
+LIBES = $(GPROJLIB) $(GISLIB)
+DEPENDENCIES = $(GPROJDEP) $(GISDEP)
+EXTRA_INC = $(PROJINC)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: trunk/grassaddons/r.sun_horizon/r.horizon/TODO
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.horizon/TODO (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.horizon/TODO 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,9 @@
+Probably the sun position calculation shouldbe replaced
+with
+
+ G_calc_solar_position()
+
+currently used in r.sunmask. G_calc_solar_position() is based on
+solpos.c from NREL and very precise.
+
+MN 4/2001
Added: trunk/grassaddons/r.sun_horizon/r.horizon/description.html
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.horizon/description.html (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.horizon/description.html 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,179 @@
+DESCRIPTION
+
+r.horizon computes the angular height of terrain horizon in
+radians. It reads a raster of elevation data and outputs the horizon
+outline in one of two modes:
+
+
+- single point: as a series of horizon
+heights in the specified directions from the given point. The results are
+written to the stdout.
+
- raster: in this case the output is
+one or more rasters, with each point in a raster giving the horizon
+height in a specific direction. One raster is created for each direction.
+
+
+The directions are given as azimuthal angles (in degrees), with
+the angle starting with 0 towards East and moving counterclockwise
+(North is 90, etc.). The calculation takes into account the actual
+projection, so the angles are corrected for direction distortions
+imposed by it. The directions are thus aligned to those of the
+geographic projection and not the coordinate system given by the rows
+and columns of the raster file. This correction implies that the
+resulting cardinal directions represent true orientation towards the
+East, North, West and South. The only exception of this feature is
+LOCATION with x,y coordinate system, where this correction is
+not applied.
+
+
+
+
+Flags:
+
+ - -d
+
- Output horizon height in degrees (the default is radians)
+
+
+Input parameters:
+The elevin parameter is an input elevation raster file. If
+the buffer options are used (see below), this raster should extend
+over the area that accommodate the presently defined region plus
+defined buffer zones.
+
+The step parameter gives the angle step (in degrees)
+between successive azimuthal directions for the calculation of the
+horizon. Thus, a value of 5 for the step will give a total of
+360/5=72 directions (72 rasters if used in the raster mode).
+
+The direction parameter gives the initial direction of the
+first output. This parameter acts as an direction angle offset. For
+example, if you want to get horizon angles for directions 45 and 225
+degrees, the direction should be set to 45 and step to
+180. If you only want one single direction, use this parameter to
+specify desired direction of horizon angle, and set the step
+size to 0 degrees.
+
+The dist controls the sampling distance step size for the
+search for horizon along the line of sight. The default value is 1.0
+meaning that the step size will be taken from the raster resolution.
+Setting the value below 1.0 might slightly improve results for
+directions apart from the cardinal ones, but increasing the
+processing load of the search algorithm.
+
+The maxdistance value gives a maximum distance to move away
+from the origin along the line of sight in order to search for the
+horizon height. The smaller this value the faster the calculation but
+the higher the risk that you may miss a terrain feature that can
+contribute significantly to the horizon outline.
+The coord parameter takes a pair of easting-northing values
+and calculates the values of angular height of the horizon around this point. To
+achieve the consistency of the results, the point coordinate is
+aligned to the midpoint of the closest elevation raster cell.
+
+If an analyzed point (or raster cell) lies close to the edge of
+the defined region, the horizon calculation may not be realistic,
+since it may not see some significant terrain features which could
+have contributed to the horizon, because these features are outside
+the region. There are to options how to set the size of the buffer
+that is used to increase the area of the horizon analysis. The
+bufferzone parameter allows you to specify the same size of
+buffer for all cardinal directions and the parameters e_buff,
+n_buff, s_buff, and w_buff allow you to specify
+a buffer size individually for each of the four directions. The
+buffer parameters influence only size of the read elevation file,
+while the analysis in the raster mode will be done only for the
+area specified by the current region definition.
+The horizon parameter gives the prefix of the output
+horizon raster files. The raster name of each horizon direction
+raster will be constructed as horizon_NNN , where NNN counts
+upwards from 0 to total number of directions. If you use r.horizon
+in the single point mode this option will be ignored.
+
+
+
+At the moment the elevation and maximum distance must be measured in meters,
+even if you use geographical coordinates (longitude/latitude). If your
+projection is based on distance (easting and northing), these too must
+be in meters. The buffer parameters must be in the same units as the
+raster coordinates.
+
+
+METHOD
+The calculation method is based on the method used in r.sun
+to calculate shadows. It starts at a very shallow angle and walks
+along the line of sight and asks at each step whether the line of
+sight "hits" the terrain. If so, the angle is increased to
+allow the line of sight to pass just above the terrain at that point.
+This is continued until the line of sight reaches a height that is
+higher than any point in the region or until it reaches the border of
+the region (see also the bufferzone,e_buff, n_buff,
+s_buff, and w_buff). The the number of lines of sight (azimuth
+directions) is determined from the direction and
+step parameters. The method takes into account the curvature
+of the Earth whereby remote features will seem to be lower than they
+actually are. It also accounts for the changes of angles towards
+cardinal directions caused by the projection (see above).
+
+
+EXAMPLE
+
+
+r.horizon elevin=DEM step=30 direction=15 bufferzone=200 coord=47.302,7.365 dist=0.7 > horizon.out
+
+
+
+raster mode:
+
+
+r.horizon elevin=DEM step=30 e_buff=20 horizon=horangle dist=0.7 maxdistance=2000
+
+
+
+SEE ALSO
+
+r.sun,
+r.los
+
+REFERENCES
+Hofierka J., 1997. Direct solar radiation modelling within an
+open GIS environment. Proceedings of JEC-GI'97 conference in Vienna,
+Austria, IOS Press Amsterdam, 575-584
+
+Hofierka J., Huld T., Cebecauer T., Suri M., 2007. Open Source Solar
+Radiation Tools for Environmental and Renewable Energy Applications,
+International Symposium on
+Environmental Software Systems, Prague, 2007
+Neteler M., Mitasova H., 2004. Open Source GIS: A GRASS GIS
+Approach, Kluwer
+Academic Publishers/Springer, Boston. ISBN: 1-4020-8064-6, 2nd
+Edition 2004 (reprinted 2005), 424 pages
+
+Project PVGIS, European
+Commission, DG Joint Research Centre 2001-2007
+Suri M., Hofierka J., 2004.
+A New GIS-based Solar Radiation Model and Its Application for
+Photovoltaic Assessments. Transactions
+in GIS, 8(2), 175-190
+
+AUTHORS
+Thomas Huld, Joint Research Centre of
+the European Commission, Ispra, Italy
+
+Tomas Cebecauer, Joint Research Centre
+of the European Commission, Ispra, Italy
+
+Jaroslav Hofierka, GeoModel s.r.o.,
+Bratislava, Slovakia
Marcel Suri, Joint Research Centre of the
+European Commission, Ispra, Italy
+© 2007, Thomas Huld, Tomas Cebecauer, Jaroslav Hofierka, Marcel Suri
+
+
+
+Thomas.Huld@jrc.it
+Tomas.Cebecauer@jrc.it
+hofierka@geomodel.sk
+Marcel.Suri@jrc.it
+
+
+Last changed: $Date: 2007/05/16 16:22:04 $
+
Added: trunk/grassaddons/r.sun_horizon/r.horizon/local_proto.h
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.horizon/local_proto.h (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.horizon/local_proto.h 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,23 @@
+/* sun11.c */
+int INPUT(void);
+int OUTGR(void);
+double amax1(double, double);
+double amin1(double, double);
+int min(int, int);
+int max(int, int);
+void com_par(void);
+double lumcline2(void);
+double joules2(void);
+int quadrant(void);
+double coef_of_line(void);
+void new_point_x(int, double *, double *, double *);
+void new_point_y(int, double *, double *, double *);
+void which_one(double, double, double, double, double, double);
+int combine_x(int, int, int, int);
+int combine_y(int, int, int, int);
+int vertex(int, int);
+int mesh_vertex(void);
+int mesh_line(void);
+void calculate(void);
+double com_sol_const(void);
+double com_declin(int);
Added: trunk/grassaddons/r.sun_horizon/r.horizon/main.c
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.horizon/main.c (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.horizon/main.c 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,1274 @@
+/*******************************************************************************
+r.horizon: This module does one of two things:
+
+1) Using a map of the terrain elevation it calculates for a set of points
+the angle height of the horizon for each point, using an angle interval given
+by the user.
+
+2) For a given minimum angle it calculates one or more raster map giving the mazimum
+distance to a point on the horizon.
+
+This program was written in 2006 by Tfomas Huld and Tomas Cebecauer,
+Joint Research Centre of the European Commission, based on bits of the r.sun module by Jaro Hofierka
+
+
+*******************************************************************************/
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define WHOLE_RASTER 1
+#define SINGLE_POINT 0
+#define RAD (180. / M_PI)
+#define DEG ((M_PI)/180.)
+#define EARTHRADIUS 6371000.
+#define UNDEF 0. /* undefined value for terrain aspect*/
+#define UNDEFZ -9999. /* undefined value for elevation */
+#define BIG 1.e20
+#define SMALL 1.e-20
+#define EPS 1.e-4
+#define DIST "1.0"
+#define DEGREEINMETERS 111120.
+#define TANMINANGLE 0.008727 /* tan of minimum horizon angle (0.5 deg) */
+
+#define AMAX1(arg1, arg2) ((arg1) >= (arg2) ? (arg1) : (arg2))
+#define DISTANCE1(x1, x2, y1, y2) (sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)))
+
+
+FILE *fw;
+
+const double rad2deg = 180./M_PI;
+const double deg2rad = M_PI/180.;
+const double pihalf=M_PI*0.5;
+const double twopi=2.*M_PI;
+const double invEarth=1./EARTHRADIUS;
+
+const double minAngle=DEG;
+
+char *elevin;
+char *latin = NULL;
+char *horizon = NULL;
+char *mapset = NULL;
+char *per;
+char shad_filename[256];
+
+struct Cell_head cellhd;
+struct Key_value *in_proj_info, *in_unit_info;
+struct pj_info iproj;
+struct pj_info oproj;
+
+struct Cell_head new_cellhd;
+double bufferZone=0., ebufferZone=0., wbufferZone=0., nbufferZone=0., sbufferZone=0.;
+
+int INPUT(void);
+int OUTGR(int numrows, int numcols);
+double amax1(double, double);
+double amin1(double, double);
+int min(int, int);
+int max(int, int);
+void com_par(double angle);
+int is_shadow(void);
+double horizon_height(void);
+void calculate_shadow();
+double calculate_shadow_onedirection(double shadow_angle);
+
+int new_point();
+double searching();
+int test_low_res();
+/*void where_is_point();
+void cube(int, int);
+*/
+
+void calculate(double xcoord, double ycoord, int buffer_e, int buffer_w, int buffer_s, int buffer_n);
+
+
+int ip, jp, ip100, jp100;
+int n, m, m100, n100;
+int degreeOutput=0;
+float **z, **z100, **horizon_raster;
+double stepx, stepy, stepxhalf, stepyhalf, stepxy, xp, yp, op, dp, xg0, xx0, yg0, yy0,deltx,delty;
+double invstepx, invstepy, distxy;
+double offsetx, offsety;
+double single_direction;
+
+/*int arrayNumInt;*/
+double xmin, xmax, ymin, ymax,zmax=0.;
+int d, day, tien=0;
+
+double length, maxlength=BIG, zmult=1.0, step=0.0,dist;
+double fixedMaxLength=BIG;
+char *tt,*lt;
+double z_orig,zp;
+double h0, tanh0, angle;
+double stepsinangle, stepcosangle, sinangle, cosangle, distsinangle, distcosangle;
+double TOLER;
+
+int mode;
+int isMode()
+ {
+ return mode;
+ }
+void setMode(int val)
+ {
+ mode = val;
+ }
+
+int ll_correction=0;
+double coslatsq;
+
+double distance(double x1, double x2, double y1, double y2)
+ {
+ if(ll_correction)
+ {
+ return DEGREEINMETERS*sqrt(coslatsq*(x1-x2)*(x1-x2)
+ +(y1-y2)*(y1-y2));
+ }
+ else
+ {
+ return sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2));
+ }
+ }
+
+
+
+int main(int argc, char *argv[])
+{
+ double xcoord, ycoord;
+
+
+ struct GModule *module;
+ struct
+ {
+ struct Option *elevin,*dist,*coord,*direction,*horizon,*step,*bufferzone,*e_buff,*w_buff,*n_buff,*s_buff, *maxdistance;
+ } parm;
+
+ struct
+ {
+ struct Flag *degreeOutput;
+ }
+ flag;
+
+ G_gisinit (argv[0]);
+ module = G_define_module();
+
+ module->keywords = _("raster");
+ module->label = _("Horizon angle computation from a digital elevation model.");
+ module->description =
+ _("Computes horizon angle height from a digital elevation model. The module has two"
+ " different modes of operation: "
+ "1. Computes the entire horizon around a single point whose coordinates are"
+ " given on withe the 'coord' option. The horizon height (in radians). "
+ "2. Computes one or more raster maps of the horizon height in a single direction. "
+ " The input for this is the angle (in degrees), which is measured "
+ " counterclockwise with east=0, north=90 etc. The output is the horizon height in radians.");
+
+ if(G_get_set_window(&cellhd)==-1) G_fatal_error("G_get_set_window() failed");
+ stepx = cellhd.ew_res;
+ stepy = cellhd.ns_res;
+ stepxhalf = stepx/2.;
+ stepyhalf = stepy/2.;
+ invstepx = 1./stepx;
+ invstepy = 1./stepy;
+ /*
+ offsetx = 2. * invstepx;
+ offsety = 2. * invstepy;
+ offsetx = 0.5*stepx;
+ offsety = 0.5*stepy;
+ */
+ offsetx = 0.5;
+ offsety = 0.5;
+
+ n/*n_cols*/ = cellhd.cols;
+ m/*n_rows*/ = cellhd.rows;
+
+ n100=ceil(n/100.);
+ m100=ceil(m/100.);
+
+ xmin = cellhd.west;
+ ymin = cellhd.south;
+ xmax = cellhd.east;
+ ymax = cellhd.north;
+ deltx = fabs(cellhd.east - cellhd.west);
+ delty = fabs(cellhd.north - cellhd.south);
+
+ parm.elevin = G_define_option();
+ parm.elevin->key = "elevin";
+ parm.elevin->type = TYPE_STRING;
+ parm.elevin->required = YES;
+ parm.elevin->gisprompt = "old,cell,raster";
+ parm.elevin->description = _("Name of the input elevation raster map [meters]");
+ parm.elevin->guisection = _("Input_options");
+
+
+ parm.direction = G_define_option();
+ parm.direction->key = "direction";
+ parm.direction->type = TYPE_DOUBLE;
+ parm.direction->required = NO;
+ parm.direction->description = _("Direction in which you want to know the horizon height");
+ parm.direction->guisection = _("Input_options");
+
+ parm.step = G_define_option();
+ parm.step->key = "step";
+ parm.step->type = TYPE_DOUBLE;
+ parm.step->required = NO;
+ parm.step->description = _("For multidirectional horizon: the step size in degrees");
+ parm.step->guisection = _("Input_options");
+
+ parm.bufferzone = G_define_option();
+ parm.bufferzone->key = "bufferzone";
+ parm.bufferzone->type = TYPE_DOUBLE;
+ parm.bufferzone->required = NO;
+ parm.bufferzone->description = _("For horizon rasters, read from the DEM an extra buffer around the present region");
+ parm.bufferzone->guisection = _("Input_options");
+
+ parm.e_buff = G_define_option();
+ parm.e_buff->key = "e_buff";
+ parm.e_buff->type = TYPE_DOUBLE;
+ parm.e_buff->required = NO;
+ parm.e_buff->description = _("For horizon rasters, read from the DEM an extra buffer eastward the present region");
+ parm.e_buff->guisection = _("Input_options");
+
+ parm.w_buff = G_define_option();
+ parm.w_buff->key = "w_buff";
+ parm.w_buff->type = TYPE_DOUBLE;
+ parm.w_buff->required = NO;
+ parm.w_buff->description = _("For horizon rasters, read from the DEM an extra buffer westward the present region");
+ parm.w_buff->guisection = _("Input_options");
+
+ parm.n_buff = G_define_option();
+ parm.n_buff->key = "n_buff";
+ parm.n_buff->type = TYPE_DOUBLE;
+ parm.n_buff->required = NO;
+ parm.n_buff->description = _("For horizon rasters, read from the DEM an extra buffer northward the present region");
+ parm.n_buff->guisection = _("Input_options");
+
+ parm.s_buff = G_define_option();
+ parm.s_buff->key = "s_buff";
+ parm.s_buff->type = TYPE_DOUBLE;
+ parm.s_buff->required = NO;
+ parm.s_buff->description = _("For horizon rasters, read from the DEM an extra buffer southward the present region");
+ parm.s_buff->guisection = _("Input_options");
+
+ parm.maxdistance = G_define_option();
+ parm.maxdistance->key = "maxdistance";
+ parm.maxdistance->type = TYPE_DOUBLE;
+ parm.maxdistance->required = NO;
+ parm.maxdistance->description = _("The maximum distance to consider when finding the horizon height");
+ parm.maxdistance->guisection = _("Input_options");
+
+
+ parm.horizon = G_define_option();
+ parm.horizon->key = "horizon";
+ parm.horizon->type = TYPE_STRING;
+ parm.horizon->required = NO;
+ parm.horizon->gisprompt = "old,cell,raster";
+ parm.horizon->description = _("Name of the horizon raster output");
+ parm.horizon->guisection = _("Output_options");
+
+
+ parm.coord = G_define_option();
+ parm.coord->key = "coord";
+ parm.coord->type = TYPE_STRING;
+ parm.coord->required = NO;
+ parm.coord->description = _("Coordinate for which you want to calculate the horizon");
+ parm.coord->guisection = _("Output_options");
+
+ parm.dist = G_define_option();
+ parm.dist->key = "dist";
+ parm.dist->type = TYPE_DOUBLE;
+ parm.dist->answer = DIST;
+ parm.dist->required = NO;
+ parm.dist->description = _("Sampling distance step coefficient (0.5-1.5)");
+ parm.dist->guisection = _("Output_options");
+
+
+ flag.degreeOutput = G_define_flag();
+ flag.degreeOutput->key = 'd';
+ flag.degreeOutput->description =
+ _("Write output in degrees (default is radians)");
+
+
+ if (G_parser(argc, argv))
+ exit(EXIT_FAILURE);
+
+ degreeOutput = flag.degreeOutput->answer;
+
+
+ elevin = parm.elevin->answer;
+
+ if(parm.coord->answer==NULL)
+ {
+ setMode(WHOLE_RASTER);
+ }
+ else
+ {
+ setMode(SINGLE_POINT);
+ if(sscanf(parm.coord->answer,"%lf,%lf", &xcoord, &ycoord)!=2)
+ {
+ G_fatal_error
+ ("Can't read the coordinates from the \"coord\" option.");
+
+ }
+
+ /* Transform the coordinates to row/column */
+
+/*
+ xcoord = (int) ((xcoord-xmin)/stepx);
+ ycoord = (int) ((ycoord-ymin)/stepy);
+*/
+ }
+
+ if(parm.direction->answer!=NULL) sscanf(parm.direction->answer, "%lf", &single_direction);
+
+
+ if(isMode(WHOLE_RASTER))
+ {
+ if((parm.direction->answer==NULL) && (parm.step->answer==NULL))
+ {
+ G_fatal_error
+ (_("You didn't specify a direction value or step size. Aborting."));
+ }
+
+
+ if(parm.horizon->answer==NULL)
+ {
+ G_fatal_error
+ (_("You didn't specify a horizon raster name. Aborting."));
+
+ }
+ horizon = parm.horizon->answer;
+ if(parm.step->answer!=NULL) sscanf(parm.step->answer, "%lf", &step);
+ }
+ else
+ {
+
+ if(parm.step->answer==NULL)
+ {
+ G_fatal_error
+ (_("You didn't specify an angle step size. Aborting."));
+
+ }
+ sscanf(parm.step->answer, "%lf", &step);
+
+
+ }
+
+ if(step==0.0)
+ {
+ step=360.;
+ }
+
+ if(parm.bufferzone->answer!=NULL)
+ {
+ if(sscanf(parm.bufferzone->answer, "%lf", &bufferZone)!=1)
+ {
+ G_fatal_error
+ (_("Could not read bufferzone size. Aborting."));
+ }
+ }
+
+ if(parm.e_buff->answer!=NULL)
+ {
+ if(sscanf(parm.e_buff->answer, "%lf", &ebufferZone)!=1)
+ {
+ G_fatal_error
+ (_("Could not read east bufferzone size. Aborting."));
+ }
+ }
+
+ if(parm.w_buff->answer!=NULL)
+ {
+ if(sscanf(parm.w_buff->answer, "%lf", &wbufferZone)!=1)
+ {
+ G_fatal_error
+ (_("Could not read west bufferzone size. Aborting."));
+ }
+ }
+
+ if(parm.s_buff->answer!=NULL)
+ {
+ if(sscanf(parm.s_buff->answer, "%lf", &sbufferZone)!=1)
+ {
+ G_fatal_error
+ (_("Could not read south bufferzone size. Aborting."));
+ }
+ }
+
+
+
+ if(parm.n_buff->answer!=NULL)
+ {
+ if(sscanf(parm.n_buff->answer, "%lf", &nbufferZone)!=1)
+ {
+ G_fatal_error
+ (_("Could not read north bufferzone size. Aborting."));
+ }
+ }
+
+ if(parm.maxdistance->answer!=NULL)
+ {
+ if(sscanf(parm.maxdistance->answer, "%lf", &fixedMaxLength)!=1)
+ {
+ G_fatal_error
+ (_("Could not read maximum distance. Aborting."));
+ }
+ }
+
+
+ sscanf(parm.dist->answer, "%lf", &dist);
+
+ stepxy = dist * 0.5 * (stepx + stepy);
+ distxy = dist;
+ TOLER = stepxy * EPS;
+
+ if(bufferZone>0. || ebufferZone>0. || wbufferZone>0. || sbufferZone>0. || nbufferZone>0.)
+ {
+ new_cellhd=cellhd;
+
+ if (ebufferZone==0.) ebufferZone=bufferZone;
+ if (wbufferZone==0.) wbufferZone=bufferZone;
+ if (sbufferZone==0.) sbufferZone=bufferZone;
+ if (nbufferZone==0.) nbufferZone=bufferZone;
+
+ new_cellhd.rows+=(int) ((nbufferZone+sbufferZone)/stepy);
+ new_cellhd.cols+=(int) ((ebufferZone+wbufferZone)/stepx);
+
+ new_cellhd.north+=nbufferZone;
+ new_cellhd.south-=sbufferZone;
+ new_cellhd.east+=ebufferZone;
+ new_cellhd.west-=wbufferZone;
+
+ xmin = new_cellhd.west;
+ ymin = new_cellhd.south;
+ xmax = new_cellhd.east;
+ ymax = new_cellhd.north;
+ deltx = fabs(new_cellhd.east - new_cellhd.west);
+ delty = fabs(new_cellhd.north - new_cellhd.south);
+
+ n/*n_cols*/ = new_cellhd.cols;
+ m/*n_rows*/ = new_cellhd.rows;
+/*printf("%lf %lf %lf %lf \n",ymax, ymin, xmin,xmax);
+*/
+ n100=ceil(n/100.);
+ m100=ceil(m/100.);
+
+ if(G_set_window(&new_cellhd)==-1) exit(EXIT_FAILURE);
+ }
+
+ struct Key_Value *in_proj_info, *in_unit_info;
+
+ if ((in_proj_info = G_get_projinfo()) == NULL)
+ G_fatal_error
+ (_("Can't get projection info of current location: please set latitude via 'lat' or 'latin' option!"));
+
+ if ((in_unit_info = G_get_projunits()) == NULL)
+ G_fatal_error(_("Can't get projection units of current location"));
+
+ if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
+ G_fatal_error
+ (_("Can't get projection key values of current location"));
+
+ G_free_key_value(in_proj_info);
+ G_free_key_value(in_unit_info);
+
+ /* Set output projection to latlong w/ same ellipsoid */
+ oproj.zone = 0;
+ oproj.meters = 1.;
+ sprintf(oproj.proj, "ll");
+ if ((oproj.pj = pj_latlong_from_proj(iproj.pj)) == NULL)
+ G_fatal_error(_("Unable to set up lat/long projection parameters"));
+
+
+
+
+/**********end of parser - ******************************/
+
+
+
+ INPUT();
+ calculate(xcoord, ycoord, (int) (ebufferZone/stepx), (int) (wbufferZone/stepx), (int) (sbufferZone/stepy), (int) (nbufferZone/stepy));
+
+ if(bufferZone>0.)
+ {
+ /* Set the region window back to the original */
+ if(G_set_window(&cellhd)==-1) exit(EXIT_FAILURE);
+ }
+
+/*sorry, I've moved OUTGR to calculate() - into the loop*/
+/* if(isMode(WHOLE_RASTER))
+ {
+ OUTGR(cellhd.rows,cellhd.cols);
+ }
+*/
+ if(G_set_window(&cellhd)==-1) exit(EXIT_FAILURE);
+
+ exit(EXIT_SUCCESS);
+}
+
+/**********************end of main.c*****************/
+
+int INPUT(void)
+
+{
+ FCELL *cell1;
+ int fd1, row, row_rev;
+ int l,i,j,k;
+ int lmax,kmax;
+
+ cell1=G_allocate_f_raster_buf();
+
+ z = (float **)malloc(sizeof(float *)*(m));
+ z100 = (float **)malloc(sizeof(float *)*(m100));
+
+ for(l=0;lm) lmax=m;
+
+ for (j=0; jn) kmax=n;
+ for (l=(i*100); l=arg2) {
+ res = arg1;
+ }
+ else {
+ res = arg2;
+ }
+ return res;
+}
+
+double amin1(arg1,arg2)
+ double arg1;
+ double arg2;
+{
+ double res;
+ if (arg1<=arg2) {
+ res = arg1;
+ }
+ else {
+ res = arg2;
+ }
+ return res;
+}
+
+
+int min(arg1,arg2)
+ int arg1;
+ int arg2;
+{
+ int res;
+ if (arg1 <= arg2)
+ {
+ res = arg1;
+ }
+ else
+ {
+ res = arg2;
+ }
+ return res;
+}
+
+int max(arg1,arg2)
+ int arg1;
+ int arg2;
+{
+ int res;
+ if (arg1>=arg2) {
+ res = arg1;
+ }
+ else {
+ res = arg2;
+ }
+ return res;
+}
+
+
+
+/**********************************************************/
+
+void com_par(double angle)
+{
+ sinangle=sin(angle);
+ if (fabs(sinangle)<0.0000001) {sinangle=0.;}
+ cosangle=cos(angle);
+ if (fabs(cosangle)<0.0000001) {cosangle=0.;}
+ distsinangle=32000;
+ distcosangle=32000;
+
+ if (sinangle != 0.)
+ { distsinangle = 100./(distxy*sinangle);}
+ if (cosangle != 0.)
+ { distcosangle = 100./(distxy*cosangle);}
+
+ stepsinangle = stepxy*sinangle;
+ stepcosangle = stepxy*cosangle;
+}
+
+double horizon_height(void)
+{
+ double height;
+
+ tanh0 = 0.;
+ length = 0;
+
+ height = searching();
+
+ xx0 = xg0; yy0 = yg0;
+
+ return height;
+}
+
+
+double calculate_shadow_onedirection(double shadow_angle)
+{
+
+ shadow_angle = horizon_height();
+
+ return shadow_angle;
+}
+
+
+
+void calculate_shadow()
+{
+ double dfr_rad;
+
+ int i;
+ int printCount;
+ double shadow_angle;
+ double printangle;
+ double sx, sy;
+ double xp, yp;
+ double latitude, longitude;
+ double delt_lat, delt_lon;
+ double delt_east, delt_nor;
+ double delt_dist;
+
+ double angle;
+
+ printCount=360./fabs(step);
+
+
+ if(printCount<1)
+ printCount=1;
+
+
+ dfr_rad = step*deg2rad ;
+
+ xp = xmin + xx0;
+ yp = ymin + yy0;
+
+ angle = (single_direction*deg2rad)+pihalf;
+
+
+ maxlength=fixedMaxLength;
+
+ for(i=0;i=360.)
+ printangle-=360;
+
+ printf("%lf, %lf\n", printangle, shadow_angle);
+
+ angle += dfr_rad;
+
+ if(angle<0.)
+ angle+=twopi;
+ else if(angle>twopi)
+ angle-=twopi;
+ } /* end of for loop over angles */
+ }
+/*//////////////////////////////////////////////////////////////////////*/
+
+
+int new_point()
+{
+ int iold, jold;
+ int succes = 1, succes2 = 1;
+ double sx, sy;
+ double dx, dy;
+
+ iold=ip; jold=jp;
+
+ while (succes)
+ {
+ yy0 += stepsinangle;
+ xx0 += stepcosangle;
+
+
+ /* offset 0.5 cell size to get the right cell i, j */
+ sx = xx0 * invstepx + offsetx;
+ sy = yy0 * invstepy + offsety;
+ ip = (int)sx; jp = (int)sy;
+
+ /* test outside of raster*/
+ if ((ip < 0) || (ip >= n) || (jp < 0) || (jp >= m)) return (3);
+
+ if ((ip!=iold) || (jp!=jold))
+ {
+ dx = (double)ip *stepx;
+ dy = (double)jp *stepy;
+
+ length = distance(xg0, dx, yg0, dy); /* dist from orig. grid point to the current grid point */
+ succes2=test_low_res();
+ if (succes2 ==1)
+ {
+ zp = z[jp][ip];
+ return(1);
+ }
+ }
+ }
+ return -1;
+}
+
+
+int test_low_res()
+{
+ int iold100, jold100;
+ double sx, sy;
+ int delx, dely, mindel;
+ double zp100, z2, curvature_diff;
+
+ iold100=ip100; jold100=jp100;
+ ip100 = floor(ip/100.); jp100 = floor(jp/100.);
+ /*test the new position with low resolution*/
+ if ((ip100!=iold100) || (jp100!=jold100))
+ {
+//printf("%d %d %d %d\n",ip,jp, iold100,jold100);
+/* replace with approximate version
+ curvature_diff = EARTHRADIUS*(1.-cos(length/EARTHRADIUS));
+*/
+ curvature_diff = 0.5*length*length*invEarth;
+ z2 = z_orig + curvature_diff + length * tanh0;
+ zp100=z100[jp100][ip100];
+//printf("%d %d %lf %lf \n",ip,jp,z2,zp100);
+
+ if (zp100 <= z2)
+ /*skip to the next lowres cell*/
+ {
+ delx=32000;
+ dely=32000;
+ if (cosangle>0.) {
+ sx = xx0 * invstepx + offsetx;
+ delx=floor(fabs((ceil(sx/100.) - (sx/100.))*distcosangle));
+ }
+ if (cosangle<0.) {
+ sx = xx0 * invstepx + offsetx;
+ delx=floor(fabs((floor(sx/100.) - (sx/100.))*distcosangle));
+ }
+ if (sinangle>0.) {
+ sy = yy0 * invstepy + offsety;
+ dely=floor(fabs((ceil(sy/100.) - (sy/100.))*distsinangle));
+ }
+ else if (sinangle<0.) {
+ sy = yy0 * invstepy + offsety;
+ dely=floor(fabs((floor(jp/100.) - (sy/100.))*distsinangle));
+ }
+
+ mindel=min(delx,dely);
+//printf("%d %d %d %lf %lf\n",ip, jp, mindel,xg0, yg0);
+
+ yy0 = yy0 + (mindel*stepsinangle);
+ xx0 = xx0 + (mindel*stepcosangle);
+//printf(" %lf %lf\n",xx0,yy0);
+
+ return(3);
+ }
+ else
+ {
+ return(1); /*change of low res array - new cell is reaching limit for high resolution processing*/
+ }
+ }
+ else
+ {
+ return(1); /*no change of low res array*/
+ }
+}
+
+
+double searching()
+ {
+ double z2;
+ double curvature_diff;
+ int succes = 1;
+
+ if(zp==UNDEFZ)
+ return 0;
+
+ while(1)
+ {
+ succes = new_point();
+
+ if(succes!=1)
+ {
+ break;
+ }
+/*
+ curvature_diff = EARTHRADIUS*(1.-cos(length/EARTHRADIUS));
+*/
+ curvature_diff = 0.5*length*length*invEarth;
+
+ z2 = z_orig + curvature_diff + length * tanh0;
+
+ if (z2 < zp)
+ {
+ tanh0 = (zp-z_orig-curvature_diff)/length;
+ }
+
+
+ if( z2 >= zmax)
+ {
+ break;
+ }
+
+ if( length >= maxlength)
+ {
+ break;
+ }
+
+ }
+
+ return atan(tanh0);
+}
+
+
+
+/*//////////////////////////////////////////////////////////////////////*/
+
+void calculate(double xcoord, double ycoord, int buffer_e, int buffer_w, int buffer_s, int buffer_n)
+{
+ int i, j, l, k=0;
+ int numDigits;
+
+ int xindex, yindex;
+ double shadow_angle;
+ double coslat;
+
+ double latitude,longitude;
+ double xp, yp;
+ double inputAngle;
+ double delt_lat, delt_lon;
+ double delt_east, delt_nor;
+ double delt_dist;
+
+ char formatString[10];
+
+
+ int hor_row_start=buffer_s;
+ int hor_row_end= m - buffer_n;
+
+ int hor_col_start= buffer_w;
+ int hor_col_end= n - buffer_e;
+
+ int hor_numrows = m - (buffer_s+buffer_n);
+ int hor_numcols = n - (buffer_e+buffer_w);
+
+/* char shad_filename[256];*/
+ int arrayNumInt;
+ double dfr_rad;
+
+ fprintf(stderr,"\n\n");
+
+
+ xindex = (int) ((xcoord-xmin)/stepx);
+ yindex = (int) ((ycoord-ymin)/stepy);
+
+ if ((G_projection() == PROJECTION_LL))
+ {
+ ll_correction=1;
+ }
+
+
+ if(isMode()==SINGLE_POINT)
+ {
+ /* Calculate the horizon for one single point */
+
+/*
+ xg0 = xx0 = (double)xcoord * stepx;
+ yg0 = yy0 = (double)ycoord * stepy;
+ xg0 = xx0 = xcoord -0.5*stepx -xmin;
+ yg0 = yy0 = ycoord -0.5*stepy-ymin;
+ xg0 = xx0 = xindex*stepx -0.5*stepx;
+ yg0 = yy0 = yindex*stepy -0.5*stepy;
+*/
+ xg0 = xx0 = xindex*stepx;
+ yg0 = yy0 = yindex*stepy;
+
+
+ if(ll_correction)
+ {
+ coslat=cos(deg2rad*(ymin + yy0));
+ coslatsq = coslat*coslat;
+ }
+
+ z_orig= zp = z[yindex][xindex];
+
+ calculate_shadow();
+
+ }
+ else
+ {
+
+
+
+ /****************************************************************/
+ /* The loop over raster points starts here! */
+ /****************************************************************/
+
+
+ if (horizon != NULL)
+ {
+ horizon_raster = (float **)malloc(sizeof(float *)*(hor_numrows));
+ for( l=0; l=twopi)?inputAngle-twopi:inputAngle;
+
+
+ delt_lat = -0.0001*cos(inputAngle); /* Arbitrary small distance in latitude */
+ delt_lon = 0.0001*sin(inputAngle)/cos(latitude);
+
+ latitude = (latitude+delt_lat)*rad2deg;
+ longitude = (longitude+delt_lon)*rad2deg;
+
+ if ((G_projection() != PROJECTION_LL))
+ {
+ if (pj_do_proj(&longitude, &latitude, &oproj, &iproj) <0)
+ {
+ G_fatal_error("Error in pj_do_proj");
+ }
+ }
+
+ delt_east=longitude-xp;
+ delt_nor=latitude-yp;
+
+ delt_dist=sqrt(delt_east*delt_east+delt_nor*delt_nor);
+
+ sinangle=delt_nor/delt_dist;
+ if (fabs(sinangle)<0.0000001) {sinangle=0.;}
+ cosangle=delt_east/delt_dist;
+ if (fabs(cosangle)<0.0000001) {cosangle=0.;}
+ distsinangle=32000;
+ distcosangle=32000;
+
+ if (sinangle != 0.)
+ { distsinangle = 100./(distxy*sinangle);}
+ if (cosangle != 0.)
+ { distcosangle = 100./(distxy*cosangle);}
+
+ stepsinangle = stepxy*sinangle;
+ stepcosangle = stepxy*cosangle;
+
+
+ z_orig= zp = z[j][i];
+ maxlength=(zmax-z_orig)/TANMINANGLE;
+ maxlength=(maxlength0.)
+ {
+ if(G_set_window(&new_cellhd)==-1) exit(0);
+ }
+ }
+
+ }
+
+}
+
+
+
Added: trunk/grassaddons/r.sun_horizon/r.sun2/Makefile
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/Makefile (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/Makefile 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,11 @@
+MODULE_TOPDIR = ../..
+
+PGM = r.sun2
+
+LIBES = $(GPROJLIB) $(GISLIB)
+DEPENDENCIES = $(GPROJDEP) $(GISDEP)
+EXTRA_INC = $(PROJINC)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: trunk/grassaddons/r.sun_horizon/r.sun2/README
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/README (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/README 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,75 @@
+Thomas Huld:
+
+I'm sending the r.sun sources to you here, even though the description is not
+yet up to date. I think it works OK now, though I haven't tried all possible
+combinations of options. For instance, I haven't ever used the incidence
+angle or insolation time outputs. There's no reason why they should have
+stopped working but there are always changes that break something unexpected.
+
+The main changes are:
+
+- possibility to read in horizon rasters to use with the shadow calculation.
+
+- Calculation of the shadowing effect should now also work in lat/lon
+projection.
+
+- There was a bug in r.sun whereby the shadowing effect was calculated wrong
+when the left-right and up-down directions in the projection are different
+from east-west and north-south, as is the case in the projection we use
+(Lambert Azimuthal) when moving away from the point of origin. This has been
+fixed now though only checked with Lambert Azimuthal.
+
+- I'm not sure if this went in already in a previous version, but the
+algorithm now also takes into account the curvature of the earth when
+calculating shadows.
+
+- new output possibility: glob_rad, which is the sum of the three radiation
+components
+
+- new input parameter: civiltime. When this parameter is given, the
+single time calculation will calculate the irradiance at the *same* time for
+the entire raster instead of using the local solar time. The value of
+civiltime is the timezone, relative to GMT. (+1 for central Europe)
+
+- new input parameter numpartitions No change in the calculation
+methods, but the program will read the input rasters and do the calculations
+in a number of chunks, instead of reading in everything at the start. Output
+is still only at the very end. This is only to save memory. It will not work
+if you try to calculate shadows without the horizon information, and the
+program will tell you so.
+
+- I reorganized the source code quite a lot. In particular, I spun off several
+functions into a separate source file called rsunlib.c. I also organized many
+of the global variables into struct's for an easier overview. I did
+this because we work here with several derivatives of r.sun:
+
+ * r.sunyear which calculates the optimum inclination angle for maximum
+insolation
+ * r.pv which calculates the PV output taking into account also temperature
+effects
+ * r.sun.2axis which is r.sun for a moving plane, whose normal always points
+to the sun (two-axis tracking solar energy systems).
+
+Splitting the source code made it easier to reuse bits for these r.sun
+derivatives. I haven't updated the Makefile to account for these changes yet.
+Look at the little script "compdebug" in the source directory.
+
+
+There may be other changes that I've forgotten about but nothing dramatic.
+
+Have fun!
+
+
+Thomas
+
+
+
+--
+--------------------------------------------------
+Thomas Huld
+Joint Research Centre of the European Commission
+T.P. 450
+I-21020 Ispra, Italy
+phone: +39 0332785273
+e-mail: Thomas.Huld@jrc.it
+--------------------------------------------------
Added: trunk/grassaddons/r.sun_horizon/r.sun2/TODO
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/TODO (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/TODO 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,89 @@
+From Thomas.Huld jrc.it Thu Jul 26 11:01:44 2007
+To: Markus Neteler
+CC: Jaro Hofierka , "marcel.suri jrc.it"
+ , Tomas Cebecauer
+Date: Thu, 26 Jul 2007 11:01:44 +0200
+Subject: Re: r.horizon source code
+Lines: 1533
+
+I'm sending the r.sun sources to you here, even though the description is not
+yet up to date. I think it works OK now, though I haven't tried all possible
+combinations of options. For instance, I haven't ever used the incidence
+angle or insolation time outputs. There's no reason why they should have
+stopped working but there are always changes that break something unexpected.
+
+The main changes are:
+
+- possibility to read in horizon rasters to use with the shadow calculation.
+
+- Calculation of the shadowing effect should now also work in lat/lon projection.
+
+- There was a bug in r.sun whereby the shadowing effect was calculated wrong
+when the left-right and up-down directions in the projection are different
+from east-west and north-south, as is the case in the projection we use
+(Lambert Azimuthal) when moving away from the point of origin. This has been
+fixed now though only checked with Lambert Azimuthal.
+
+- I'm not sure if this went in already in a previous version, but the
+algorithm now also takes into account the curvature of the earth when
+calculating shadows.
+
+- new output possibility: glob_rad, which is the sum of the three radiation
+components
+
+- new input parameter: civiltime. When this parameter is given, the
+single time calculation will calculate the irradiance at the *same* time for
+the entire raster instead of using the local solar time. The value of
+civiltime is the timezone, relative to GMT. (+1 for central Europe)
+
+- new input parameter numpartitions No change in the calculation
+methods, but the program will read the input rasters and do the calculations
+in a number of chunks, instead of reading in everything at the start. Output
+is still only at the very end. This is only to save memory. It will not work
+if you try to calculate shadows without the horizon information, and the
+program will tell you so.
+
+- I reorganized the source code quite a lot. In particular, I spun off several
+functions into a separate source file called rsunlib.c. I also organized many
+of the global variables into struct's for an easier overview. I did
+this because we work here with several derivatives of r.sun:
+
+ * r.sunyear which calculates the optimum inclination angle for maximum
+insolation
+ * r.pv which calculates the PV output taking into account also temperature
+effects
+ * r.sun.2axis which is r.sun for a moving plane, whose normal always points
+to the sun (two-axis tracking solar energy systems).
+
+Splitting the source code made it easier to reuse bits for these r.sun
+derivatives. I haven't updated the Makefile to account for these changes yet.
+Look at the little script "compdebug" in the source directory.
+
+
+There may be other changes that I've forgotten about but nothing dramatic.
+
+Have fun!
+
+
+Thomas
+
+--
+--------------------------------------------------
+Thomas Huld
+Joint Research Centre of the European Commission
+T.P. 450
+I-21020 Ispra, Italy
+phone: +39 0332785273
+e-mail: Thomas.Huld@jrc.it
+--------------------------------------------------
+
+######################################################################
+Probably the sun position calculation shouldbe replaced
+with
+
+ G_calc_solar_position()
+
+currently used in r.sunmask. G_calc_solar_position() is based on
+solpos.c from NREL and very precise.
+
+MN 4/2001
Added: trunk/grassaddons/r.sun_horizon/r.sun2/description.html
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/description.html (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/description.html 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,248 @@
+DESCRIPTION
+
+r.sun computes beam (direct), diffuse and ground reflected solar
+irradiation raster maps for given day, latitude, surface and atmospheric
+conditions. Solar parameters (e.g. time of sunrise and sunset, declination,
+extraterrestrial irradiance, daylight length) are stored in the resultant maps'
+history files. Alternatively, the local time can be specified to compute solar
+incidence angle and/or irradiance raster maps. The shadowing effect of the
+topography is optionally incorporated. This can be done either by calculating
+the shadowing effect directly from the digital elevation model or using rasters
+of the horizon height which is much faster. The horizon rasters can be
+constructed using
+r.horizon.
+
+
+The solar geometry of the model is based on the works of Krcho (1990), later
+improved by Jenco (1992). The equations describing Sun – Earth position as
+well as an interaction of the solar radiation with atmosphere were originally
+based on the formulas suggested by Kitler and Mikler (1986). This component
+was considerably updated by the results and suggestions of the working group
+co-ordinated by Scharmer and Greif (2000) (this algorithm might be replaced
+by SOLPOS algorithm-library included in GRASS within
+r.sunmask
+ command). The model computes all three components of global radiation (beam,
+diffuse and reflected) for the clear sky conditions, i.e. not taking into
+consideration the spatial and temporal variation of clouds. The extent and
+spatial resolution of the modelled area, as well as integration over time,
+are limited only by the memory and data storage resources. The model is built
+to fulfil user needs in various fields of science (hydrology, climatology,
+ecology and environmental sciences, photovoltaics, engineering, etc.) for
+continental, regional up to the landscape scales.
+
As an option the model considers a shadowing effect of the local topography.
+The r.sun program works in two modes. In the first mode it calculates for the set
+local time a solar incidence angle [degrees] and solar irradiance values [W.m-2].
+In the second mode daily sums of solar radiation [Wh.m-2.day-1] are computed
+within a set day. By a scripting the two modes can be used separately or
+in a combination to provide estimates for any desired time interval. The
+model accounts for sky obstruction by local relief features. Several solar
+parameters are saved in the resultant maps' history files, which may be viewed
+with the r.info command.
+
+The solar incidence angle raster map incidout is computed specifying
+elevation raster map elevin, aspect raster map aspin, slope
+steepness raster map slopin, given the day day and local time
+time. There is no need to define latitude for locations with known
+and defined projection/coordinate system (check it with the
+g.proj
+ command). If you have undefined projection, (x,y) system, etc. then the latitude
+can be defined explicitely for large areas by input raster map latin
+ with interpolated latitude values or, for smaller areas, a single region
+latitude value lat can be used instead. All input raster maps must
+be floating point (FCELL) raster maps. Null data in maps are excluded from
+the computation (and also speeding-up the computation), so each output raster
+map will contain null data in cells according to all input raster maps. The
+user can use r.null
+ command to create/reset null file for your input raster maps.
+The specified day day is the number of the day of the general year
+where January 1 is day no.1 and December 31 is 365. Time time must
+be a local (solar) time (i.e. NOT a zone time, e.g. GMT, CET) in decimal system,
+e.g. 7.5 (= 7h 30m A.M.), 16.1 = 4h 6m P.M..
+Setting the solar declination declin by user is an option to override
+the value computed by the internal routine for the day of the year. The value
+of geographical latitude can be set as a constant for the whole computed
+region or, as an option, a grid representing spatially distributed values
+over a large region. The geographical latitude must be also in decimal system
+with positive values for northern hemisphere and negative for southern one.
+In similar principle the Linke turbidity factor (linkein, lin
+) and ground albedo (albedo, alb) can be set.
+Besides clear-sky radiations, the user can compute a real-sky radiation (beam,
+diffuse) using coefbh and coefdh input raster maps defining
+the fraction of the respective clear-sky radiations reduced by atmospheric
+factors (e.g. cloudiness). The value is between 0-1. Usually these
+coefficients can be obtained from a long-terms meteorological measurements.
+The solar irradiation or irradiance raster maps beam_rad, diff_rad
+, refl_rad are computed for a given day day, latitude lat
+(latin), elevation elevin, slope slopein and aspect
+aspin raster files. For convenience, the output raster given as glob_rad will output the sum of the three radiation components. The program uses the Linke atmosphere turbidity factor
+and ground albedo coefficient. A default, single value of Linke factor is
+lin=3.0 and is near the annual average for rural-city areas. The Linke
+factor for an absolutely clear atmosphere is lin=1.0. See notes below
+to learn more about this factor. The incidence solar angle is the angle between
+horizon and solar beam vector. The solar radiation maps for given day are
+computed integrating the relevant irradiance between sunrise and sunset times
+for given day. The user can set finer or coarser time step step used
+for all-day radiation calculations. A default value of step is 0.5
+hour. Larger steps (e.g. 1.0-2.0) can speed-up calculations but produce less
+reliable results. The output units are in Wh per squared meter per given
+day [Wh/(m*m)/day]. The incidence angle and irradiance/irradiation maps can
+be computed without shadowing influence of relief by default or they can
+be computed with this influence using the flag -s. In mountainous areas
+this can lead to very different results! The user should be aware that taken
+into account the shadowing effect of relief can slow
+down the speed of computing especially when the sun altitude is low.
+ When considering shadowing effect (flag -s) speed and precision computing
+can be controlled by a parameter dist which defines the sampling density
+at which the visibility of a grid cell is computed in the direction of a
+path of the solar flow. It also defines the method by which the obstacle's
+altitude is computed. When choosing dist less than 1.0 (i.e. sampling
+points will be computed at dist * cellsize distance), r.sun takes
+altitude from the nearest grid point. Values above 1.0 will use the maximum
+altitude value found in the nearest 4 surrounding grid points. The default
+value dist=1.0 should give reasonable results for most cases (e.g.
+on DEM). Dist value defines a multiplying coefficient for sampling
+distance. This basic sampling distance equals to the arithmetic average of
+both cell sizes. The reasonable values are in the range 0.5-1.5. The values
+below 0.5 will decrease and values above 1.0 will increase the computing
+speed. Values greater than 2.0 may produce estimates with lower accuracy
+in highly dissected relief. The fully shadowed areas are written to the ouput
+maps as zero values. Areas with NULL data are considered as no barrier with
+shadowing effect .
+The maps' history files are generated containing the following listed
+parameters used in the computation:
+- Solar constant 1367 W.m-2
+- Extraterrestrial irradiance on a plane perpendicular to the solar beam
+[W.m-2]
+- Day of the year
+- Declination [radians]
+- Decimal hour (Alternative 1 only)
+- Sunrise and sunset (min-max) over a horizontal plane
+- Daylight lengths
+- Geographical latitude (min-max)
+- Linke turbidity factor (min-max)
+- Ground albedo (min-max)
+The user can use a nice shellcript with variable
+day to compute radiation for some time interval within the year (e.g. vegetation
+or winter period). Elevation, aspect and slope input values should not be
+reclassified into coarser categories. This could lead to incorrect results.
+
+
+ OPTIONS
+Currently, there are two modes of r.sun.
+In the first mode it calculates solar incidence angle and solar irradiance
+raster maps using the set local time. In the second mode daily sums of solar
+irradiation [kWh.m-2.day-1] are computed for a specified day.
+
+
+NOTES
+
+Solar energy is an important input parameter in different models concerning
+energy industry, landscape, vegetation, evapotranspiration, snowmelt or remote
+sensing. Solar rays incidence angle maps can be effectively used in radiometric
+and topographic corrections in mountainous and hilly terrain where very accurate
+investigations should be performed.
+
+The clear-sky solar radiation model applied in the r.sun is based on the
+work undertaken for development of European Solar Radiation Atlas (Scharmer
+and Greif 2000, Page et al. 2001, Rigollier 2001). The clear sky model estimates
+the global radiation from the sum of its beam, diffuse and reflected components.
+The main difference between solar radiation models for inclined surfaces
+in Europe is the treatment of the diffuse component. In the European climate
+this component is often the largest source of estimation error. Taking into
+consideration the existing models and their limitation the European Solar
+Radiation Atlas team selected the Muneer (1990) model as it has a sound theoretical
+basis and thus more potential for later improvement.
+
+Details of underlying equations used in this program can be found in the
+reference literature cited below or book published by Neteler and Mitasova:
+Open Source GIS: A GRASS GIS Approach (published in Kluwer Academic Publishers
+in 2002).
+
+Average monthly values of the Linke turbidity coefficient for a mild climate
+(see reference literature for your study area):
+
+Month Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec annual
+mountains 1.5 1.6 1.8 1.9 2.0 2.3 2.3 2.3 2.1 1.8 1.6 1.5 1.90
+rural 2.1 2.2 2.5 2.9 3.2 3.4 3.5 3.3 2.9 2.6 2.3 2.2 2.75
+city 3.1 3.2 3.5 4.0 4.2 4.3 4.4 4.3 4.0 3.6 3.3 3.1 3.75
+industrial 4.1 4.3 4.7 5.3 5.5 5.7 5.8 5.7 5.3 4.9 4.5 4.2 5.00
+
+
+Planned improvements include the use of the SOLPOS algorithm for solar
+geometry calculations and internal computation of aspect and slope.
+
+
Shadow maps
+A map of shadows can be extracted from the solar incidence angle map
+(incidout). Areas with zero values are shadowed. The -s flag
+has to be used.
+
+SEE ALSO
+r.slope.aspect,
+r.sunmask,
+g.proj,
+r.null,
+v.surf.rst
+
+
+REFERENCES
+
+Hofierka, J., Suri, M. (2002): The solar radiation model for Open source
+GIS: implementation and applications. Manuscript submitted to the International
+GRASS users conference in Trento, Italy, September 2002.
+
+Hofierka, J. (1997). Direct solar radiation modelling within an open GIS
+environment. Proceedings of JEC-GI'97 conference in Vienna, Austria, IOS
+Press Amsterdam, 575-584.
+
+Jenco, M. (1992). Distribution of direct solar radiation on georelief and
+its modelling by means of complex digital model of terrain (in Slovak). Geograficky
+casopis, 44, 342-355.
+
+Kasten, F. (1996). The Linke turbidity factor based on improved values of
+the integral Rayleigh optical thickness. Solar Energy, 56 (3), 239-244.
+
+Kasten, F., Young, A. T. (1989). Revised optical air mass tables and approximation
+formula. Applied Optics, 28, 4735-4738.
+
+Kittler, R., Mikler, J. (1986): Basis of the utilization of solar radiation
+(in Slovak). VEDA, Bratislava, p. 150.
+
+Krcho, J. (1990). Morphometric analysis and digital models of georelief. VEDA,
+Bratislava (in Slovak).
+
+Muneer, T. (1990). Solar radiation model for Europe. Building services engineering
+research and technology, 11, 4, 153-163.
+
+Neteler, M., Mitasova, H. (2002): Open Source GIS: A GRASS GIS Approach, Kluwer
+Academic Publishers.
+
+Page, J. ed. (1986). Prediction of solar radiation on inclined surfaces. Solar
+energy R&D in the European Community, series F – Solar radiation data,
+Dordrecht (D. Reidel), 3, 71, 81-83.
+
+Page, J., Albuisson, M., Wald, L. (2001). The European solar radiation atlas:
+a valuable digital tool. Solar Energy, 71, 81-83.
+
+Rigollier, Ch., Bauer, O., Wald, L. (2000). On the clear sky model of the
+ESRA - European Solar radiation Atlas - with respect to the Heliosat method.
+Solar energy, 68, 33-48.
+
+Scharmer, K., Greif, J., eds., (2000). The European solar radiation atlas,
+Vol. 2: Database and exploitation software. Paris (Les Presses de l’ École
+des Mines).
+
+Joint Research Centre: GIS solar radiation database for Europe
+
+AUTHORS
+
+Jaroslav Hofierka, GeoModel, s.r.o. Bratislava, Slovakia
+
+Marcel Suri, GeoModel, s.r.o. Bratislava, Slovakia
+
+© 2007, Jaroslav Hofierka, Marcel Suri
+
+hofierka@geomodel.sk
+suri@geomodel.sk
+
+
+Last changed: $Date: 2005/03/06 12:33:04 $
Added: trunk/grassaddons/r.sun_horizon/r.sun2/local_proto.h
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/local_proto.h (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/local_proto.h 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,65 @@
+/* main.c */
+
+
+void where_is_point(double *length, struct SunGeometryVarDay *sunVarGeom,
+ struct GridGeometry *gridGeom);
+int searching(double *length, struct SunGeometryVarDay *sunVarGeom,
+ struct GridGeometry *gridGeom);
+
+int useCivilTime();
+void setUseCivilTime(int val);
+int useShadow();
+void setUseShadow(int val);
+int useShadowData();
+void setUseShadowData(int val);
+int useHorizonData();
+void setUseHorizonData(int val);
+double getTimeOffset();
+void setTimeOffset(double val);
+double getHorizonInterval();
+void setHorizonInterval(double val);
+void setAngularLossDenominator();
+
+
+void cube(int, int);
+
+double com_sol_const(int no_of_day);
+
+
+double brad(double, double *bh, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+double drad(double, double bh, double *rr, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+
+
+double brad_angle_loss(double, double *bh, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+double drad_angle_loss(double, double bh, double *rr, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+
+
+void com_par( struct SunGeometryConstDay *sungeom,
+ struct SunGeometryVarDay *sunVarGeom,
+ struct GridGeometry *gridGeom,
+ double latitude, double longitude);
+void com_par_const(double longitTime, struct SunGeometryConstDay *sungeom,
+ struct GridGeometry *gridGeom);
+double lumcline2(struct SunGeometryConstDay *sungeom,
+ struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct GridGeometry *gridGeom,
+ unsigned char *horizonpointer);
+
+
+typedef double (*BeamRadFunc)(double sh, double *bh, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+
+typedef double (*DiffRadFunc)(double sh, double bh, double *rr, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar);
+
Added: trunk/grassaddons/r.sun_horizon/r.sun2/main.c
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/main.c (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/main.c 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,2131 @@
+/*******************************************************************************
+r.sun: This program was writen by Jaro Hofierka in Summer 1993 and re-engineered
+in 1996-1999. In cooperation with Marcel Suri and Thomas Huld from JRC in Ispra
+a new version of r.sun was prepared using ESRA solar radiation formulas.
+See manual pages for details.
+(C) 2002 Copyright Jaro Hofierka, Gresaka 22, 085 01 Bardejov, Slovakia,
+ and GeoModel, s.r.o., Bratislava, Slovakia
+email: hofierka@geomodel.sk,marcel.suri@jrc.it,suri@geomodel.sk
+*******************************************************************************/
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*v. 2.0 July 2002, NULL data handling, JH */
+/*v. 2.1 January 2003, code optimization by Thomas Huld, JH */
+
+#define NUM_PARTITIONS "1"
+#define SKIP "1"
+#define BIG 1.e20
+#define LINKE "3.0"
+#define SLOPE "0.0"
+#define ASPECT "270"
+#define ALB "0.2"
+#define STEP "0.5"
+#define BSKY 1.0
+#define DSKY 1.0
+#define DIST "1.0"
+
+#define SCALING_FACTOR 150.
+const double invScale=1./SCALING_FACTOR;
+
+#define AMAX1(arg1, arg2) ((arg1) >= (arg2) ? (arg1) : (arg2))
+#define AMIN1(arg1, arg2) ((arg1) <= (arg2) ? (arg1) : (arg2))
+#define DISTANCE1(x1, x2, y1, y2) (sqrt((x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2)))
+#define DISTANCE2(x00, y00) ((xx0 - x00)*(xx0 - x00) + (yy0 - y00)*(yy0 - y00))
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "sunradstruct.h"
+#include "local_proto.h"
+#include "rsunglobals.h"
+
+
+
+const double pihalf = M_PI*0.5;
+const double pi2 = M_PI*2.;
+const double deg2rad = M_PI/180.;
+const double rad2deg = 180./M_PI;
+
+
+
+FILE *felevin,*faspin,*fslopein,*flinkein,*falbedo,*flatin;
+FILE *fincidout,*fbeam_rad,*finsol_time,*fdiff_rad,*frefl_rad;
+FILE *fw;
+
+
+char *elevin;
+char *aspin;
+char *slopein;
+char *civiltime = NULL;
+char *linkein = NULL;
+char *albedo = NULL;
+char *latin = NULL;
+char *coefbh = NULL;
+char *coefdh = NULL;
+char *incidout = NULL;
+char *longin = NULL;
+char *horizon = NULL;
+char *beam_rad = NULL;
+char *insol_time = NULL;
+char *diff_rad = NULL;
+char *refl_rad = NULL;
+char *glob_rad = NULL;
+char *mapset = NULL;
+char *per;
+char *shade;
+char mapname[1024];
+
+struct Cell_head cellhd;
+struct pj_info iproj;
+struct pj_info oproj;
+struct History hist;
+
+
+int INPUT_part(int offset, double *zmax);
+int OUTGR(void);
+int min(int, int);
+int max(int, int);
+
+void cube(int, int);
+void (*func) (int, int);
+
+void joules2(struct SunGeometryConstDay *sunGeom,
+ struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar,
+ struct GridGeometry *gridGeom,
+ unsigned char *horizonpointer,
+ double latitude, double longitude);
+
+
+void calculate(double singleSlope, double singleAspect,
+ double singleAlbedo, double singleLinke,
+ struct GridGeometry gridGeom);
+double com_declin(int);
+
+int n, m, ip, jp;
+int d, day;
+int saveMemory, numPartitions=1;
+int shadowoffset=0;
+int varCount_global=0;
+int bitCount_global=0;
+int arrayNumInt = 1;
+float **z=NULL, **o=NULL, **s=NULL, **li=NULL, **a=NULL, **la=NULL, **longitArray,
+ **cbhr=NULL, **cdhr=NULL;
+double op, dp;
+double invstepx, invstepy;
+double sr_min = 24., sr_max = 0., ss_min = 24., ss_max = 0.;
+
+float **lumcl, **beam, **insol, **diff, **refl, **globrad;
+unsigned char *horizonarray=NULL;
+double civilTime;
+/*
+double startTime, endTime;
+*/
+double xmin, xmax, ymin, ymax;
+double declin, step, dist;
+double li_max = 0., li_min = 100., al_max = 0., al_min = 1.0, la_max = -90.,
+ la_min = 90.;
+ double offsetx=0.5, offsety=0.5;
+char *tt, *lt;
+/*
+double slope;
+*/
+double o_orig, z1;
+/*
+double lum_C11, lum_C13, lum_C22, lum_C31, lum_C33;
+double sinSolarAltitude; */
+
+/* Sine of the solar altitude (angle above horizon)
+*/
+/*
+double sunrise_time, sunset_time;
+double solarAltitude;
+double tanSolarAlt, solarAzimuth;
+double stepsinangle, stepcosangle;
+double angle;
+*/
+double horizonStep;
+double ltime, tim, timo;
+double declination; /* Contains the negative of the declination at the chosen day*/
+/*
+double lum_C31_l, lum_C33_l;
+*/
+double beam_e, diff_e, refl_e, rr, insol_t;
+double cbh, cdh;
+double TOLER;
+
+int main(int argc, char *argv[])
+{
+ double singleSlope;
+ double singleAspect;
+ double singleAlbedo;
+ double singleLinke;
+
+ struct GModule *module;
+ struct
+ {
+ struct Option *elevin,*aspin,*aspect,*slopein,*slope,*linkein,*lin,*albedo,*longin,
+ *alb,*latin,*lat,*coefbh, *coefdh, *incidout,*beam_rad,
+ *insol_time,*diff_rad,*refl_rad,*glob_rad,*day,*step, *declin,*ltime,*dist,*horizon,*horizonstep,
+ *numPartitions, *civilTime;
+ }
+ parm;
+
+ struct
+ {
+ struct Flag *shade, *saveMemory;
+ }
+ flag;
+
+ struct GridGeometry gridGeom;
+
+
+ G_gisinit(argv[0]);
+ module = G_define_module();
+
+ module->description =
+ _("Computes direct (beam), diffuse and reflected solar irradiation raster "
+ "maps for given day, latitude, surface and atmospheric conditions. Solar "
+ "parameters (e.g. sunrise, sunset times, declination, extraterrestrial "
+ "irradiance, daylight length) are saved in a local text file. "
+ "Alternatively, a local time can be specified to compute solar "
+ "incidence angle and/or irradiance raster maps. The shadowing effect of "
+ "the topography is optionally incorporated.");
+
+ if(G_get_set_window(&cellhd)==-1) G_fatal_error("G_get_set_window() failed");
+ gridGeom.stepx = cellhd.ew_res;
+ gridGeom.stepy = cellhd.ns_res;
+ invstepx = 1. / gridGeom.stepx;
+ invstepy = 1. / gridGeom.stepy;
+ n /*n_cols */ = cellhd.cols;
+ m /*n_rows */ = cellhd.rows;
+ xmin = cellhd.west;
+ ymin = cellhd.south;
+ xmax = cellhd.east;
+ ymax = cellhd.north;
+ gridGeom.deltx = fabs(cellhd.east - cellhd.west);
+ gridGeom.delty = fabs(cellhd.north - cellhd.south);
+
+ parm.elevin = G_define_option();
+ parm.elevin->key = "elevin";
+ parm.elevin->type = TYPE_STRING;
+ parm.elevin->required = YES;
+ parm.elevin->gisprompt = "old,cell,raster";
+ parm.elevin->description = _("Name of the elevation raster file");
+
+ parm.aspin = G_define_option();
+ parm.aspin->key = "aspin";
+ parm.aspin->type = TYPE_STRING;
+ parm.aspin->required = NO;
+ parm.aspin->gisprompt = "old,cell,raster";
+ parm.aspin->description = _("Name of the aspect raster file");
+
+ parm.aspect = G_define_option();
+ parm.aspect->key = "aspect";
+ parm.aspect->type = TYPE_DOUBLE;
+ parm.aspect->answer = ASPECT;
+ parm.aspect->required = NO;
+ parm.aspect->description = _("A single value of the orientation (aspect), 270 is south");
+
+ parm.slopein = G_define_option();
+ parm.slopein->key = "slopein";
+ parm.slopein->type = TYPE_STRING;
+ parm.slopein->required = NO;
+/* parm.slopein->gisprompt = "old,cell,raster";
+*/
+ parm.slopein->description = _("Name of the slope raster file");
+
+ parm.slope = G_define_option();
+ parm.slope->key = "slope";
+ parm.slope->type = TYPE_DOUBLE;
+ parm.slope->answer = SLOPE;
+ parm.slope->required = NO;
+ parm.slope->description = _("A single value of inclination (slope)");
+
+ parm.linkein = G_define_option();
+ parm.linkein->key = "linkein";
+ parm.linkein->type = TYPE_STRING;
+ parm.linkein->required = NO;
+ parm.linkein->gisprompt = "old,cell,raster";
+ parm.linkein->description =
+ _("Name of the Linke turbidity coefficient raster file");
+
+ if (parm.linkein->answer == NULL) {
+ parm.lin = G_define_option();
+ parm.lin->key = "lin";
+ parm.lin->type = TYPE_DOUBLE;
+ parm.lin->answer = LINKE;
+ parm.lin->required = NO;
+ parm.lin->description =
+ _("A single value of the Linke turbidity coefficient");
+ }
+
+ parm.albedo = G_define_option();
+ parm.albedo->key = "albedo";
+ parm.albedo->type = TYPE_STRING;
+ parm.albedo->required = NO;
+ parm.albedo->gisprompt = "old,cell,raster";
+ parm.albedo->description = _("Name of the albedo coefficient raster file");
+
+ if (parm.albedo->answer == NULL) {
+ parm.alb = G_define_option();
+ parm.alb->key = "alb";
+ parm.alb->type = TYPE_DOUBLE;
+ parm.alb->answer = ALB;
+ parm.alb->required = NO;
+ parm.alb->description = _("A single value of the albedo coefficient");
+ }
+
+ parm.latin = G_define_option();
+ parm.latin->key = "latin";
+ parm.latin->type = TYPE_STRING;
+ parm.latin->required = NO;
+ parm.latin->gisprompt = "old,cell,raster";
+ parm.latin->description = _("Name of the latitude raster file");
+
+ if (parm.latin->answer == NULL) {
+ parm.lat = G_define_option();
+ parm.lat->key = "lat";
+ parm.lat->type = TYPE_DOUBLE;
+ parm.lat->required = NO;
+ parm.lat->description = _("A single value of latitude");
+ }
+
+ parm.longin = G_define_option();
+ parm.longin->key = "longin";
+ parm.longin->type = TYPE_STRING;
+ parm.longin->required = NO;
+ parm.longin->gisprompt = "old,cell,raster";
+ parm.longin->description = _("Name of the longitude raster file");
+
+
+ parm.coefbh = G_define_option();
+ parm.coefbh->key = "coefbh";
+ parm.coefbh->type = TYPE_STRING;
+ parm.coefbh->required = NO;
+ parm.coefbh->gisprompt = "old,cell,raster";
+ parm.coefbh->description = _("The real-sky beam radiation coefficient file");
+
+ parm.coefdh = G_define_option();
+ parm.coefdh->key = "coefdh";
+ parm.coefdh->type = TYPE_STRING;
+ parm.coefdh->required = NO;
+ parm.coefdh->gisprompt = "old,cell,raster";
+ parm.coefdh->description =
+ _("The real-sky diffuse radiation coefficient file");
+
+
+ parm.horizon = G_define_option();
+ parm.horizon->key = "horizon";
+ parm.horizon->type = TYPE_STRING;
+ parm.horizon->required = NO;
+ parm.horizon->gisprompt = "old,cell,raster";
+ parm.horizon->description = _("The horizon information file prefix");
+
+ parm.horizonstep = G_define_option();
+ parm.horizonstep->key = "horizonstep";
+ parm.horizonstep->type = TYPE_DOUBLE;
+ parm.horizonstep->required = NO;
+ parm.horizonstep->description = _("Angle step size for the horizon information (degrees)");
+
+ parm.incidout = G_define_option();
+ parm.incidout->key = "incidout";
+ parm.incidout->type = TYPE_STRING;
+ parm.incidout->required = NO;
+ parm.incidout->gisprompt = "old,cell,raster";
+ parm.incidout->description = _("Output incidence angle file (raster)");
+
+ parm.beam_rad = G_define_option();
+ parm.beam_rad->key = "beam_rad";
+ parm.beam_rad->type = TYPE_STRING;
+ parm.beam_rad->required = NO;
+ parm.beam_rad->gisprompt = "old,cell,raster";
+ parm.beam_rad->description =
+ _("Output direct (beam) irradiance/irradiation file (raster)");
+
+ parm.insol_time = G_define_option();
+ parm.insol_time->key = "insol_time";
+ parm.insol_time->type = TYPE_STRING;
+ parm.insol_time->required = NO;
+ parm.insol_time->gisprompt = "old,cell,raster";
+ parm.insol_time->description = _("Output insolation time file (raster)");
+
+ parm.diff_rad = G_define_option();
+ parm.diff_rad->key = "diff_rad";
+ parm.diff_rad->type = TYPE_STRING;
+ parm.diff_rad->required = NO;
+ parm.diff_rad->gisprompt = "old,cell,raster";
+ parm.diff_rad->description =
+ _("Output diffuse irradiance/irradiation file (raster)");
+
+ parm.refl_rad = G_define_option();
+ parm.refl_rad->key = "refl_rad";
+ parm.refl_rad->type = TYPE_STRING;
+ parm.refl_rad->required = NO;
+ parm.refl_rad->gisprompt = "old,cell,raster";
+ parm.refl_rad->description =
+ _("Output reflected irradiance/irradiation file (raster)");
+
+ parm.glob_rad = G_define_option();
+ parm.glob_rad->key = "glob_rad";
+ parm.glob_rad->type = TYPE_STRING;
+ parm.glob_rad->required = NO;
+ parm.glob_rad->gisprompt = "old,cell,raster";
+ parm.glob_rad->description = _("Output global (total) irradiance/irradiation file (raster)");
+
+
+ parm.day = G_define_option();
+ parm.day->key = "day";
+ parm.day->type = TYPE_INTEGER;
+ parm.day->required = YES;
+ parm.day->description = _("No. of day of the year (1-365)");
+
+ parm.step = G_define_option();
+ parm.step->key = "step";
+ parm.step->type = TYPE_DOUBLE;
+ parm.step->answer = STEP;
+ parm.step->required = NO;
+ parm.step->description = _("Time step computing all-day radiation");
+
+ parm.declin = G_define_option();
+ parm.declin->key = "declin";
+ parm.declin->type = TYPE_DOUBLE;
+ parm.declin->required = NO;
+ parm.declin->description =
+ _("Required declination value (overriding the internal value)");
+
+ parm.ltime = G_define_option();
+ parm.ltime->key = "time";
+ parm.ltime->type = TYPE_DOUBLE;
+ /* parm.ltime->answer = TIME; */
+ parm.ltime->required = NO;
+ parm.ltime->description = _("Local (solar) time [decimal hours]");
+
+/*
+ parm.startTime = G_define_option();
+ parm.startTime->key = "starttime";
+ parm.startTime->type = TYPE_DOUBLE;
+ parm.startTime->required = NO;
+ parm.startTime->description = _("Starting time for calculating results for several different times.");
+
+ parm.endTime = G_define_option();
+ parm.endTime->key = "endtime";
+ parm.endTime->type = TYPE_DOUBLE;
+ parm.endTime->required = NO;
+ parm.endTime->description = _("End time for calculating results for several different times.)";
+*/
+
+ parm.dist = G_define_option();
+ parm.dist->key = "dist";
+ parm.dist->type = TYPE_DOUBLE;
+ parm.dist->answer = DIST;
+ parm.dist->required = NO;
+ parm.dist->description = _("Sampling distance step coefficient (0.5-1.5)");
+
+ parm.numPartitions = G_define_option();
+ parm.numPartitions->key = "numpartitions";
+ parm.numPartitions->type = TYPE_INTEGER;
+ parm.numPartitions->answer = NUM_PARTITIONS;
+ parm.numPartitions->required = NO;
+ parm.numPartitions->description = _("Read the input files in this number of chunks");
+
+ parm.civilTime = G_define_option();
+ parm.civilTime->key = "civiltime";
+ parm.civilTime->type = TYPE_DOUBLE;
+ parm.civilTime->required = NO;
+ parm.civilTime->description = _("(optional) The civil time zone value, if none, the time will be local solar time");
+
+
+ flag.shade = G_define_flag();
+ flag.shade->key = 's';
+ flag.shade->description =
+ _("Do you want to incorporate the shadowing effect of terrain (y/n)");
+
+ flag.saveMemory = G_define_flag();
+ flag.saveMemory->key = 'm';
+ flag.saveMemory->description = _("Do you want to use the low-memory version of the program (y/n)");
+
+
+ if(G_parser(argc,argv))
+ exit(EXIT_FAILURE);
+
+
+ setUseShadow(flag.shade->answer);
+
+/*
+ if(shd)
+ {
+
+ }
+*/
+ saveMemory=flag.saveMemory->answer;
+ civiltime = parm.civilTime->answer;
+
+
+ elevin = parm.elevin->answer;
+ aspin = parm.aspin->answer;
+ slopein = parm.slopein->answer;
+ linkein = parm.linkein->answer;
+ albedo = parm.albedo->answer;
+ latin = parm.latin->answer;
+
+
+ if(civiltime != NULL)
+ {
+ setUseCivilTime(1);
+ longin = parm.longin->answer;
+
+ if(longin == NULL)
+ {
+ G_fatal_error(_("You must give the longitude raster if you use civil time"));
+
+ }
+ sscanf(parm.civilTime->answer, "%lf", &civilTime);
+
+ /* Normalize if somebody should be weird enough to give more than +- 12
+ hours offset. */
+
+ civilTime -= 24*((int) (civilTime/24.));
+ if(civilTime<-12.)
+ {
+ civilTime +=24.;
+ }
+ else if(civilTime>12.)
+ {
+ civilTime-=24;
+ }
+
+ }
+ else
+ {
+ setUseCivilTime(0);
+ }
+ coefbh = parm.coefbh->answer;
+ coefdh = parm.coefdh->answer;
+ incidout = parm.incidout->answer;
+ horizon = parm.horizon->answer;
+ setUseHorizonData(horizon!=NULL);
+ beam_rad = parm.beam_rad->answer;
+ insol_time = parm.insol_time->answer;
+ diff_rad = parm.diff_rad->answer;
+ refl_rad = parm.refl_rad->answer;
+ glob_rad = parm.glob_rad->answer;
+
+ if((insol_time != NULL) && (incidout != NULL))
+ G_fatal_error(_("insol_time and incidout are incompatible options"));
+
+ sscanf(parm.day->answer, "%d", &day);
+ sscanf(parm.step->answer, "%lf", &step);
+
+ if(parm.step->answer!=NULL)
+ {
+ if(sscanf(parm.step->answer, "%lf", &step)!=1)
+ G_fatal_error(_("Error reading time step size"));
+ }
+ if(parm.horizonstep->answer!=NULL)
+ {
+ if(sscanf(parm.horizonstep->answer, "%lf", &horizonStep)!=1)
+ G_fatal_error(_("Error reading horizon step size"));
+ setHorizonInterval(deg2rad* horizonStep);
+ }
+
+
+ tt = parm.ltime->answer;
+ if (parm.ltime->answer != NULL) {
+ if(insol_time != NULL) G_fatal_error(_("time and insol_time are incompatible options"));
+ G_message ( _("Mode 1: instantaneous solar incidence angle & irradiance using a set local time"));
+ sscanf(parm.ltime->answer, "%lf", &timo);
+ }
+ else {
+ if(incidout != NULL) G_fatal_error(_("incidout requres time parameter to be set"));
+ G_message ( _("Mode 2: integrated daily irradiation"));
+ }
+
+/*
+ if (parm.startTime->answer != NULL) sscanf(parm.startTime->answer, "%lf", &startTime);
+ if (parm.endTime->answer != NULL) sscanf(parm.endTime->answer, "%lf", &endTime);
+
+ if((parm.startTime->answer != NULL) ||(parm.endTime->answer != NULL))
+ {
+*/
+ /* The start and end times should only be defined if the single
+ time is not defined, and if the step size *is* defined. */
+/*
+ if(parm.step->answer==NULL)
+ {
+ printf("If you want to use a time interval you must also define a step size.\n");
+ exit(1);
+ }
+ if(parm.ltime->answer!=NULL)
+ {
+ printf("If you want to use a time interval you can't define a single time value.\n");
+ exit(1);
+ }
+ if((parm.startTime->answer==NULL)||(parm.endTime->answer==NULL))
+ {
+ printf("If you want to use a time interval\n");
+ printf("both the start and end times must be defined.\n");
+ exit(1);
+ }
+ }
+*/
+ if (parm.linkein->answer == NULL)
+ sscanf(parm.lin->answer, "%lf", &singleLinke);
+ if (parm.albedo->answer == NULL)
+ sscanf(parm.alb->answer, "%lf", &singleAlbedo);
+ lt = parm.lat->answer;
+/*
+ if (parm.lat->answer != NULL)
+ sscanf(parm.lat->answer, "%lf", &latitude);
+*/
+ if (parm.slopein->answer == NULL)
+ sscanf(parm.slope->answer, "%lf", &singleSlope);
+ singleSlope *= deg2rad;
+
+ if (parm.aspin->answer == NULL)
+ sscanf(parm.aspect->answer, "%lf", &singleAspect);
+ singleAspect *= deg2rad;
+
+ if (parm.coefbh->answer == NULL)
+ cbh = BSKY;
+ if (parm.coefdh->answer == NULL)
+ cdh = DSKY;
+ sscanf(parm.dist->answer, "%lf", &dist);
+
+ if(parm.numPartitions->answer != NULL)
+ {
+ sscanf(parm.numPartitions->answer, "%d", &numPartitions);
+ if(useShadow()&&(!useHorizonData())&&(numPartitions!=1))
+ {
+ /* If you calculate shadows on the fly, the number of partitions
+ must be one.
+ */
+ G_fatal_error(_("If you use -s and no horizon rasters, numpartitions must be =1"));
+
+ }
+
+ }
+
+ gridGeom.stepxy = dist * 0.5 * (gridGeom.stepx + gridGeom.stepy);
+ TOLER = gridGeom.stepxy * EPS;
+
+ /* The save memory scheme will not work if you want to calculate shadows
+ on the fly. If you calculate without shadow effects or if you have the
+ shadows pre-calculated, there is no problem. */
+
+ if(saveMemory && useShadow() && (!useHorizonData()))
+ G_fatal_error(_("If you want to save memory and to use shadows, you must use pre-calculated horizons."));
+
+ if (parm.declin->answer == NULL)
+ declination = com_declin(day);
+ else {
+ sscanf(parm.declin->answer, "%lf", &declin);
+ declination = -declin;
+ }
+
+
+/*
+ if (lt != NULL)
+ latitude = -latitude * deg2rad;
+*/
+ if(tt!=0)
+ {
+ /* Shadow for just one time during the day */
+ if(horizon==NULL)
+ {
+ arrayNumInt = 1;
+ }
+ else if (useHorizonData())
+ {
+ arrayNumInt = (int)(360. / horizonStep);
+
+ }
+ }
+ else
+ {
+ if (useHorizonData())
+ {
+/* Number of bytes holding the horizon information */
+ arrayNumInt = (int)(360. / horizonStep);
+ }
+ }
+
+ if (tt != NULL) {
+
+ tim = (timo - 12) * 15;
+ /* converting to degrees */
+ /* Jenco (12-timeAngle) * 15 */
+ if (tim < 0)
+ tim += 360;
+ tim = M_PI * tim / 180;
+ /* conv. to radians */
+ }
+
+ /* Set up parameters for projection to lat/long if necessary */
+
+
+ struct Key_Value *in_proj_info, *in_unit_info;
+
+ if ((in_proj_info = G_get_projinfo()) == NULL)
+ G_fatal_error
+ (_("Can't get projection info of current location: please set latitude via 'lat' or 'latin' option!"));
+
+ if ((in_unit_info = G_get_projunits()) == NULL)
+ G_fatal_error(_("Can't get projection units of current location"));
+
+ if (pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0)
+ G_fatal_error
+ (_("Can't get projection key values of current location"));
+
+ G_free_key_value(in_proj_info);
+ G_free_key_value(in_unit_info);
+
+ /* Set output projection to latlong w/ same ellipsoid */
+ oproj.zone = 0;
+ oproj.meters = 1.;
+ sprintf(oproj.proj, "ll");
+ if ((oproj.pj = pj_latlong_from_proj(iproj.pj)) == NULL)
+ G_fatal_error(_("Unable to set up lat/long projection parameters"));
+
+
+/**********end of parser - ******************************/
+
+ calculate(singleSlope, singleAspect, singleAlbedo,
+ singleLinke,gridGeom);
+ OUTGR();
+
+ return 1;
+}
+
+
+int INPUT_part(int offset, double *zmax)
+
+{
+ int finalRow, rowrevoffset;
+ int numRows;
+ FCELL *cell1=NULL, *cell2=NULL;
+ FCELL *cell3=NULL, *cell4=NULL, *cell5=NULL, *cell6=NULL, *cell7=NULL;
+ FCELL *rast1=NULL, *rast2=NULL;
+ static FCELL **horizonbuf;
+ char* horizonpointer;
+ int fd1=-1, fd2=-1, fd3=-1, fd4=-1, fd5=-1, fd6=-1, fd7=-1, row, row_rev;
+ static int *fd_shad;
+ int fr1=-1, fr2=-1;
+ int l, i, j;
+ char shad_filename[256];
+
+ finalRow = m- offset -m/numPartitions;
+ if(finalRow<0)
+ {
+ finalRow = 0;
+ }
+
+ numRows = m/numPartitions;
+
+ cell1=G_allocate_f_raster_buf();
+
+ if(z==NULL)
+ {
+ z = (float **)malloc(sizeof(float *)*(numRows));
+
+
+ for(l=0;l=finalRow; row--)
+ {
+
+ row_rev = m - row - 1;
+ rowrevoffset = row_rev-offset;
+ G_get_f_raster_row(fd_shad[i],horizonbuf[i],row);
+ horizonpointer = horizonarray + arrayNumInt*n*rowrevoffset;
+ for (j=0; j=finalRow; row--)
+ {
+ G_get_f_raster_row(fd1,cell1,row);
+ if(aspin != NULL) G_get_f_raster_row(fd2,cell2,row);
+ if(slopein != NULL) G_get_f_raster_row(fd3,cell3,row);
+ if(linkein != NULL) G_get_f_raster_row(fd4,cell4,row);
+ if(albedo != NULL) G_get_f_raster_row(fd5,cell5,row);
+ if(latin != NULL) G_get_f_raster_row(fd6,cell6,row);
+ if(longin != NULL) G_get_f_raster_row(fd7,cell7,row);
+ if(coefbh != NULL) G_get_f_raster_row(fr1,rast1,row);
+ if(coefdh != NULL) G_get_f_raster_row(fr2,rast2,row);
+
+
+
+ row_rev = m - row - 1;
+ rowrevoffset = row_rev-offset;
+
+ for (j=0; j= arg2) {
+ res = arg1;
+ }
+ else {
+ res = arg2;
+ }
+ return res;
+}
+*/
+
+
+
+/**********************************************************/
+
+
+void joules2(struct SunGeometryConstDay *sunGeom,
+ struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar,
+ struct GridGeometry *gridGeom, unsigned char *horizonpointer,
+ double latitude, double longitude)
+ {
+
+ double s0, dfr, dfr_rad;
+ double ra, dra;
+ int ss = 1;
+ double firstTime;
+ double firstAngle, lastAngle;
+ int srStepNo;
+ double bh;
+ double rr;
+
+ beam_e = 0.;
+ diff_e = 0.;
+ refl_e = 0.;
+ insol_t = 0.;
+
+
+ com_par(sunGeom, sunVarGeom,gridGeom,latitude,longitude);
+
+ if (tt != NULL) { /*irradiance */
+
+ s0 = lumcline2(sunGeom,sunVarGeom,sunSlopeGeom,gridGeom,
+ horizonpointer);
+
+ if (sunVarGeom->solarAltitude > 0.) {
+ if ((!sunVarGeom->isShadow) && (s0 > 0.)) {
+ ra = brad(s0,&bh, sunVarGeom,sunSlopeGeom,sunRadVar); /* beam radiation */
+ beam_e += ra;
+ }
+ else {
+ beam_e = 0.;
+ bh = 0.;
+ }
+
+ if((diff_rad != NULL) || (glob_rad!=NULL)) {
+ dra = drad(s0,bh, &rr, sunVarGeom,sunSlopeGeom,sunRadVar); /* diffuse rad. */
+ diff_e += dra;
+ }
+ if((refl_rad != NULL) || (glob_rad!=NULL)) {
+ if ((diff_rad == NULL) && (glob_rad == NULL))
+ drad(s0,bh, &rr, sunVarGeom,sunSlopeGeom,sunRadVar);
+ refl_e += rr; /* reflected rad. */
+ }
+ } /* solarAltitude */
+ }
+ else {
+ /* all-day radiation */
+
+ srStepNo = (int) (sunGeom->sunrise_time/step);
+
+ if((sunGeom->sunrise_time-srStepNo*step)>0.5*step)
+ {
+ firstTime = (srStepNo+1.5)*step;
+ }
+ else
+ {
+ firstTime = (srStepNo+0.5)*step;
+ }
+
+
+ firstAngle = (firstTime - 12)*HOURANGLE;
+ lastAngle = (sunGeom->sunset_time - 12)*HOURANGLE;
+
+
+
+
+ dfr_rad = step * HOURANGLE;
+
+ sunGeom->timeAngle = firstAngle;
+
+ varCount_global=0;
+
+
+ dfr = step;
+
+ while (ss == 1) {
+
+ com_par(sunGeom,sunVarGeom,gridGeom,latitude,longitude);
+ s0 = lumcline2(sunGeom,sunVarGeom,sunSlopeGeom,gridGeom,
+ horizonpointer);
+
+ if (sunVarGeom->solarAltitude > 0.)
+ {
+
+ if ((!sunVarGeom->isShadow) && (s0 > 0.))
+ {
+ insol_t += dfr;
+ ra = brad(s0,&bh,sunVarGeom,sunSlopeGeom,sunRadVar);
+ beam_e += dfr * ra;
+ ra=0.;
+ }
+ else
+ {
+ bh = 0.;
+ }
+ if((diff_rad != NULL) || (glob_rad!=NULL))
+ {
+ dra = drad(s0,bh, &rr, sunVarGeom,sunSlopeGeom,sunRadVar);
+ diff_e += dfr * dra;
+ dra=0.;
+ }
+ if((refl_rad != NULL) || (glob_rad!=NULL))
+ {
+ if ((diff_rad == NULL) && (glob_rad == NULL))
+ {
+ drad(s0,bh, &rr, sunVarGeom,sunSlopeGeom,sunRadVar);
+ }
+ refl_e += dfr * rr;
+ rr = 0.;
+ }
+ } /* illuminated */
+
+
+ sunGeom->timeAngle = sunGeom->timeAngle + dfr_rad;
+
+ if (sunGeom->timeAngle > lastAngle) {
+ ss = 0; /* we've got the sunset */
+ }
+ } /* end of while */
+ } /* all-day radiation */
+
+}
+/*//////////////////////////////////////////////////////////////////////*/
+
+
+
+
+/*
+void where_is_point(void)
+{
+ double sx, sy;
+ double dx, dy;
+ double adx, ady;
+ int i, j;
+
+ sx = xx0 * invstepx + TOLER;
+ sy = yy0 * invstepy + TOLER;
+
+ i = (int)sx;
+ j = (int)sy;
+ if (i < n - 1 && j < m - 1) {
+
+ dx = xx0 - (double)i *stepx;
+ dy = yy0 - (double)j *stepy;
+
+ adx = fabs(dx);
+ ady = fabs(dy);
+
+ if ((adx > TOLER) && (ady > TOLER)) {
+ cube(j, i);
+ return;
+ }
+ else if ((adx > TOLER) && (ady < TOLER)) {
+ line_x(j, i);
+ return;
+ }
+ else if ((adx < TOLER) && (ady > TOLER)) {
+ line_y(j, i);
+ return;
+ }
+ else if ((adx < TOLER) && (ady < TOLER)) {
+ vertex(j, i);
+ return;
+ }
+
+
+ }
+ else {
+ func = NULL;
+ }
+}
+
+*/
+
+void where_is_point(double *length , struct SunGeometryVarDay *sunVarGeom,
+ struct GridGeometry *gridGeom)
+{
+ double sx, sy;
+ double dx, dy;
+/* double adx, ady;*/
+ int i, j;
+
+ sx = gridGeom->xx0 * invstepx + offsetx; /* offset 0.5 cell size to get the right cell i, j */
+ sy = gridGeom->yy0 * invstepy + offsety;
+
+ i = (int)sx; j = (int)sy;
+
+/* if (i < n-1 && j < m-1) { to include last row/col*/
+ if (i <= n-1 && j <= m-1) {
+
+ dx = (double)i *gridGeom->stepx;
+ dy = (double)j *gridGeom->stepy;
+
+ *length = DISTANCE1(gridGeom->xg0, dx, gridGeom->yg0, dy); /* dist from orig. grid point to the current grid point */
+
+ sunVarGeom->zp = z[j][i];
+
+/*
+ cube(j, i);
+*/
+ }
+}
+
+/*
+void vertex(jmin, imin)
+ int jmin, imin;
+{
+ zp = z[jmin][imin];
+ if ((zp == UNDEFZ))
+ func = NULL;
+}
+void line_x(jmin, imin)
+ int jmin, imin;
+{
+ double c1, c2;
+ double d1, d2, e1, e2;
+ e1 = (double)imin *stepx;
+ e2 = (double)(imin + 1) * stepx;
+
+ c1 = z[jmin][imin];
+ c2 = z[jmin][imin + 1];
+ if (!((c1 == UNDEFZ) || (c2 == UNDEFZ))) {
+
+ if (dist <= 1.0) {
+ d1 = (xx0 - e1) / (e2 - e1);
+ d2 = 1 - d1;
+ if (d1 < d2)
+ zp = c1;
+ else
+ zp = c2;
+ }
+
+ if (dist > 1.0)
+ zp = AMAX1(c1, c2);
+ }
+ else
+ func = NULL;
+}
+
+
+void line_y(jmin, imin)
+ int jmin, imin;
+{
+ double c1, c2;
+ double d1, d2, e1, e2;
+ e1 = (double)jmin *stepy;
+ e2 = (double)(jmin + 1) * stepy;
+
+ c1 = z[jmin][imin];
+ c2 = z[jmin + 1][imin];
+ if (!((c1 == UNDEFZ) || (c2 == UNDEFZ))) {
+
+ if (dist <= 1.0) {
+ d1 = (yy0 - e1) / (e2 - e1);
+ d2 = 1 - d1;
+ if (d1 < d2)
+ zp = c1;
+ else
+ zp = c2;
+ }
+
+ if (dist > 1.0)
+ zp = AMAX1(c1, c2);
+
+ }
+ else
+ func = NULL;
+
+}
+
+void cube(jmin, imin)
+ int jmin, imin;
+{
+ int i, ig = 0;
+ double x1, x2, y1, y2;
+ double v[4], vmin = BIG;
+ double c[4], cmax = -BIG;
+
+ x1 = (double)imin *stepx;
+ x2 = x1 + stepx;
+
+ y1 = (double)jmin *stepy;
+ y2 = y1 + stepy;
+
+ v[0] = DISTANCE2(x1, y1);
+
+ if (v[0] < vmin) {
+ ig = 0;
+ vmin = v[0];
+ }
+ v[1] = DISTANCE2(x2, y1);
+
+ if (v[1] < vmin) {
+ ig = 1;
+ vmin = v[1];
+ }
+
+ v[2] = DISTANCE2(x2, y2);
+ if (v[2] < vmin) {
+ ig = 2;
+ vmin = v[2];
+ }
+
+ v[3] = DISTANCE2(x1, y2);
+ if (v[3] < vmin) {
+ ig = 3;
+ vmin = v[3];
+ }
+
+ c[0] = z[jmin][imin];
+ c[1] = z[jmin][imin + 1];
+ c[2] = z[jmin + 1][imin + 1];
+ c[3] = z[jmin + 1][imin];
+
+
+ if (dist <= 1.0) {
+
+ if (c[ig] != UNDEFZ)
+ zp = c[ig];
+ else
+ func = NULL;
+ return;
+ }
+
+ if (dist > 1.0) {
+ for (i = 0; i < 4; i++) {
+ if (c[i] != UNDEFZ) {
+ cmax = AMAX1(cmax, c[i]);
+ zp = cmax;
+ }
+ else
+ func = NULL;
+ }
+ }
+}
+*/
+
+/*
+void cube(jmin, imin)
+int jmin, imin;
+{
+ zp = z[jmin][imin];
+
+}
+*/
+
+void cube(jmin, imin)
+{}
+
+
+/*////////////////////////////////////////////////////////////////////// */
+
+void calculate(double singleSlope, double singleAspect, double singleAlbedo, double singleLinke,
+ struct GridGeometry gridGeom)
+{
+ int i, j, l;
+ /* double energy; */
+ int someRadiation;
+ int numRows;
+ int arrayOffset;
+ double lum, q1;
+ double dayRad;
+ double latid_l, cos_u, cos_v, sin_u, sin_v;
+ double sin_phi_l, tan_lam_l;
+ double zmax;
+ double longitTime=0.;
+ double locTimeOffset;
+ double latitude, longitude;
+
+
+ struct SunGeometryConstDay sunGeom;
+ struct SunGeometryVarDay sunVarGeom;
+ struct SunGeometryVarSlope sunSlopeGeom;
+ struct SolarRadVar sunRadVar;
+
+ sunSlopeGeom.slope=singleSlope;
+ sunSlopeGeom.aspect=singleAspect;
+ sunRadVar.alb=singleAlbedo;
+ sunRadVar.linke=singleLinke;
+ sunRadVar.cbh = 1.0;
+ sunRadVar.cdh = 1.0;
+
+ sunGeom.sindecl = sin(declination);
+ sunGeom.cosdecl = cos(declination);
+
+
+ someRadiation = (beam_rad != NULL) || (insol_time != NULL) || (diff_rad != NULL) ||
+ (refl_rad != NULL)|| (glob_rad != NULL);
+
+
+ fprintf(stderr, "\n\n");
+
+ if (incidout != NULL) {
+ lumcl = (float **)malloc(sizeof(float *) * (m));
+ for (l = 0; l < m; l++) {
+ lumcl[l] = (float *)malloc(sizeof(float) * (n));
+ }
+ for (j = 0; j < m; j++) {
+ for (i = 0; i < n; i++)
+ lumcl[j][i] = UNDEFZ;
+ }
+ }
+
+ if (beam_rad != NULL) {
+ beam = (float **)malloc(sizeof(float *) * (m));
+ for (l = 0; l < m; l++) {
+ beam[l] = (float *)malloc(sizeof(float) * (n));
+ }
+
+ for (j = 0; j < m; j++) {
+ for (i = 0; i < n; i++)
+ beam[j][i] = UNDEFZ;
+ }
+ }
+
+ if (insol_time != NULL) {
+ insol = (float **)malloc(sizeof(float *) * (m));
+ for (l = 0; l < m; l++) {
+ insol[l] = (float *)malloc(sizeof(float) * (n));
+ }
+
+ for (j = 0; j < m; j++) {
+ for (i = 0; i < n; i++)
+ insol[j][i] = UNDEFZ;
+ }
+ }
+
+ if (diff_rad != NULL) {
+ diff = (float **)malloc(sizeof(float *) * (m));
+ for (l = 0; l < m; l++) {
+ diff[l] = (float *)malloc(sizeof(float) * (n));
+ }
+
+ for (j = 0; j < m; j++) {
+ for (i = 0; i < n; i++)
+ diff[j][i] = UNDEFZ;
+ }
+ }
+
+ if (refl_rad != NULL) {
+ refl = (float **)malloc(sizeof(float *) * (m));
+ for (l = 0; l < m; l++) {
+ refl[l] = (float *)malloc(sizeof(float) * (n));
+ }
+
+ for (j = 0; j < m; j++) {
+ for (i = 0; i < n; i++)
+ refl[j][i] = UNDEFZ;
+ }
+ }
+
+ if (glob_rad != NULL)
+ {
+ globrad = (float **)malloc(sizeof(float *)*(m));
+ for( l=0; l day + 5)
+ return 0;
+ else
+ return 1;
+}
Added: trunk/grassaddons/r.sun_horizon/r.sun2/rsunglobals.h
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/rsunglobals.h (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/rsunglobals.h 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,62 @@
+/*******************************************************************************
+r.sun: rsunglobals.h. This program was writen by Jaro Hofierka in Summer 1993 and re-engineered
+in 1996-1999. In cooperation with Marcel Suri and Thomas Huld from JRC in Ispra
+a new version of r.sun was prepared using ESRA solar radiation formulas.
+See manual pages for details.
+(C) 2002 Copyright Jaro Hofierka, Gresaka 22, 085 01 Bardejov, Slovakia,
+ and GeoModel, s.r.o., Bratislava, Slovakia
+email: hofierka@geomodel.sk,marcel.suri@jrc.it,suri@geomodel.sk
+*******************************************************************************/
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*v. 2.0 July 2002, NULL data handling, JH */
+/*v. 2.1 January 2003, code optimization by Thomas Huld, JH */
+
+#define EARTHRADIUS 6371000.
+/* undefined value for terrain aspect */
+#define UNDEF 0.
+/* internal undefined value for NULL */
+#define UNDEFZ -9999.
+
+/* Constant for calculating angular loss */
+#define a_r 0.155
+
+extern int varCount_global;
+extern int bitCount_global;
+extern int arrayNumInt;
+
+/*
+extern double xp;
+extern double yp;
+*/
+
+extern double angular_loss_denom;
+
+extern const double invScale;
+extern const double pihalf;
+extern const double pi2;
+extern const double deg2rad;
+extern const double rad2deg;
+
+extern struct pj_info iproj;
+extern struct pj_info oproj;
+
+
+extern void (*func) (int, int);
+
Added: trunk/grassaddons/r.sun_horizon/r.sun2/rsunlib.c
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/rsunlib.c (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/rsunlib.c 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,699 @@
+/*******************************************************************************
+r.sun: rsunlib.c. This program was writen by Jaro Hofierka in Summer 1993 and re-engineered
+in 1996-1999. In cooperation with Marcel Suri and Thomas Huld from JRC in Ispra
+a new version of r.sun was prepared using ESRA solar radiation formulas.
+See manual pages for details.
+(C) 2002 Copyright Jaro Hofierka, Gresaka 22, 085 01 Bardejov, Slovakia,
+ and GeoModel, s.r.o., Bratislava, Slovakia
+email: hofierka@geomodel.sk,marcel.suri@jrc.it,suri@geomodel.sk
+*******************************************************************************/
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*v. 2.0 July 2002, NULL data handling, JH */
+/*v. 2.1 January 2003, code optimization by Thomas Huld, JH */
+
+#include
+#include
+#include
+#include
+#include
+#include "sunradstruct.h"
+#include "local_proto.h"
+#include "rsunglobals.h"
+
+
+int civilTimeFlag;
+int useCivilTime()
+ {
+ return civilTimeFlag;
+ }
+void setUseCivilTime(int val)
+ {
+ civilTimeFlag=val;
+ }
+
+
+double angular_loss_denom;
+
+void setAngularLossDenominator()
+{
+ angular_loss_denom=1./(1-exp(-1./a_r));
+
+}
+
+
+int useShadowFlag;
+int useShadow()
+ {
+ return useShadowFlag;
+ }
+void setUseShadow(int val)
+ {
+ useShadowFlag=val;
+ }
+
+
+
+int useHorizonDataFlag;
+int useHorizonData()
+ {
+ return useHorizonDataFlag;
+ }
+void setUseHorizonData(int val)
+ {
+ useHorizonDataFlag=val;
+ }
+
+double timeOffset;
+double getTimeOffset()
+ {
+ return timeOffset;
+ }
+void setTimeOffset(double val)
+ {
+ timeOffset=val;
+ }
+
+double horizonInterval;
+double getHorizonInterval()
+ {
+ return horizonInterval;
+ }
+void setHorizonInterval(double val)
+ {
+ horizonInterval=val;
+ }
+
+
+
+double com_sol_const(int no_of_day)
+ {
+ double I0, d1;
+
+ /* v W/(m*m) */
+ d1 = pi2 * no_of_day / 365.25;
+ I0 = 1367. * (1 + 0.03344 * cos(d1 - 0.048869));
+
+ return I0;
+ }
+
+
+
+
+void com_par_const(double longitTime, struct SunGeometryConstDay *sungeom,
+ struct GridGeometry *gridGeom)
+ {
+ double pom;
+ double totOffsetTime;
+
+ sungeom->lum_C11 = gridGeom->sinlat * sungeom->cosdecl;
+ sungeom->lum_C13 = -gridGeom->coslat * sungeom->sindecl;
+ sungeom->lum_C22 = sungeom->cosdecl;
+ sungeom->lum_C31 = gridGeom->coslat * sungeom->cosdecl;
+ sungeom->lum_C33 = gridGeom->sinlat * sungeom->sindecl;
+
+ if (fabs(sungeom->lum_C31) >= EPS) {
+ totOffsetTime = timeOffset + longitTime;
+
+ if(useCivilTime())
+ {
+ sungeom->timeAngle -= totOffsetTime*HOURANGLE;
+ }
+ pom = -sungeom->lum_C33 / sungeom->lum_C31;
+ if (fabs(pom) <= 1) {
+ pom = acos(pom);
+ pom = (pom * 180) / M_PI;
+ sungeom->sunrise_time = (90 - pom) / 15 + 6;
+ sungeom->sunset_time = (pom - 90) / 15 + 18;
+ }
+ else {
+ if (pom < 0) {
+ /* printf("\n Sun is ABOVE the surface during the whole day\n"); */
+ sungeom->sunrise_time = 0;
+ sungeom->sunset_time = 24;
+ }
+ else {
+ /* printf("\n The sun is BELOW the surface during the whole day\n"); */
+ if (fabs(pom) - 1 <= EPS) {
+ sungeom->sunrise_time = 12;
+ sungeom->sunset_time = 12;
+ }
+ }
+ }
+ }
+
+}
+
+
+
+
+
+void com_par( struct SunGeometryConstDay *sungeom,
+ struct SunGeometryVarDay *sunVarGeom, struct GridGeometry *gridGeom,
+ double latitude, double longitude)
+{
+ double pom, xpom, ypom;
+
+ double costimeAngle;
+ double lum_Lx, lum_Ly;
+
+ double newLatitude, newLongitude;
+ double inputAngle;
+ double delt_lat, delt_lon;
+ double delt_east, delt_nor;
+ double delt_dist;
+
+
+ costimeAngle = cos(sungeom->timeAngle);
+
+
+
+ lum_Lx = -sungeom->lum_C22 * sin(sungeom->timeAngle);
+ lum_Ly = sungeom->lum_C11 * costimeAngle + sungeom->lum_C13;
+ sunVarGeom->sinSolarAltitude = sungeom->lum_C31 * costimeAngle + sungeom->lum_C33;
+
+ if (fabs(sungeom->lum_C31) < EPS)
+ {
+ if (fabs(sunVarGeom->sinSolarAltitude) >= EPS)
+ {
+ if (sunVarGeom->sinSolarAltitude > 0)
+ {
+ /* printf("\tSun is ABOVE area during the whole day\n"); */
+ sungeom->sunrise_time = 0;
+ sungeom->sunset_time = 24;
+ }
+ else
+ {
+ sunVarGeom->solarAltitude = 0.;
+ sunVarGeom->solarAzimuth = UNDEF;
+ return;
+ }
+ }
+ else
+ {
+ /* printf("\tThe Sun is ON HORIZON during the whole day\n"); */
+ sungeom->sunrise_time = 0;
+ sungeom->sunset_time = 24;
+ }
+ }
+
+ sunVarGeom->solarAltitude = asin(sunVarGeom->sinSolarAltitude); /* vertical angle of the sun */
+ /* sinSolarAltitude is sin(solarAltitude) */
+
+ xpom = lum_Lx * lum_Lx;
+ ypom = lum_Ly * lum_Ly;
+ pom = sqrt(xpom + ypom);
+
+
+ if (fabs(pom) > EPS)
+ {
+ sunVarGeom->solarAzimuth = lum_Ly / pom;
+ sunVarGeom->solarAzimuth = acos(sunVarGeom->solarAzimuth); /* horiz. angle of the Sun */
+ /* solarAzimuth *= RAD; */
+ if (lum_Lx < 0)
+ sunVarGeom->solarAzimuth = pi2 - sunVarGeom->solarAzimuth;
+ }
+ else
+ {
+ sunVarGeom->solarAzimuth = UNDEF;
+ }
+
+
+
+ if (sunVarGeom->solarAzimuth < 0.5 * M_PI)
+ sunVarGeom->sunAzimuthAngle = 0.5 * M_PI - sunVarGeom->solarAzimuth;
+ else
+ sunVarGeom->sunAzimuthAngle = 2.5 * M_PI - sunVarGeom->solarAzimuth;
+
+
+ inputAngle=sunVarGeom->sunAzimuthAngle+pihalf;
+ inputAngle=(inputAngle>=pi2)?inputAngle-pi2:inputAngle;
+
+
+ delt_lat = -0.0001*cos(inputAngle); /* Arbitrary small distance in latitude */
+ delt_lon = 0.0001*sin(inputAngle)/cos(latitude);
+
+ newLatitude = (latitude+delt_lat)*rad2deg;
+ newLongitude = (longitude+delt_lon)*rad2deg;
+
+
+ if ((G_projection() != PROJECTION_LL))
+ {
+ if (pj_do_proj(&newLongitude, &newLatitude, &oproj, &iproj) <0)
+ {
+ G_fatal_error("Error in pj_do_proj");
+ }
+ }
+
+ delt_east=newLongitude-gridGeom->xp;
+ delt_nor=newLatitude-gridGeom->yp;
+
+ delt_dist=sqrt(delt_east*delt_east+delt_nor*delt_nor);
+
+
+
+ sunVarGeom->stepsinangle = gridGeom->stepxy*delt_nor/delt_dist;
+ sunVarGeom->stepcosangle = gridGeom->stepxy*delt_east/delt_dist;
+
+/*
+ sunVarGeom->stepsinangle = stepxy * sin(sunVarGeom->sunAzimuthAngle);
+ sunVarGeom->stepcosangle = stepxy * cos(sunVarGeom->sunAzimuthAngle);
+*/
+ sunVarGeom->tanSolarAltitude = tan(sunVarGeom->solarAltitude);
+
+ return;
+
+}
+
+
+int searching(double *length, struct SunGeometryVarDay *sunVarGeom,
+ struct GridGeometry *gridGeom)
+{
+ double z2;
+ double curvature_diff;
+ int succes = 0;
+
+ if (sunVarGeom->zp == UNDEFZ)
+ return 0;
+
+
+ gridGeom->yy0 += sunVarGeom->stepsinangle;
+ gridGeom->xx0 += sunVarGeom->stepcosangle;
+ if (((gridGeom->xx0+(0.5*gridGeom->stepx)) < 0)
+ || ((gridGeom->xx0+(0.5*gridGeom->stepx)) > gridGeom->deltx)
+ || ((gridGeom->yy0+(0.5*gridGeom->stepy)) < 0)
+ || ((gridGeom->yy0+(0.5*gridGeom->stepy)) > gridGeom->delty))
+ succes=3;
+ else
+ succes=1;
+
+
+ if (succes == 1)
+ {
+ where_is_point(length, sunVarGeom,gridGeom);
+ if (func == NULL)
+ {
+ gridGeom->xx0 = gridGeom->xg0;
+ gridGeom->yy0 = gridGeom->yg0;
+ return (3);
+ }
+ curvature_diff = EARTHRADIUS*(1.-cos(*length/EARTHRADIUS));
+
+ z2 = sunVarGeom->z_orig + curvature_diff + *length * sunVarGeom->tanSolarAltitude;
+ if (z2 < sunVarGeom->zp)
+ succes = 2; /* shadow */
+ if (z2 > sunVarGeom->zmax)
+ succes = 3; /* no test needed all visible */
+ }
+
+ if(succes!=1)
+ {
+ gridGeom->xx0 = gridGeom->xg0;
+ gridGeom->yy0 = gridGeom->yg0;
+ }
+ return (succes);
+}
+
+
+
+
+double lumcline2(
+ struct SunGeometryConstDay *sungeom,
+ struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct GridGeometry *gridGeom,
+ unsigned char *horizonpointer)
+ {
+ double s = 0;
+ double length;
+ int r = 0;
+
+ int lowPos, highPos;
+ double timeoffset, horizPos;
+ double horizonHeight;
+
+ func = cube;
+ sunVarGeom->isShadow = 0;
+
+ if (useShadow())
+ {
+ length = 0;
+
+ if(useHorizonData())
+ {
+ /* Start is due east, sungeom->timeangle = -pi/2 */
+/*
+ timeoffset = sungeom->timeAngle+pihalf;
+*/
+ timeoffset = sunVarGeom->sunAzimuthAngle;
+
+/*
+ if(timeoffset<0.)
+ timeoffset+=pi2;
+ else if(timeoffset>pi2)
+ timeoffset-=pi2;
+ horizPos = arrayNumInt - timeoffset/horizonInterval;
+*/
+
+ horizPos = timeoffset/getHorizonInterval();
+
+
+ lowPos = (int)horizPos;
+ highPos=lowPos+1;
+ if(highPos==arrayNumInt)
+ {
+ highPos=0;
+ }
+ horizonHeight = invScale*(
+ (1.-(horizPos-lowPos))*horizonpointer[lowPos]
+ +(horizPos-lowPos)
+ *horizonpointer[highPos]);
+ sunVarGeom->isShadow = (horizonHeight>sunVarGeom->solarAltitude);
+
+ if (!sunVarGeom->isShadow)
+ {
+/*
+ if (z_orig != UNDEFZ)
+ {
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l;
+
+ }
+ else
+ {
+ s = sunVarGeom->sinSolarAltitude;
+ }
+*/
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l; /* Jenco */
+ }
+
+
+ } /* End if useHorizonData() */
+ else
+ {
+ while ((r = searching(&length, sunVarGeom, gridGeom)) == 1)
+ {
+ if (r == 3)
+ break; /* no test is needed */
+ }
+
+
+
+
+ if (r == 2)
+ {
+ sunVarGeom->isShadow = 1; /* shadow */
+ }
+ else
+ {
+
+/*
+ if (z_orig != UNDEFZ)
+ {
+
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l;
+ }
+ else
+ {
+ s = sunVarGeom->sinSolarAltitude;
+ }
+*/
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l; /* Jenco */
+ }
+ }
+ }
+ else
+ {
+ /*
+ if (z_orig != UNDEFZ)
+ {
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l;
+ }
+ else
+ {
+ s = sunVarGeom->sinSolarAltitude;
+ }
+*/
+ s = sunSlopeGeom->lum_C31_l * cos(-sungeom->timeAngle - sunSlopeGeom->longit_l) + sunSlopeGeom->lum_C33_l; /* Jenco */
+
+
+ }
+
+ if (s < 0) return 0.;
+ return (s);
+ }
+
+
+
+double brad(double sh, double *bh, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar)
+{
+ double opticalAirMass, airMass2Linke, rayl, br;
+ double drefract, temp1, temp2, h0refract;
+ double elevationCorr;
+
+ double locSolarAltitude;
+
+ locSolarAltitude=sunVarGeom->solarAltitude;
+
+
+ elevationCorr = exp(-sunVarGeom->z_orig / 8434.5);
+ temp1 = 0.1594 + locSolarAltitude * (1.123 + 0.065656 * locSolarAltitude);
+ temp2 = 1. + locSolarAltitude * (28.9344 + 277.3971 * locSolarAltitude);
+ drefract = 0.061359 * temp1 / temp2; /* in radians */
+ h0refract = locSolarAltitude + drefract;
+ opticalAirMass = elevationCorr / (sin(h0refract) +
+ 0.50572 * pow(h0refract * rad2deg + 6.07995, -1.6364));
+ airMass2Linke = 0.8662 * sunRadVar->linke;
+ if (opticalAirMass <= 20.)
+ {
+ rayl = 1. / (6.6296 +
+ opticalAirMass * (1.7513 +
+ opticalAirMass * (-0.1202 + opticalAirMass * (0.0065 - opticalAirMass * 0.00013))));
+ }
+ else
+ {
+ rayl = 1. / (10.4 + 0.718 * opticalAirMass);
+ }
+ *bh = sunRadVar->cbh * sunRadVar->G_norm_extra * sunVarGeom->sinSolarAltitude * exp(-rayl * opticalAirMass * airMass2Linke);
+ if (sunSlopeGeom->aspect != UNDEF && sunSlopeGeom->slope != 0.)
+ br = *bh * sh / sunVarGeom->sinSolarAltitude;
+ else
+ br = *bh;
+
+ return (br);
+}
+
+double brad_angle_loss(double sh, double *bh, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar)
+{
+ double p, opticalAirMass, airMass2Linke, rayl, br;
+ double drefract, temp1, temp2, h0refract;
+
+ double locSolarAltitude;
+
+ locSolarAltitude=sunVarGeom->solarAltitude;
+
+
+ p = exp(-sunVarGeom->z_orig / 8434.5);
+ temp1 = 0.1594 + locSolarAltitude * (1.123 + 0.065656 * locSolarAltitude);
+ temp2 = 1. + locSolarAltitude * (28.9344 + 277.3971 * locSolarAltitude);
+ drefract = 0.061359 * temp1 / temp2; /* in radians */
+ h0refract = locSolarAltitude + drefract;
+ opticalAirMass = p / (sin(h0refract) +
+ 0.50572 * pow(h0refract * rad2deg + 6.07995, -1.6364));
+ airMass2Linke = 0.8662 * sunRadVar->linke;
+ if (opticalAirMass <= 20.)
+ rayl =
+ 1. / (6.6296 +
+ opticalAirMass * (1.7513 +
+ opticalAirMass * (-0.1202 + opticalAirMass * (0.0065 - opticalAirMass * 0.00013))));
+ else
+ rayl = 1. / (10.4 + 0.718 * opticalAirMass);
+ *bh = sunRadVar->cbh * sunRadVar->G_norm_extra * sunVarGeom->sinSolarAltitude * exp(-rayl * opticalAirMass * airMass2Linke);
+ if (sunSlopeGeom->aspect != UNDEF && sunSlopeGeom->slope != 0.)
+ br = *bh * sh / sunVarGeom->sinSolarAltitude;
+ else
+ br = *bh;
+
+ br *= (1-exp(-sh/a_r))*angular_loss_denom;
+
+ return (br);
+}
+
+
+
+double drad(double sh, double bh, double *rr, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar)
+{
+ double tn, fd, fx = 0., A1, A2, A3, A1b;
+ double r_sky, kb, dr, gh, a_ln, ln, fg;
+ double dh;
+ double cosslope, sinslope;
+ double locSinSolarAltitude;
+ double locLinke;
+
+ locLinke = sunRadVar->linke;
+ locSinSolarAltitude=sunVarGeom->sinSolarAltitude;
+
+ cosslope = cos(sunSlopeGeom->slope);
+ sinslope = sin(sunSlopeGeom->slope);
+
+ tn = -0.015843 + locLinke * (0.030543 + 0.0003797 * locLinke);
+ A1b = 0.26463 + locLinke * (-0.061581 + 0.0031408 * locLinke);
+ if (A1b * tn < 0.0022)
+ A1 = 0.0022 / tn;
+ else
+ A1 = A1b;
+ A2 = 2.04020 + locLinke * (0.018945 - 0.011161 * locLinke);
+ A3 = -1.3025 + locLinke * (0.039231 + 0.0085079 * locLinke);
+
+ fd = A1 + A2 * locSinSolarAltitude + A3 * locSinSolarAltitude * locSinSolarAltitude;
+ dh = sunRadVar->cdh * sunRadVar->G_norm_extra * fd * tn;
+ gh = bh + dh;
+ if (sunSlopeGeom->aspect != UNDEF && sunSlopeGeom->slope != 0.) {
+ kb = bh / (sunRadVar->G_norm_extra * locSinSolarAltitude);
+ r_sky = (1. + cosslope) / 2.;
+ a_ln = sunVarGeom->solarAzimuth - sunSlopeGeom->aspect;
+ ln = a_ln;
+ if (a_ln > M_PI)
+ ln = a_ln - pi2;
+ else if (a_ln < -M_PI)
+ ln = a_ln + pi2;
+ a_ln = ln;
+ fg = sinslope - sunSlopeGeom->slope * cosslope -
+ M_PI * sin(0.5*sunSlopeGeom->slope) * sin(0.5*sunSlopeGeom->slope);
+ if ((sunVarGeom->isShadow == 1) || sh <= 0.)
+ fx = r_sky + fg * 0.252271;
+ else if (sunVarGeom->solarAltitude >= 0.1) {
+ fx = ((0.00263 - kb * (0.712 + 0.6883 * kb)) * fg + r_sky) * (1. -
+ kb) +
+ kb * sh / locSinSolarAltitude;
+ }
+ else if (sunVarGeom->solarAltitude < 0.1)
+ fx = ((0.00263 - 0.712 * kb - 0.6883 * kb * kb) * fg +
+ r_sky) * (1. - kb) + kb * sinslope * cos(a_ln) / (0.1 -
+ 0.008 *
+ sunVarGeom->solarAltitude);
+ dr = dh * fx;
+ /* refl. rad */
+ *rr = sunRadVar->alb * gh * (1 - cosslope) / 2.;
+ }
+ else { /* plane */
+ dr = dh;
+ *rr = 0.;
+ }
+ return (dr);
+}
+
+#define c2 -0.074
+
+double drad_angle_loss(double sh, double bh, double *rr, struct SunGeometryVarDay *sunVarGeom,
+ struct SunGeometryVarSlope *sunSlopeGeom,
+ struct SolarRadVar *sunRadVar)
+{
+ double dh;
+ double tn, fd, fx = 0., A1, A2, A3, A1b;
+ double r_sky, kb, dr, gh, a_ln, ln, fg;
+ double cosslope, sinslope;
+
+ double diff_coeff_angleloss;
+ double refl_coeff_angleloss;
+ double c1;
+ double diff_loss_factor, refl_loss_factor;
+ double locSinSolarAltitude;
+ double locLinke;
+
+ locSinSolarAltitude=sunVarGeom->sinSolarAltitude;
+ locLinke = sunRadVar->linke;
+ cosslope = cos(sunSlopeGeom->slope);
+ sinslope = sin(sunSlopeGeom->slope);
+
+
+ tn = -0.015843 + locLinke * (0.030543 + 0.0003797 * locLinke);
+ A1b = 0.26463 + locLinke * (-0.061581 + 0.0031408 * locLinke);
+ if (A1b * tn < 0.0022)
+ A1 = 0.0022 / tn;
+ else
+ A1 = A1b;
+ A2 = 2.04020 + locLinke * (0.018945 - 0.011161 * locLinke);
+ A3 = -1.3025 + locLinke * (0.039231 + 0.0085079 * locLinke);
+
+ fd = A1 + A2 * locSinSolarAltitude + A3 * locSinSolarAltitude * locSinSolarAltitude;
+ dh = sunRadVar->cdh * sunRadVar->G_norm_extra * fd * tn;
+ gh = bh + dh;
+ if (sunSlopeGeom->aspect != UNDEF && sunSlopeGeom->slope != 0.) {
+ kb = bh / (sunRadVar->G_norm_extra * locSinSolarAltitude);
+ r_sky = (1. + cosslope) / 2.;
+ a_ln = sunVarGeom->solarAzimuth - sunSlopeGeom->aspect;
+ ln = a_ln;
+ if (a_ln > M_PI)
+ ln = a_ln - pi2;
+ else if (a_ln < -M_PI)
+ ln = a_ln + pi2;
+ a_ln = ln;
+ fg = sinslope - sunSlopeGeom->slope * cosslope -
+ M_PI * sin(sunSlopeGeom->slope / 2.) * sin(sunSlopeGeom->slope / 2.);
+ if ((sunVarGeom->isShadow) || (sh <= 0.))
+ fx = r_sky + fg * 0.252271;
+ else if (sunVarGeom->solarAltitude >= 0.1) {
+ fx = ((0.00263 - kb * (0.712 + 0.6883 * kb)) * fg + r_sky) * (1. -
+ kb) +
+ kb * sh / locSinSolarAltitude;
+ }
+ else if (sunVarGeom->solarAltitude < 0.1)
+ fx = ((0.00263 - 0.712 * kb - 0.6883 * kb * kb) * fg +
+ r_sky) * (1. - kb) + kb * sinslope * cos(a_ln) / (0.1 -
+ 0.008 *
+ sunVarGeom->solarAltitude);
+ dr = dh * fx;
+ /* refl. rad */
+ *rr = sunRadVar->alb * gh * (1 - cosslope) / 2.;
+ }
+ else { /* plane */
+ dr = dh;
+ *rr = 0.;
+ }
+
+ c1 = 4./(3.*M_PI);
+ diff_coeff_angleloss = sinslope
+ + (M_PI-sunSlopeGeom->slope-sinslope)/(1+cosslope);
+ refl_coeff_angleloss = sinslope
+ + (sunSlopeGeom->slope-sinslope)/(1-cosslope);
+
+ diff_loss_factor
+ = 1. - exp(-(c1*diff_coeff_angleloss
+ +c2*diff_coeff_angleloss*diff_coeff_angleloss)
+ /a_r);
+ refl_loss_factor
+ = 1. - exp(-(c1*refl_coeff_angleloss
+ +c2*refl_coeff_angleloss*refl_coeff_angleloss)
+ /a_r);
+
+ dr *= diff_loss_factor;
+ *rr *= refl_loss_factor;
+
+
+
+ return (dr);
+}
+
+
Added: trunk/grassaddons/r.sun_horizon/r.sun2/sunradstruct.h
===================================================================
--- trunk/grassaddons/r.sun_horizon/r.sun2/sunradstruct.h (rev 0)
+++ trunk/grassaddons/r.sun_horizon/r.sun2/sunradstruct.h 2007-10-09 10:33:54 UTC (rev 1129)
@@ -0,0 +1,109 @@
+/*******************************************************************************
+r.sun: sunradstruct.h. This program was writen by Jaro Hofierka in Summer 1993 and re-engineered
+in 1996-1999. In cooperation with Marcel Suri and Thomas Huld from JRC in Ispra
+a new version of r.sun was prepared using ESRA solar radiation formulas.
+See manual pages for details.
+(C) 2002 Copyright Jaro Hofierka, Gresaka 22, 085 01 Bardejov, Slovakia,
+ and GeoModel, s.r.o., Bratislava, Slovakia
+email: hofierka@geomodel.sk,marcel.suri@jrc.it,suri@geomodel.sk
+*******************************************************************************/
+/*
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*v. 2.0 July 2002, NULL data handling, JH */
+/*v. 2.1 January 2003, code optimization by Thomas Huld, JH */
+
+#define EPS 1.e-4
+#define HOURANGLE M_PI/12.
+
+
+struct SunGeometryConstDay
+ {
+ double lum_C11;
+ double lum_C13;
+ double lum_C22;
+ double lum_C31;
+ double lum_C33;
+ double sunrise_time;
+ double sunset_time;
+ double timeAngle;
+ double sindecl;
+ double cosdecl;
+
+ };
+
+
+struct SunGeometryVarDay
+ {
+ int isShadow;
+ double z_orig;
+ double zmax;
+ double zp;
+ double solarAltitude;
+ double sinSolarAltitude;
+ double tanSolarAltitude;
+ double solarAzimuth;
+ double sunAzimuthAngle;
+ double stepsinangle;
+ double stepcosangle;
+
+ };
+
+
+struct SunGeometryVarSlope
+ {
+ double longit_l; /* The "longitude" difference between the inclined */
+ /* and orientated plane and the instantaneous solar position */
+ double lum_C31_l;
+ double lum_C33_l;
+ double slope;
+ double aspect;
+
+ };
+
+
+
+struct SolarRadVar
+ {
+ double cbh;
+ double cdh;
+ double linke;
+ double G_norm_extra;
+ double alb;
+
+ };
+
+
+
+struct GridGeometry
+ {
+ double xp;
+ double yp;
+ double xx0;
+ double yy0;
+ double xg0;
+ double yg0;
+ double stepx;
+ double stepy;
+ double deltx;
+ double delty;
+ double stepxy;
+ double sinlat;
+ double coslat;
+
+ };
From landa at grass.itc.it Tue Oct 9 20:37:40 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Tue Oct 9 20:37:42 2007
Subject: [grass-addons] r1130 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710091837.l99Ibeci023637@grass.itc.it>
Author: landa
Date: 2007-10-09 20:37:36 +0200 (Tue, 09 Oct 2007)
New Revision: 1130
Modified:
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/render.py
trunk/grassaddons/gui/gui_modules/toolbars.py
Log:
Digitization tool: Fix copying features from background map.
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-09 10:33:54 UTC (rev 1129)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-09 18:37:36 UTC (rev 1130)
@@ -69,7 +69,7 @@
if not settings:
self.settings = {}
# symbology
-# self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white
+ # self.settings["symbolBackground"] = (None, (255,255,255, 255)) # white
self.settings["symbolHighlight"] = (None, (255, 255, 0, 255)) #yellow
self.settings["symbolPoint"] = (True, (0, 0, 0, 255)) # black
self.settings["symbolLine"] = (True, (0, 0, 0, 255)) # black
@@ -89,7 +89,7 @@
# snapping
self.settings["snapping"] = (10, "screen pixels") # value, unit
self.settings["snapToVertex"] = False
- self.settings["backgroundMap"] = 'a1@martin'
+ self.settings["backgroundMap"] = ''
# digitize new record
self.settings["addRecord"] = True
@@ -181,7 +181,7 @@
Debug.msg (4, "Vline.AddPoint(): input=%s" % addstring)
- self._AddFeature (map=map, input=addstring)
+ self.__AddFeature (map=map, input=addstring)
def AddLine (self, map, type, coords):
"""
@@ -215,9 +215,9 @@
Debug.msg (4, "VEdit.AddLine(): input=%s" % addstring)
- self._AddFeature (map=map, input=addstring, flags=flags)
+ self.__AddFeature (map=map, input=addstring, flags=flags)
- def _AddFeature (self, map, input, flags=[]):
+ def __AddFeature (self, map, input, flags=[]):
"""
General method which adds feature to the vector map
"""
@@ -244,7 +244,7 @@
command.append(flag)
# run the command
- Debug.msg(4, "VEdit._AddFeature(): input=%s" % input)
+ Debug.msg(4, "VEdit.AddFeature(): input=%s" % input)
vedit = gcmd.Command(cmd=command, stdin=input)
# reload map (needed for v.edit)
@@ -489,22 +489,20 @@
Debug.msg(4, "VEdit.SelectLinesFromBackgroundMap(): []")
return []
- print "#", pos1, pos2
x1, y1 = pos1
x2, y2 = pos2
vEditCmd = gcmd.Command(['v.edit',
'--q',
- 'map=%s' % self.map,
+ 'map=%s' % self.settings['backgroundMap'],
'tool=select',
# 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
(x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
-
+
try:
- output = vEditCmd.ReadStdOutput()[0][0]
- print "#", output
- ids = output.split(',') #first line & item in list
+ output = vEditCmd.ReadStdOutput()[0] # first line
+ ids = output.split(',')
ids = map(int, ids) # str -> int
except:
return []
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-09 10:33:54 UTC (rev 1129)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-09 18:37:36 UTC (rev 1130)
@@ -46,10 +46,9 @@
sys.path.append(CompatPath)
from compat import subprocess
-gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" )
-sys.path.append(gmpath)
-gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","icons" )
-sys.path.append(gmpath)
+for gmpath in [os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" ),
+ os.path.join( os.getenv("GISBASE"),"etc","wx","icons" )]:
+ sys.path.append(gmpath)
import render
import toolbars
@@ -60,9 +59,9 @@
import disp_print
import gcmd
import dbm
-import defaultfont as defaultfont
-import histogram as histogram
-import profile as profile
+import defaultfont
+import histogram
+import profile
from digit import Digit as Digit
from digit import DigitCategoryDialog as DigitCategoryDialog
from debug import Debug as Debug
@@ -953,6 +952,7 @@
self.mouse['box'] = 'box'
elif digitToolbar.action == "copyLine":
self.copyIds = None
+ self.layerTmp = None
else:
# get decoration id
self.lastpos = self.mouse['begin']
@@ -1099,10 +1099,22 @@
if nselected > 0:
# highlight selected features
self.UpdateMap(render=False)
+ else:
+ self.UpdateMap(render=False, renderVector=False)
else:
# copy features from background map
self.copyIds = self.parent.digit.SelectLinesFromBackgroundMap(pos1, pos2)
- self.UpdateMap(render=False, renderVector=False)
+ if len(self.copyIds) > 0:
+ dVectTmp = ['d.vect',
+ 'map=%s' % self.parent.digit.settings['backgroundMap'],
+ 'cats=%s' % ",".join(["%d" % v for v in self.copyIds]),
+ '-i',
+ 'color=yellow']
+ self.layerTmp = self.Map.AddLayer(type='vector',
+ command=dVectTmp)
+ self.UpdateMap(render=True, renderVector=False)
+ else:
+ self.UpdateMap(render=False, renderVector=False)
elif self.dragid != None:
# end drag of overlay decoration
@@ -1313,6 +1325,10 @@
elif digit.action == "copyLine":
self.parent.digit.CopyLine(self.copyIds)
del self.copyIds
+ if self.layerTmp:
+ self.Map.DeleteLayer(self.layerTmp)
+ self.UpdateMap(render=True, renderVector=False)
+ del self.layerTmp
if digit.action != "addLine":
self.parent.digit.driver.Unselect()
@@ -1369,6 +1385,10 @@
pass
elif digit.action == "copyLine":
del self.copyIds
+ if self.layerTmp:
+ self.Map.DeleteLayer(self.layerTmp)
+ self.UpdateMap(render=True, renderVector=False)
+ del self.layerTmp
self.UpdateMap(render=False) # render map
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-09 10:33:54 UTC (rev 1129)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-09 18:37:36 UTC (rev 1130)
@@ -29,7 +29,7 @@
Common layer attributes:
type - layer type (raster, vector, overlay, command, etc.)
name - layer name, e.g. map name ('elevation@PERMANENT')
- cmdlist - GRASS command (e.g. 'd.rast map=elevation@PERMANENT')
+ cmdlist - GRASS command (e.g. ['d.rast', 'map=elevation@PERMANENT'])
active - layer is active, will be rendered only if True
hidden - layer is hidden, won't be listed in GIS Manager if True
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-09 10:33:54 UTC (rev 1129)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-09 18:37:36 UTC (rev 1130)
@@ -325,7 +325,7 @@
wx.ITEM_RADIO, Icons["digDispAttr"].GetLabel(), Icons["digDispAttr"].GetDesc(),
self.OnDisplayAttr),
(self.additioanlTools, "digAdditionalTools", Icons["digAdditionalTools"].GetBitmap(),
- wx.ITEM_NORMAL, Icons["digAdditionalTools"].GetLabel(),
+ wx.ITEM_RADIO, Icons["digAdditionalTools"].GetLabel(),
Icons["digAdditionalTools"].GetDesc(),
self.OnAdditionalToolMenu))
From landa at grass.itc.it Fri Oct 12 17:05:19 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 12 17:05:21 2007
Subject: [grass-addons] r1131 - trunk/grassaddons/gui/display_driver
Message-ID: <200710121505.l9CF5JaW015648@grass.itc.it>
Author: landa
Date: 2007-10-12 17:05:12 +0200 (Fri, 12 Oct 2007)
New Revision: 1131
Added:
trunk/grassaddons/gui/display_driver/pseudodc.h
Log:
Added header for pseudodc.h (should be removed in the future).
Added: trunk/grassaddons/gui/display_driver/pseudodc.h
===================================================================
--- trunk/grassaddons/gui/display_driver/pseudodc.h (rev 0)
+++ trunk/grassaddons/gui/display_driver/pseudodc.h 2007-10-12 15:05:12 UTC (rev 1131)
@@ -0,0 +1,814 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name: pseudodc.h
+// Purpose: wxPseudoDC class
+// Author: Paul Lanier
+// Modified by:
+// Created: 05/25/06
+// RCS-ID: $Id: pseudodc.h,v 1.5 2006/10/11 04:01:29 RD Exp $
+// Copyright: (c) wxWidgets team
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_PSUEDO_DC_H_BASE_
+#define _WX_PSUEDO_DC_H_BASE_
+
+//----------------------------------------------------------------------------
+// Base class for all pdcOp classes
+//----------------------------------------------------------------------------
+class pdcOp
+{
+ public:
+ // Constructor and Destructor
+ pdcOp() {}
+ virtual ~pdcOp() {}
+
+ // Virtual Drawing Methods
+ virtual void DrawToDC(wxDC *dc, bool grey=false)=0;
+ virtual void Translate(wxCoord WXUNUSED(dx), wxCoord WXUNUSED(dy)) {}
+ virtual void CacheGrey() {}
+};
+
+//----------------------------------------------------------------------------
+// declare a list class for list of pdcOps
+//----------------------------------------------------------------------------
+WX_DECLARE_LIST(pdcOp, pdcOpList);
+
+
+//----------------------------------------------------------------------------
+// Helper functions used for drawing greyed out versions of objects
+//----------------------------------------------------------------------------
+wxColour &MakeColourGrey(const wxColour &c);
+wxBrush &GetGreyBrush(wxBrush &brush);
+wxPen &GetGreyPen(wxPen &pen);
+wxIcon &GetGreyIcon(wxIcon &icon);
+wxBitmap &GetGreyBitmap(wxBitmap &bmp);
+
+//----------------------------------------------------------------------------
+// Classes derived from pdcOp
+// There is one class for each method mirrored from wxDC to wxPseudoDC
+//----------------------------------------------------------------------------
+class pdcSetFontOp : public pdcOp
+{
+ public:
+ pdcSetFontOp(const wxFont& font)
+ {m_font=font;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetFont(m_font);}
+ protected:
+ wxFont m_font;
+};
+
+class pdcSetBrushOp : public pdcOp
+{
+ public:
+ pdcSetBrushOp(const wxBrush& brush)
+ {m_greybrush=m_brush=brush;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->SetBrush(m_brush);
+ else dc->SetBrush(m_greybrush);
+ }
+ virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
+ protected:
+ wxBrush m_brush;
+ wxBrush m_greybrush;
+};
+
+class pdcSetBackgroundOp : public pdcOp
+{
+ public:
+ pdcSetBackgroundOp(const wxBrush& brush)
+ {m_greybrush=m_brush=brush;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->SetBackground(m_brush);
+ else dc->SetBackground(m_greybrush);
+ }
+ virtual void CacheGrey() {m_greybrush=GetGreyBrush(m_brush);}
+ protected:
+ wxBrush m_brush;
+ wxBrush m_greybrush;
+};
+
+class pdcSetPenOp : public pdcOp
+{
+ public:
+ pdcSetPenOp(const wxPen& pen)
+ {m_greypen=m_pen=pen;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->SetPen(m_pen);
+ else dc->SetPen(m_greypen);
+ }
+ virtual void CacheGrey() {m_greypen=GetGreyPen(m_pen);}
+ protected:
+ wxPen m_pen;
+ wxPen m_greypen;
+};
+
+class pdcSetTextBackgroundOp : public pdcOp
+{
+ public:
+ pdcSetTextBackgroundOp(const wxColour& colour)
+ {m_colour=colour;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->SetTextBackground(m_colour);
+ else dc->SetTextBackground(MakeColourGrey(m_colour));
+ }
+ protected:
+ wxColour m_colour;
+};
+
+class pdcSetTextForegroundOp : public pdcOp
+{
+ public:
+ pdcSetTextForegroundOp(const wxColour& colour)
+ {m_colour=colour;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->SetTextForeground(m_colour);
+ else dc->SetTextForeground(MakeColourGrey(m_colour));
+ }
+ protected:
+ wxColour m_colour;
+};
+
+class pdcDrawRectangleOp : public pdcOp
+{
+ public:
+ pdcDrawRectangleOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h)
+ {m_x=x; m_y=y; m_w=w; m_h=h;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawRectangle(m_x,m_y,m_w,m_h);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx;m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y,m_w,m_h;
+};
+
+class pdcDrawLineOp : public pdcOp
+{
+ public:
+ pdcDrawLineOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
+ {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawLine(m_x1,m_y1,m_x2,m_y2);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x1+=dx; m_y1+=dy; m_x2+=dx; m_y2+=dy;}
+ protected:
+ wxCoord m_x1,m_y1,m_x2,m_y2;
+};
+
+class pdcSetBackgroundModeOp : public pdcOp
+{
+ public:
+ pdcSetBackgroundModeOp(int mode) {m_mode=mode;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetBackgroundMode(m_mode);}
+ protected:
+ int m_mode;
+};
+
+class pdcDrawTextOp : public pdcOp
+{
+ public:
+ pdcDrawTextOp(const wxString& text, wxCoord x, wxCoord y)
+ {m_text=text; m_x=x; m_y=y;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawText(m_text, m_x, m_y);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxString m_text;
+ wxCoord m_x, m_y;
+};
+
+class pdcClearOp : public pdcOp
+{
+ public:
+ pdcClearOp() {}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->Clear();}
+};
+
+class pdcBeginDrawingOp : public pdcOp
+{
+ public:
+ pdcBeginDrawingOp() {}
+ virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
+};
+
+class pdcEndDrawingOp : public pdcOp
+{
+ public:
+ pdcEndDrawingOp() {}
+ virtual void DrawToDC(wxDC *WXUNUSED(dc), bool WXUNUSED(grey)=false) {}
+};
+
+class pdcFloodFillOp : public pdcOp
+{
+ public:
+ pdcFloodFillOp(wxCoord x, wxCoord y, const wxColour& col,
+ int style) {m_x=x; m_y=y; m_col=col; m_style=style;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (!grey) dc->FloodFill(m_x,m_y,m_col,m_style);
+ else dc->FloodFill(m_x,m_y,MakeColourGrey(m_col),m_style);
+ }
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y;
+ wxColour m_col;
+ int m_style;
+};
+
+class pdcCrossHairOp : public pdcOp
+{
+ public:
+ pdcCrossHairOp(wxCoord x, wxCoord y) {m_x=x; m_y=y;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->CrossHair(m_x,m_y);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y;
+};
+
+class pdcDrawArcOp : public pdcOp
+{
+ public:
+ pdcDrawArcOp(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
+ wxCoord xc, wxCoord yc)
+ {m_x1=x1; m_y1=y1; m_x2=x2; m_y2=y2; m_xc=xc; m_yc=yc;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawArc(m_x1,m_y1,m_x2,m_y2,m_xc,m_yc);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x1+=dx; m_x2+=dx; m_y1+=dy; m_y2+=dy;}
+ protected:
+ wxCoord m_x1,m_x2,m_xc;
+ wxCoord m_y1,m_y2,m_yc;
+};
+
+class pdcDrawCheckMarkOp : public pdcOp
+{
+ public:
+ pdcDrawCheckMarkOp(wxCoord x, wxCoord y,
+ wxCoord width, wxCoord height)
+ {m_x=x; m_y=y; m_w=width; m_h=height;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawCheckMark(m_x,m_y,m_w,m_h);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y,m_w,m_h;
+};
+
+class pdcDrawEllipticArcOp : public pdcOp
+{
+ public:
+ pdcDrawEllipticArcOp(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
+ double sa, double ea)
+ {m_x=x; m_y=y; m_w=w; m_h=h; m_sa=sa; m_ea=ea;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawEllipticArc(m_x,m_y,m_w,m_h,m_sa,m_ea);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y,m_w,m_h;
+ double m_sa,m_ea;
+};
+
+class pdcDrawPointOp : public pdcOp
+{
+ public:
+ pdcDrawPointOp(wxCoord x, wxCoord y)
+ {m_x=x; m_y=y;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawPoint(m_x,m_y);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y;
+};
+
+class pdcDrawRoundedRectangleOp : public pdcOp
+{
+ public:
+ pdcDrawRoundedRectangleOp(wxCoord x, wxCoord y, wxCoord width,
+ wxCoord height, double radius)
+ {m_x=x; m_y=y; m_w=width; m_h=height; m_r=radius;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawRoundedRectangle(m_x,m_y,m_w,m_h,m_r);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y,m_w,m_h;
+ double m_r;
+};
+
+class pdcDrawEllipseOp : public pdcOp
+{
+ public:
+ pdcDrawEllipseOp(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+ {m_x=x; m_y=y; m_w=width; m_h=height;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawEllipse(m_x,m_y,m_w,m_h);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxCoord m_x,m_y,m_w,m_h;
+};
+
+class pdcDrawIconOp : public pdcOp
+{
+ public:
+ pdcDrawIconOp(const wxIcon& icon, wxCoord x, wxCoord y)
+ {m_icon=icon; m_x=x; m_y=y;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (grey) dc->DrawIcon(m_greyicon,m_x,m_y);
+ else dc->DrawIcon(m_icon,m_x,m_y);
+ }
+ virtual void CacheGrey() {m_greyicon=GetGreyIcon(m_icon);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxIcon m_icon;
+ wxIcon m_greyicon;
+ wxCoord m_x,m_y;
+};
+
+class pdcDrawLinesOp : public pdcOp
+{
+ public:
+ pdcDrawLinesOp(int n, wxPoint points[],
+ wxCoord xoffset = 0, wxCoord yoffset = 0);
+ virtual ~pdcDrawLinesOp();
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawLines(m_n,m_points,m_xoffset,m_yoffset);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {
+ for(int i=0; iDrawPolygon(m_n,m_points,m_xoffset,m_yoffset,m_fillStyle);}
+
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {
+ for(int i=0; iDrawPolyPolygon(m_n,m_count,m_points,
+ m_xoffset,m_yoffset,m_fillStyle);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {
+ for(int i=0; iDrawRotatedText(m_text,m_x,m_y,m_angle);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxString m_text;
+ wxCoord m_x,m_y;
+ double m_angle;
+};
+
+class pdcDrawBitmapOp : public pdcOp
+{
+ public:
+ pdcDrawBitmapOp(const wxBitmap &bmp, wxCoord x, wxCoord y,
+ bool useMask = false)
+ {m_bmp=bmp; m_x=x; m_y=y; m_useMask=useMask;}
+ virtual void DrawToDC(wxDC *dc, bool grey=false)
+ {
+ if (grey) dc->DrawBitmap(m_greybmp,m_x,m_y,m_useMask);
+ else dc->DrawBitmap(m_bmp,m_x,m_y,m_useMask);
+ }
+ virtual void CacheGrey() {m_greybmp=GetGreyBitmap(m_bmp);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_x+=dx; m_y+=dy;}
+ protected:
+ wxBitmap m_bmp;
+ wxBitmap m_greybmp;
+ wxCoord m_x,m_y;
+ bool m_useMask;
+};
+
+class pdcDrawLabelOp : public pdcOp
+{
+ public:
+ pdcDrawLabelOp(const wxString& text,
+ const wxBitmap& image,
+ const wxRect& rect,
+ int alignment = wxALIGN_LEFT | wxALIGN_TOP,
+ int indexAccel = -1)
+ {m_text=text; m_image=image; m_rect=rect;
+ m_align=alignment; m_iAccel=indexAccel;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false)
+ {dc->DrawLabel(m_text,m_image,m_rect,m_align,m_iAccel);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {m_rect.x+=dx; m_rect.y+=dy;}
+ protected:
+ wxString m_text;
+ wxBitmap m_image;
+ wxRect m_rect;
+ int m_align;
+ int m_iAccel;
+};
+
+#if wxUSE_SPLINES
+class pdcDrawSplineOp : public pdcOp
+{
+ public:
+ pdcDrawSplineOp(int n, wxPoint points[]);
+ virtual ~pdcDrawSplineOp();
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->DrawSpline(m_n,m_points);}
+ virtual void Translate(wxCoord dx, wxCoord dy)
+ {
+ int i;
+ for(i=0; iSetPalette(m_palette);}
+ protected:
+ wxPalette m_palette;
+};
+#endif // wxUSE_PALETTE
+
+class pdcSetLogicalFunctionOp : public pdcOp
+{
+ public:
+ pdcSetLogicalFunctionOp(int function) {m_function=function;}
+ virtual void DrawToDC(wxDC *dc, bool WXUNUSED(grey)=false) {dc->SetLogicalFunction(m_function);}
+ protected:
+ int m_function;
+};
+
+//----------------------------------------------------------------------------
+// pdcObject type to contain list of operations for each real (Python) object
+//----------------------------------------------------------------------------
+class pdcObject
+{
+ public:
+ pdcObject(int id)
+ {m_id=id; m_bounded=false; m_oplist.DeleteContents(true);
+ m_greyedout=false;}
+
+ virtual ~pdcObject() {m_oplist.Clear();}
+
+ // Protected Member Access
+ void SetId(int id) {m_id=id;}
+ int GetId() {return m_id;}
+ void SetBounds(wxRect& rect) {m_bounds=rect; m_bounded=true;}
+ wxRect GetBounds() {return m_bounds;}
+ void SetBounded(bool bounded) {m_bounded=bounded;}
+ bool IsBounded() {return m_bounded;}
+ void SetGreyedOut(bool greyout=true);
+ bool GetGreyedOut() {return m_greyedout;}
+
+ // Op List Management Methods
+ void Clear() {m_oplist.Clear();}
+ void AddOp(pdcOp *op)
+ {
+ m_oplist.Append(op);
+ if (m_greyedout) op->CacheGrey();
+ }
+ int GetLen() {return m_oplist.GetCount();}
+ virtual void Translate(wxCoord dx, wxCoord dy);
+
+ // Drawing Method
+ virtual void DrawToDC(wxDC *dc);
+ protected:
+ int m_id; // id of object (associates this pdcObject
+ // with a Python object with same id)
+ wxRect m_bounds; // bounding rect of this object
+ bool m_bounded; // true if bounds is valid, false by default
+ pdcOpList m_oplist; // list of operations for this object
+ bool m_greyedout; // if true then draw this object in greys only
+};
+
+
+//----------------------------------------------------------------------------
+// Declare a wxList to hold all the objects. List order reflects drawing
+// order (Z order) and is the same order as objects are added to the list
+//----------------------------------------------------------------------------
+class pdcObjectList;
+WX_DECLARE_LIST(pdcObject, pdcObjectList);
+
+
+// ----------------------------------------------------------------------------
+// wxPseudoDC class
+// ----------------------------------------------------------------------------
+// This is the actual PseudoDC class
+// This class stores a list of recorded dc operations in m_list
+// and plays them back to a real dc using DrawToDC or DrawToDCClipped.
+// Drawing methods are mirrored from wxDC but add nodes to m_list
+// instead of doing any real drawing.
+// ----------------------------------------------------------------------------
+class wxPseudoDC : public wxObject
+{
+public:
+ wxPseudoDC()
+ {m_currId=-1; m_lastObjNode=NULL; m_objectlist.DeleteContents(true);}
+ ~wxPseudoDC();
+ // ------------------------------------------------------------------------
+ // List managment methods
+ //
+ void RemoveAll();
+ int GetLen();
+
+ // ------------------------------------------------------------------------
+ // methods for managing operations by ID
+ //
+ // Set the Id for all subsequent operations (until SetId is called again)
+ void SetId(int id) {m_currId = id;}
+ // Remove all the operations associated with an id so it can be redrawn
+ void ClearId(int id);
+ // Remove the object node (and all operations) associated with an id
+ void RemoveId(int id);
+ // Set the bounding rect of a given object
+ // This will create an object node if one doesn't exist
+ void SetIdBounds(int id, wxRect& rect);
+ void GetIdBounds(int id, wxRect& rect);
+ // Translate all the operations for this id
+ void TranslateId(int id, wxCoord dx, wxCoord dy);
+ // Grey-out an object
+ void SetIdGreyedOut(int id, bool greyout=true);
+ bool GetIdGreyedOut(int id);
+ // Find Objects at a point. Returns Python list of id's
+ // sorted in reverse drawing order (result[0] is top object)
+ // This version looks at drawn pixels
+ PyObject *FindObjects(wxCoord x, wxCoord y,
+ wxCoord radius=1, const wxColor& bg=*wxWHITE);
+ // This version only looks at bounding boxes
+ PyObject *FindObjectsByBBox(wxCoord x, wxCoord y);
+
+ // ------------------------------------------------------------------------
+ // Playback Methods
+ //
+ // draw to dc but skip objects known to be outside of rect
+ // This is a coarse level of clipping to speed things up
+ // when lots of objects are off screen and doesn't affect the dc level
+ // clipping
+ void DrawToDCClipped(wxDC *dc, const wxRect& rect);
+ void DrawToDCClippedRgn(wxDC *dc, const wxRegion& region);
+ // draw to dc with no clipping (well the dc will still clip)
+ void DrawToDC(wxDC *dc);
+ // draw a single object to the dc
+ void DrawIdToDC(int id, wxDC *dc);
+
+ // ------------------------------------------------------------------------
+ // Hit Detection Methods
+ //
+ // returns list of object with a drawn pixel within radius pixels of (x,y)
+ // the list is in reverse draw order so last drawn is first in list
+ // PyObject *HitTest(wxCoord x, wxCoord y, double radius)
+ // returns list of objects whose bounding boxes include (x,y)
+ // PyObject *HitTestBB(wxCoord x, wxCoord y)
+
+
+ // ------------------------------------------------------------------------
+ // Methods mirrored from wxDC
+ //
+ void FloodFill(wxCoord x, wxCoord y, const wxColour& col,
+ int style = wxFLOOD_SURFACE)
+ {AddToList(new pdcFloodFillOp(x,y,col,style));}
+ void FloodFill(const wxPoint& pt, const wxColour& col,
+ int style = wxFLOOD_SURFACE)
+ { FloodFill(pt.x, pt.y, col, style); }
+
+ void DrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
+ {AddToList(new pdcDrawLineOp(x1, y1, x2, y2));}
+ void DrawLine(const wxPoint& pt1, const wxPoint& pt2)
+ { DrawLine(pt1.x, pt1.y, pt2.x, pt2.y); }
+
+ void CrossHair(wxCoord x, wxCoord y)
+ {AddToList(new pdcCrossHairOp(x,y));}
+ void CrossHair(const wxPoint& pt)
+ { CrossHair(pt.x, pt.y); }
+
+ void DrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2,
+ wxCoord xc, wxCoord yc)
+ {AddToList(new pdcDrawArcOp(x1,y1,x2,y2,xc,yc));}
+ void DrawArc(const wxPoint& pt1, const wxPoint& pt2, const wxPoint& centre)
+ { DrawArc(pt1.x, pt1.y, pt2.x, pt2.y, centre.x, centre.y); }
+
+ void DrawCheckMark(wxCoord x, wxCoord y,
+ wxCoord width, wxCoord height)
+ {AddToList(new pdcDrawCheckMarkOp(x,y,width,height));}
+ void DrawCheckMark(const wxRect& rect)
+ { DrawCheckMark(rect.x, rect.y, rect.width, rect.height); }
+
+ void DrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h,
+ double sa, double ea)
+ {AddToList(new pdcDrawEllipticArcOp(x,y,w,h,sa,ea));}
+ void DrawEllipticArc(const wxPoint& pt, const wxSize& sz,
+ double sa, double ea)
+ { DrawEllipticArc(pt.x, pt.y, sz.x, sz.y, sa, ea); }
+
+ void DrawPoint(wxCoord x, wxCoord y)
+ {AddToList(new pdcDrawPointOp(x,y));}
+ void DrawPoint(const wxPoint& pt)
+ { DrawPoint(pt.x, pt.y); }
+
+ void DrawPolygon(int n, wxPoint points[],
+ wxCoord xoffset = 0, wxCoord yoffset = 0,
+ int fillStyle = wxODDEVEN_RULE)
+ {AddToList(new pdcDrawPolygonOp(n,points,xoffset,yoffset,fillStyle));}
+
+ void DrawPolyPolygon(int n, int count[], wxPoint points[],
+ wxCoord xoffset = 0, wxCoord yoffset = 0,
+ int fillStyle = wxODDEVEN_RULE)
+ {AddToList(new pdcDrawPolyPolygonOp(n,count,points,xoffset,yoffset,fillStyle));}
+
+ void DrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+ {AddToList(new pdcDrawRectangleOp(x, y, width, height));}
+ void DrawRectangle(const wxPoint& pt, const wxSize& sz)
+ { DrawRectangle(pt.x, pt.y, sz.x, sz.y); }
+ void DrawRectangle(const wxRect& rect)
+ { DrawRectangle(rect.x, rect.y, rect.width, rect.height); }
+
+ void DrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height,
+ double radius)
+ {AddToList(new pdcDrawRoundedRectangleOp(x,y,width,height,radius));}
+ void DrawRoundedRectangle(const wxPoint& pt, const wxSize& sz,
+ double radius)
+ { DrawRoundedRectangle(pt.x, pt.y, sz.x, sz.y, radius); }
+ void DrawRoundedRectangle(const wxRect& r, double radius)
+ { DrawRoundedRectangle(r.x, r.y, r.width, r.height, radius); }
+
+ void DrawCircle(wxCoord x, wxCoord y, wxCoord radius)
+ { DrawEllipse(x - radius, y - radius, 2*radius, 2*radius); }
+ void DrawCircle(const wxPoint& pt, wxCoord radius)
+ { DrawCircle(pt.x, pt.y, radius); }
+
+ void DrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+ {AddToList(new pdcDrawEllipseOp(x,y,width,height));}
+ void DrawEllipse(const wxPoint& pt, const wxSize& sz)
+ { DrawEllipse(pt.x, pt.y, sz.x, sz.y); }
+ void DrawEllipse(const wxRect& rect)
+ { DrawEllipse(rect.x, rect.y, rect.width, rect.height); }
+
+ void DrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
+ {AddToList(new pdcDrawIconOp(icon,x,y));}
+ void DrawIcon(const wxIcon& icon, const wxPoint& pt)
+ { DrawIcon(icon, pt.x, pt.y); }
+
+ void DrawLines(int n, wxPoint points[],
+ wxCoord xoffset = 0, wxCoord yoffset = 0)
+ {AddToList(new pdcDrawLinesOp(n,points,xoffset,yoffset));}
+
+ void DrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y,
+ bool useMask = false)
+ {AddToList(new pdcDrawBitmapOp(bmp,x,y,useMask));}
+ void DrawBitmap(const wxBitmap &bmp, const wxPoint& pt,
+ bool useMask = false)
+ { DrawBitmap(bmp, pt.x, pt.y, useMask); }
+
+ void DrawText(const wxString& text, wxCoord x, wxCoord y)
+ {AddToList(new pdcDrawTextOp(text, x, y));}
+ void DrawText(const wxString& text, const wxPoint& pt)
+ { DrawText(text, pt.x, pt.y); }
+
+ void DrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
+ {AddToList(new pdcDrawRotatedTextOp(text,x,y,angle));}
+ void DrawRotatedText(const wxString& text, const wxPoint& pt, double angle)
+ { DrawRotatedText(text, pt.x, pt.y, angle); }
+
+ // this version puts both optional bitmap and the text into the given
+ // rectangle and aligns is as specified by alignment parameter; it also
+ // will emphasize the character with the given index if it is != -1
+ void DrawLabel(const wxString& text,
+ const wxBitmap& image,
+ const wxRect& rect,
+ int alignment = wxALIGN_LEFT | wxALIGN_TOP,
+ int indexAccel = -1)
+ {AddToList(new pdcDrawLabelOp(text,image,rect,alignment,indexAccel));}
+
+ void DrawLabel(const wxString& text, const wxRect& rect,
+ int alignment = wxALIGN_LEFT | wxALIGN_TOP,
+ int indexAccel = -1)
+ { DrawLabel(text, wxNullBitmap, rect, alignment, indexAccel); }
+
+/*?????? I don't think that the source dc would stick around
+ void Blit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+ wxDC *source, wxCoord xsrc, wxCoord ysrc,
+ int rop = wxCOPY, bool useMask = false, wxCoord xsrcMask = wxDefaultCoord, wxCoord ysrcMask = wxDefaultCoord)
+ {AddToList(new pdcBlitOp(xdest,ydest,width,height,source,xsrc,
+ ysrc,rop,useMask,xsrcMask,ysrcMask));}
+ void Blit(const wxPoint& destPt, const wxSize& sz,
+ wxDC *source, const wxPoint& srcPt,
+ int rop = wxCOPY, bool useMask = false, const wxPoint& srcPtMask = wxDefaultPosition)
+ {
+ Blit(destPt.x, destPt.y, sz.x, sz.y, source, srcPt.x, srcPt.y,
+ rop, useMask, srcPtMask.x, srcPtMask.y);
+ }
+??????*/
+
+#if wxUSE_SPLINES
+ void DrawSpline(int n, wxPoint points[])
+ {AddToList(new pdcDrawSplineOp(n,points));}
+#endif // wxUSE_SPLINES
+
+#if wxUSE_PALETTE
+ void SetPalette(const wxPalette& palette)
+ {AddToList(new pdcSetPaletteOp(palette));}
+#endif // wxUSE_PALETTE
+
+ void SetLogicalFunction(int function)
+ {AddToList(new pdcSetLogicalFunctionOp(function));}
+ void SetFont(const wxFont& font)
+ {AddToList(new pdcSetFontOp(font));}
+ void SetPen(const wxPen& pen)
+ {AddToList(new pdcSetPenOp(pen));}
+ void SetBrush(const wxBrush& brush)
+ {AddToList(new pdcSetBrushOp(brush));}
+ void SetBackground(const wxBrush& brush)
+ {AddToList(new pdcSetBackgroundOp(brush));}
+ void SetBackgroundMode(int mode)
+ {AddToList(new pdcSetBackgroundModeOp(mode));}
+ void SetTextBackground(const wxColour& colour)
+ {AddToList(new pdcSetTextBackgroundOp(colour));}
+ void SetTextForeground(const wxColour& colour)
+ {AddToList(new pdcSetTextForegroundOp(colour));}
+
+ void Clear()
+ {AddToList(new pdcClearOp());}
+ void BeginDrawing()
+ {AddToList(new pdcBeginDrawingOp());}
+ void EndDrawing()
+ {AddToList(new pdcEndDrawingOp());}
+
+protected:
+ // ------------------------------------------------------------------------
+ // protected helper methods
+ void AddToList(pdcOp *newOp);
+ pdcObjectList::Node *FindObjNode(int id, bool create=false);
+
+ // ------------------------------------------------------------------------
+ // Data members
+ //
+ int m_currId; // id to use for operations done on the PseudoDC
+ pdcObjectList::Node *m_lastObjNode; // used to find last used object quickly
+ pdcObjectList m_objectlist; // list of objects
+};
+
+#endif
+
From landa at grass.itc.it Fri Oct 12 21:05:42 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 12 21:05:44 2007
Subject: [grass-addons] r1132 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710121905.l9CJ5ga1018036@grass.itc.it>
Author: landa
Date: 2007-10-12 21:05:38 +0200 (Fri, 12 Oct 2007)
New Revision: 1132
Modified:
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/toolbars.py
Log:
Digitization tool: Basic query tool implemented.
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-12 15:05:12 UTC (rev 1131)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-12 19:05:38 UTC (rev 1132)
@@ -96,6 +96,11 @@
self.settings["layer"] = 1
self.settings["category"] = 1
self.settings["categoryMode"] = "Next to use"
+
+ # query tool
+ self.settings["query"] = "length"
+ self.settings["queryLength"] = ("shorter than", 0)
+ self.settings["queryDangle"] = (0,)
else:
self.settings = settings
@@ -496,9 +501,9 @@
'--q',
'map=%s' % self.settings['backgroundMap'],
'tool=select',
- # 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
- 'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
- (x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
+ 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1])])
+ #'polygon=%f,%f,%f,%f,%f,%f,%f,%f,%f,%f' % \
+ # (x1, y1, x2, y1, x2, y2, x1, y2, x1, y1)])
try:
output = vEditCmd.ReadStdOutput()[0] # first line
@@ -512,6 +517,34 @@
return ids
+ def SelectLinesByQuery(self, pos1, pos2, query="length"):
+ """Select features by query"""
+
+ vEdit = (['v.edit',
+ '--q',
+ 'map=%s' % self.map,
+ 'tool=select',
+ 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1]),
+ 'query=%s' % self.settings['query'],
+ 'thresh=%f' % self.settings['queryLength'][1]])
+
+ if self.settings['queryLength'][0] == "longer than":
+ vEdit.append('-r')
+
+ vEditCmd = gcmd.Command(vEdit)
+
+ try:
+ output = vEditCmd.ReadStdOutput()[0] # first line
+ ids = output.split(',')
+ ids = map(int, ids) # str -> int
+ except:
+ return []
+
+ Debug.msg(4, "VEdit.SelectLinesByQuery(): %s" % \
+ ",".join(["%d" % v for v in ids]))
+
+ return ids
+
class VDigit(AbstractDigit):
"""
Prototype of digitization class based on v.digit reimplementation
@@ -823,7 +856,8 @@
self.__CreateSymbologyPage(notebook)
parent.digit.SetCategory() # update category number (next to use)
self.__CreateSettingsPage(notebook)
-
+ self.__CreateQueryPage(notebook)
+
# buttons
btnApply = wx.Button(self, wx.ID_APPLY, _("Apply") )
btnCancel = wx.Button(self, wx.ID_CANCEL)
@@ -833,6 +867,7 @@
# bindigs
btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
+ btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
# sizers
btnSizer = wx.StdDialogButtonSizer()
@@ -1017,6 +1052,75 @@
return panel
+ def __CreateQueryPage(self, notebook):
+ """Create notebook page for query tool"""
+
+ settings = self.parent.digit.settings
+
+ panel = wx.Panel(parent=notebook, id=wx.ID_ANY)
+ notebook.AddPage(page=panel, text=_("Query tool"))
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Choose query tool"))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+
+ #
+ # length
+ #
+ self.queryLength = wx.RadioButton(parent=panel, id=wx.ID_ANY, label=_("length"))
+ self.queryLength.Bind(wx.EVT_RADIOBUTTON, self.OnChangeQuery)
+ sizer.Add(item=self.queryLength, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+ flexSizer = wx.FlexGridSizer (cols=4, hgap=5, vgap=5)
+ flexSizer.AddGrowableCol(0)
+ txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select lines"))
+ self.queryLengthSL = wx.Choice (parent=panel, id=wx.ID_ANY,
+ choices = [_("shorter than"), _("longer than")])
+ self.queryLengthSL.SetStringSelection(settings["queryLength"][0])
+ self.queryLengthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
+ initial=1,
+ min=0, max=1e6)
+ self.queryLengthValue.SetValue(settings["queryLength"][1])
+ units = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("map units"))
+ flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(self.queryLengthSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+ flexSizer.Add(self.queryLengthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+ flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+
+ #
+ # dangle
+ #
+ self.queryDangle = wx.RadioButton(parent=panel, id=wx.ID_ANY, label=_("dangle"))
+ self.queryDangle.Bind(wx.EVT_RADIOBUTTON, self.OnChangeQuery)
+ sizer.Add(item=self.queryDangle, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+ flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+ flexSizer.AddGrowableCol(0)
+ txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select dangles shorter than"))
+ self.queryDangleValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
+ initial=1,
+ min=0, max=1e6)
+ self.queryDangleValue.SetValue(settings["queryDangle"][0])
+ units = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("map units"))
+ flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(self.queryDangleValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+ flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+
+ if settings["query"] == "length":
+ self.queryLength.SetValue(True)
+ else:
+ self.queryDangle.SetValue(True)
+ # enable & disable items
+ self.OnChangeQuery(None)
+
+ border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+
+ panel.SetSizer(border)
+
+ return panel
+
+
def __SymbologyData(self):
"""
Data for __CreateSymbologyPage()
@@ -1093,17 +1197,37 @@
self.parent.digit.settings['backgroundMap'] = map
+ def OnChangeQuery(self, event):
+ """Change query"""
+ if self.queryLength.GetValue():
+ # length
+ self.queryLengthSL.Enable(True)
+ self.queryLengthValue.Enable(True)
+ self.queryDangleValue.Enable(False)
+ else:
+ # dangle
+ self.queryLengthSL.Enable(False)
+ self.queryLengthValue.Enable(False)
+ self.queryDangleValue.Enable(True)
+
def OnOK(self, event):
"""Button 'OK' clicked"""
self.UpdateSettings()
+ self.parent.digittoolbar.settingsDialog = None
self.Close()
def OnApply(self, event):
"""Button 'Apply' clicked"""
self.UpdateSettings()
+ def OnCancel(self, event):
+ """Button 'Cancel' clicked"""
+ self.parent.digittoolbar.settingsDialog = None
+ self.Close()
+
def UpdateSettings(self):
"""Update self.parent.digit.settings"""
+
# symbology
for key, (enabled, color) in self.symbology.iteritems():
if enabled:
@@ -1134,6 +1258,15 @@
except:
pass
+ # query tool
+ if self.queryLength.GetValue():
+ self.parent.digit.settings["query"] = "length"
+ else:
+ self.parent.digit.settings["query"] = "dangle"
+ self.parent.digit.settings["queryLength"] = (self.queryLengthSL.GetStringSelection(),
+ int(self.queryLengthValue.GetValue()))
+ self.parent.digit.settings["queryDangle"] = (int(self.queryDangleValue.GetValue()),)
+
# update driver settings
self.parent.digit.driver.UpdateSettings()
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-12 15:05:12 UTC (rev 1131)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-12 19:05:38 UTC (rev 1132)
@@ -1006,7 +1006,8 @@
if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex",
"copyCats", "editLine", "flipLine",
- "mergeLine", "snapLine", "connectLine"]:
+ "mergeLine", "snapLine", "connectLine",
+ "queryLine"]:
nselected = 0
# -> delete line || move line || move vertex
if digitToolbar.action in ["moveVertex", "editLine"]:
@@ -1041,6 +1042,12 @@
if nselected > 0:
self.copyCatsIds = driver.GetSelected()
+ elif digitToolbar.action == "queryLine":
+ selected = self.parent.digit.SelectLinesByQuery(pos1, pos2)
+ nselected = len(selected)
+ if nselected > 0:
+ driver.SetSelected(selected)
+
else:
# -> moveLine || deleteLine, etc. (select by box)
nselected = driver.SelectLinesByBox(pos1, pos2)
@@ -1368,7 +1375,8 @@
elif digit.action in ["deleteLine", "moveLine", "splitLine",
"addVertex", "removeVertex", "moveVertex",
"copyCats", "flipLine", "mergeLine",
- "snapLine", "connectLine", "copyLine"]:
+ "snapLine", "connectLine", "copyLine",
+ "queryLine"]:
# varios tools -> unselected selected features
self.parent.digit.driver.Unselect()
if digit.action in ["moveLine", "moveVertex", "editLine"] and \
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-12 15:05:12 UTC (rev 1131)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-12 19:05:38 UTC (rev 1132)
@@ -243,6 +243,9 @@
self.comboid = None
+ # only one dialog settings can be one
+ self.settingsDialog = None
+
# create toolbars (two rows)
self.toolbar = []
numOfRows = 2
@@ -434,9 +437,11 @@
def OnSettings(self, event):
"""Show settings dialog"""
- DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"),
- style=wx.DEFAULT_DIALOG_STYLE).Show()
+ if not self.settingsDialog:
+ self.settingsDialog = DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"),
+ style=wx.DEFAULT_DIALOG_STYLE).Show()
+
def OnAdditionalToolMenu(self, event):
"""Menu for additional tools"""
point = wx.GetMousePosition()
@@ -462,6 +467,14 @@
toolMenu.AppendItem(connect)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnConnect, connect)
+ query = wx.MenuItem(toolMenu, wx.ID_ANY, 'Query tool')
+ toolMenu.AppendItem(query)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnQuery, query)
+
+ zbulk = wx.MenuItem(toolMenu, wx.ID_ANY, 'Z bulk-labeling 3D lines')
+ toolMenu.AppendItem(zbulk)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnZBulk, zbulk)
+
# Popup the menu. If an item is selected then its handler
# will be called before PopupMenu returns.
self.parent.MapWindow.PopupMenu(toolMenu)
@@ -497,6 +510,18 @@
self.action="connectLine"
self.parent.MapWindow.mouse['box'] = 'box'
+ def OnQuery(self, event):
+ """Query selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnQuery(): %s" % self.parent.digit.settings["query"])
+ self.action="queryLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
+ def OnZBulk(self, event):
+ """Z bulk-labeling selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnZBulk():")
+ self.action="zbulkLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
def OnSelectMap (self, event):
"""
Select vector map layer for editing
From landa at grass.itc.it Sat Oct 13 21:55:53 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Sat Oct 13 21:55:56 2007
Subject: [grass-addons] r1133 - in trunk/grassaddons/gui: . display_driver
gui_modules icons/silk
Message-ID: <200710131955.l9DJtr6R020334@grass.itc.it>
Author: landa
Date: 2007-10-13 21:55:37 +0200 (Sat, 13 Oct 2007)
New Revision: 1133
Modified:
trunk/grassaddons/gui/display_driver/driver.cpp
trunk/grassaddons/gui/display_driver/driver.h
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/gui_modules/toolbars.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/icons/silk/
trunk/grassaddons/gui/wxgui.py
Log:
Digitization tool:
* z bulk-labeling tool implemented
* 'connect line' tool fixed
* various minor fixes
Modified: trunk/grassaddons/gui/display_driver/driver.cpp
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-13 19:55:37 UTC (rev 1133)
@@ -742,11 +742,11 @@
dx = std::fabs(x2 - x1);
dy = std::fabs(y2 - y1);
- Vect_append_point(bbox, x1, y1, 0.0);
- Vect_append_point(bbox, x2, y1, 0.0);
- Vect_append_point(bbox, x2, y2, 0.0);
- Vect_append_point(bbox, x1, y2, 0.0);
- Vect_append_point(bbox, x1, y1, 0.0);
+ Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x2, y1, PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x2, y2, -PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x1, y2, PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
Vect_select_lines_by_polygon(mapInfo, bbox,
0, NULL,
@@ -837,23 +837,6 @@
}
/**
- \brief Unselect selected features by user
-
- Clear list of ids of selected vector objects
-
- \param
-
- \return
-*/
-void DisplayDriver::Unselect()
-{
- selected.clear();
- drawSegments = false;
-
- return;
-}
-
-/**
\brief Get ids of selected objects
\param[in] grassId if true return GRASS line ids
@@ -923,6 +906,9 @@
{
selected = id;
+ if (selected.size() <= 0)
+ drawSegments = false;
+
return 1;
}
Modified: trunk/grassaddons/gui/display_driver/driver.h
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.h 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/display_driver/driver.h 2007-10-13 19:55:37 UTC (rev 1133)
@@ -157,7 +157,6 @@
std::vector SelectLineByPoint(double x, double y, double thresh,
int type);
- void Unselect();
std::vector GetSelected(bool grassId);
int SetSelected(std::vector id);
std::vector GetSelectedVertex(double x, double y);
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -9,6 +9,7 @@
* CDisplayDriver
* DigitSettingsDialog
* DigitCategoryDialog
+ * DigitZBulkDialog
PURPOSE: Digitization tool wxPython GUI prototype
@@ -517,7 +518,7 @@
return ids
- def SelectLinesByQuery(self, pos1, pos2, query="length"):
+ def SelectLinesByQuery(self, pos1, pos2):
"""Select features by query"""
vEdit = (['v.edit',
@@ -528,8 +529,9 @@
'query=%s' % self.settings['query'],
'thresh=%f' % self.settings['queryLength'][1]])
- if self.settings['queryLength'][0] == "longer than":
- vEdit.append('-r')
+ if self.settings['query'] == "length" and \
+ self.settings['queryLength'][0] == "longer than":
+ vEdit.append('-r') # FIXBUG: reverse selection regardless of bbox
vEditCmd = gcmd.Command(vEdit)
@@ -545,6 +547,17 @@
return ids
+ def ZBulkLine(self, pos1, pos2, value, step):
+ """Provide z bulk-labeling (automated assigment of z coordinate
+ to 3d lines"""
+
+ gcmd.Command(['v.edit',
+ '--q',
+ 'map=%s' % self.map,
+ 'tool=zbulk',
+ 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1]),
+ 'zbulk=%f,%f' % (value, step)])
+
class VDigit(AbstractDigit):
"""
Prototype of digitization class based on v.digit reimplementation
@@ -743,11 +756,6 @@
return id
- def Unselect(self):
- """Delesect selected vector features"""
-
- self.__display.Unselect()
-
def SetSelected(self, id):
"""Set selected vector features"""
@@ -1065,6 +1073,7 @@
box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Choose query tool"))
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ LocUnits = self.parent.MapWindow.Map.ProjInfo()['units']
#
# length
#
@@ -1081,7 +1090,7 @@
initial=1,
min=0, max=1e6)
self.queryLengthValue.SetValue(settings["queryLength"][1])
- units = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("map units"))
+ units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
flexSizer.Add(self.queryLengthSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
flexSizer.Add(self.queryLengthValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
@@ -1101,7 +1110,7 @@
initial=1,
min=0, max=1e6)
self.queryDangleValue.SetValue(settings["queryDangle"][0])
- units = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("map units"))
+ units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
flexSizer.Add(self.queryDangleValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
@@ -1305,7 +1314,7 @@
Debug.msg(3, "DigitCategoryDialog(): line=%d, cats=%s" % \
(self.line, self.cats))
- wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title, style=style)
+ wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title, style=style, pos=pos)
# list of categories
box = wx.StaticBox(parent=self, id=wx.ID_ANY,
@@ -1652,3 +1661,65 @@
self.currentItem = 0
return itemData
+
+class DigitZBulkDialog(wx.Dialog):
+ """
+ Dialog used for Z bulk-labeling tool
+ """
+ def __init__(self, parent, title, nselected, style=wx.DEFAULT_DIALOG_STYLE):
+ wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
+
+ self.parent = parent # mapdisplay.BufferedWindow class instance
+
+ # panel = wx.Panel(parent=self, id=wx.ID_ANY)
+
+ border = wx.BoxSizer(wx.VERTICAL)
+
+ txt = wx.StaticText(parent=self,
+ label=_("%d lines selected for z bulk-labeling") % nselected);
+ border.Add(item=txt, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)
+
+ box = wx.StaticBox (parent=self, id=wx.ID_ANY, label=" %s " % _("Set value"))
+ sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
+ flexSizer = wx.FlexGridSizer (cols=2, hgap=5, vgap=5)
+ flexSizer.AddGrowableCol(0)
+
+ # starting value
+ txt = wx.StaticText(parent=self,
+ label=_("Starting value"));
+ self.value = wx.SpinCtrl(parent=self, id=wx.ID_ANY, size=(150, -1),
+ initial=0,
+ min=-1e6, max=1e6)
+ flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(self.value, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+
+ # step
+ txt = wx.StaticText(parent=self,
+ label=_("Step"))
+ self.step = wx.SpinCtrl(parent=self, id=wx.ID_ANY, size=(150, -1),
+ initial=0,
+ min=0, max=1e6)
+ flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(self.step, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
+
+ sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
+ border.Add(item=sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)
+
+ # buttons
+ btnCancel = wx.Button(self, wx.ID_CANCEL)
+ btnOk = wx.Button(self, wx.ID_OK)
+ btnOk.SetDefault()
+
+ # sizers
+ btnSizer = wx.StdDialogButtonSizer()
+ btnSizer.AddButton(btnCancel)
+ btnSizer.AddButton(btnOk)
+ btnSizer.Realize()
+
+ mainSizer = wx.BoxSizer(wx.VERTICAL)
+ mainSizer.Add(item=border, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
+ mainSizer.Add(item=btnSizer, proportion=0,
+ flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
+
+ self.SetSizer(mainSizer)
+ mainSizer.Fit(self)
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -62,10 +62,11 @@
import defaultfont
import histogram
import profile
-from digit import Digit as Digit
+from digit import Digit as Digit
from digit import DigitCategoryDialog as DigitCategoryDialog
-from debug import Debug as Debug
-from icon import Icons as Icons
+from digit import DigitZBulkDialog as DigitZBulkDialog
+from debug import Debug as Debug
+from icon import Icons as Icons
import images
imagepath = images.__path__[0]
@@ -447,6 +448,8 @@
"""
dc = wx.BufferedPaintDC(self, self._Buffer)
self.pdc.DrawToDC(dc)
+ if self.pdcVector:
+ self.pdcVector.DrawToDC(dc)
self._Buffer.SaveFile(FileName, FileType)
def GetOverlay(self):
@@ -815,6 +818,7 @@
elif self.mouse["use"] == "pointer" and self.parent.digittoolbar:
# digitization
digitToolbar = self.parent.digittoolbar
+ digitClass = self.parent.digit
east, north = self.Pixel2Cell(self.mouse['begin'])
try:
@@ -842,18 +846,18 @@
if digitToolbar.action == "addLine":
if digitToolbar.type in ["point", "centroid"]:
# add new point
- self.parent.digit.AddPoint(map=map,
+ digitClass.AddPoint(map=map,
type=digitToolbar.type,
x=east, y=north)
self.UpdateMap(render=False) # redraw map
# add new record into atribute table
- if self.parent.digit.settings["addRecord"]:
+ if digitClass.settings["addRecord"]:
# select attributes based on layer and category
addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
- layer=self.parent.digit.settings["layer"],
- cat=self.parent.digit.settings["category"],
+ layer=digitClass.settings["layer"],
+ cat=digitClass.settings["category"],
pos=posWindow,
action="add")
if addRecordDlg.mapInfo and \
@@ -893,15 +897,17 @@
self.moveIds = []
if digitToolbar.action in ["moveVertex", "editLine"]:
# set pen
- self.polypen = wx.Pen(colour=self.parent.digit.settings["symbolHighlight"][1],
+ self.polypen = wx.Pen(colour=digitClass.settings["symbolHighlight"][1],
width=2, style=wx.SHORT_DASH)
self.pdcVector.SetPen(self.polypen)
+
elif digitToolbar.action == "splitLine":
pass
- elif digitToolbar.action in ["displayAttributes", "displayCategories"]:
+
+ elif digitToolbar.action in ["displayAttrs", "displayCats"]:
qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width)
redraw = False
- if digitToolbar.action == "displayAttributes":
+ if digitToolbar.action == "displayAttrs":
# select attributes based on coordinates (all layers)
updateRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
queryCoords=(east, north),
@@ -911,7 +917,7 @@
if updateRecordDlg.mapInfo and \
updateRecordDlg.GetLine():
# highlight feature & re-draw map
- self.parent.digit.driver.SetSelected([updateRecordDlg.GetLine()])
+ digitClass.driver.SetSelected([updateRecordDlg.GetLine()])
self.UpdateMap(render=False)
redraw = True
if updateRecordDlg.ShowModal() == wx.ID_OK:
@@ -924,7 +930,7 @@
executeCommand = gcmd.Command(cmd=["db.execute",
"--q",
"input=%s" % sqlfile.name])
- else: # displayCategories
+ else: # displayCats
categoryDlg = DigitCategoryDialog(parent=self,
map=map,
queryCoords=(east, north),
@@ -934,7 +940,7 @@
if categoryDlg.GetLine():
# highlight feature & re-draw map
- self.parent.digit.driver.SetSelected([categoryDlg.GetLine()])
+ digitClass.driver.SetSelected([categoryDlg.GetLine()])
self.UpdateMap(render=False)
redraw = True
@@ -942,17 +948,36 @@
pass
# unselect & re-draw
if redraw:
- self.parent.digit.driver.Unselect()
+ digitClass.driver.SetSelected([])
self.UpdateMap(render=False)
+
elif digitToolbar.action == "copyCats":
if not hasattr(self, "copyCatsList"):
self.copyCatsList = []
else:
self.copyCatsIds = []
self.mouse['box'] = 'box'
+
elif digitToolbar.action == "copyLine":
self.copyIds = None
self.layerTmp = None
+
+ elif digitToolbar.action == "zbulkLine":
+ if len(self.polycoords) > 1: # start new line
+ self.polycoords = []
+ self.ClearLines(pdc=self.pdcTmp)
+ self.polycoords.append(event.GetPositionTuple()[:])
+ if len(self.polycoords) == 1:
+ self.mouse['begin'] = self.polycoords[-1]
+ else:
+ self.mouse['end'] = self.polycoords[-1]
+ self.DrawLines(pdc=self.pdcTmp)
+ elif digitToolbar.action == "connectLine":
+ if len(digitClass.driver.GetSelected()) > 1:
+ # if two line selected -> reset
+ digitClass.driver.SetSelected([])
+ digitClass.driver.SelectLineByPoint(self.Pixel2Cell(self.mouse['begin']))
+
else:
# get decoration id
self.lastpos = self.mouse['begin']
@@ -970,10 +995,9 @@
Debug.msg (5, "BufferedWindow.OnLeftUp(): use=%s" % \
self.mouse["use"])
+ self.mouse['end'] = event.GetPositionTuple()[:]
+
if self.mouse['use'] in ["zoom", "pan"]:
- # end point of zoom box or drag
- self.mouse['end'] = event.GetPositionTuple()[:]
-
# set region in zoom or pan
self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype)
@@ -999,33 +1023,34 @@
elif self.mouse["use"] == "pointer" and self.parent.digittoolbar:
# digitization tool active
digitToolbar = self.parent.digittoolbar
- driver = self.parent.digit.driver
+ digitClass = self.parent.digit
+
self.mouse['end'] = event.GetPositionTuple()[:]
pos1 = self.Pixel2Cell(self.mouse['begin'])
pos2 = self.Pixel2Cell(self.mouse['end'])
if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex",
"copyCats", "editLine", "flipLine",
- "mergeLine", "snapLine", "connectLine",
+ "mergeLine", "snapLine",
"queryLine"]:
nselected = 0
# -> delete line || move line || move vertex
if digitToolbar.action in ["moveVertex", "editLine"]:
- if len(driver.GetSelected()) == 0:
+ if len(digitClass.driver.GetSelected()) == 0:
# -> move vertex (select by point)
# return vertex coordinates (tuple)
- nselected = driver.SelectLineByPoint(pos1, type="line")
+ nselected = digitClass.driver.SelectLineByPoint(pos1, type="line")
elif digitToolbar.action == "copyCats":
if not hasattr(self, "copyCatsIds"):
# collect categories
- nselected = driver.SelectLineByPoint(pos1, type="line")
+ nselected = digitClass.driver.SelectLineByPoint(pos1, type="line")
if nselected:
qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \
self.Map.width)
vWhat = gcmd.Command(['v.what',
'--q',
- 'map=%s' % self.parent.digit.map,
+ 'map=%s' % digitClass.map,
'east_north=%f,%f' % \
(float(pos1[0]), float(pos1[1])),
'distance=%f' % qdist])
@@ -1036,21 +1061,21 @@
self.copyCatsList.append(cat)
else:
# collect ids
- driver.Unselect()
+ digitClass.driver.SetSelected([])
# return number of selected features
- nselected = driver.SelectLinesByBox(pos1, pos2)
+ nselected = digitClass.driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
- self.copyCatsIds = driver.GetSelected()
+ self.copyCatsIds = digitClass.driver.GetSelected()
elif digitToolbar.action == "queryLine":
- selected = self.parent.digit.SelectLinesByQuery(pos1, pos2)
+ selected = digitClass.SelectLinesByQuery(pos1, pos2)
nselected = len(selected)
if nselected > 0:
- driver.SetSelected(selected)
+ digitClass.driver.SetSelected(selected)
else:
# -> moveLine || deleteLine, etc. (select by box)
- nselected = driver.SelectLinesByBox(pos1, pos2)
+ nselected = digitClass.driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
# highlight selected features
@@ -1063,17 +1088,17 @@
# get pseudoDC id of objects which should be redrawn
if digitToolbar.action == "moveLine":
# -> move line
- self.moveIds = driver.GetSelected(grassId=False)
+ self.moveIds = digitClass.driver.GetSelected(grassId=False)
elif digitToolbar.action == "moveVertex":
# -> move vertex
- self.moveIds = driver.GetSelectedVertex(pos1)
+ self.moveIds = digitClass.driver.GetSelectedVertex(pos1)
elif digitToolbar.action == "editLine":
# -> edit line
# get id of selected vertex (last or first node)
- selVertex = driver.GetSelectedVertex(pos1)[0]
- ids = driver.GetSelected(grassId=False)
+ selVertex = digitClass.driver.GetSelectedVertex(pos1)[0]
+ ids = digitClass.driver.GetSelected(grassId=False)
for id in ids:
if id % 2: # vertex
self.moveIds.append(id)
@@ -1084,7 +1109,7 @@
else:
self.UpdateMap(render=False, renderVector=False)
elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]:
- pointOnLine = driver.SelectLineByPoint(pos1,
+ pointOnLine = digitClass.driver.SelectLineByPoint(pos1,
type="line")
if pointOnLine:
self.UpdateMap(render=False) # highlight object
@@ -1093,15 +1118,15 @@
size=5)
elif digitToolbar.action == "removeVertex":
# get only id of vertex
- id = driver.GetSelectedVertex(pos1)[0]
+ id = digitClass.driver.GetSelectedVertex(pos1)[0]
x, y = self.pdcVector.GetIdBounds(id)[0:2]
self.pdcVector.RemoveId(id)
self.DrawCross(pdc=self.pdcVector, coords=(x, y),
size=5)
elif digitToolbar.action == "copyLine":
- if self.parent.digit.settings['backgroundMap'] == '':
+ if digitClass.settings['backgroundMap'] == '':
# no background map -> copy from current vector map layer
- nselected = driver.SelectLinesByBox(pos1, pos2)
+ nselected = digitClass.driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
# highlight selected features
@@ -1110,10 +1135,10 @@
self.UpdateMap(render=False, renderVector=False)
else:
# copy features from background map
- self.copyIds = self.parent.digit.SelectLinesFromBackgroundMap(pos1, pos2)
+ self.copyIds = digitClass.SelectLinesFromBackgroundMap(pos1, pos2)
if len(self.copyIds) > 0:
dVectTmp = ['d.vect',
- 'map=%s' % self.parent.digit.settings['backgroundMap'],
+ 'map=%s' % digitClass.settings['backgroundMap'],
'cats=%s' % ",".join(["%d" % v for v in self.copyIds]),
'-i',
'color=yellow']
@@ -1123,6 +1148,23 @@
else:
self.UpdateMap(render=False, renderVector=False)
+ elif digitToolbar.action == "zbulkLine" and len(self.polycoords) == 2:
+ # select lines to be labeled
+ pos1 = self.Pixel2Cell(self.polycoords[0])
+ pos2 = self.Pixel2Cell(self.polycoords[1])
+ nselected = digitClass.driver.SelectLinesByBox(pos1, pos2)
+
+ if nselected > 0:
+ # highlight selected features
+ self.UpdateMap(render=False)
+ self.DrawLines(pdc=self.pdcTmp) # redraw temp line
+ else:
+ self.UpdateMap(render=False, renderVector=False)
+
+ elif digitToolbar.action == "connectLine":
+ if len(digitClass.driver.GetSelected()) > 0:
+ self.UpdateMap(render=False)
+
elif self.dragid != None:
# end drag of overlay decoration
self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid)
@@ -1213,14 +1255,15 @@
Debug.msg (5, "BufferedWindow.OnRightUp(): use=%s" % \
self.mouse["use"])
- digit = self.parent.digittoolbar
- if digit:
+ digitToolbar = self.parent.digittoolbar
+ if digitToolbar:
+ digitClass = self.parent.digit
# digitization tool (confirm action)
- if digit.action == "addLine" and \
- digit.type in ["line", "boundary"]:
+ if digitToolbar.action == "addLine" and \
+ digitToolbar.type in ["line", "boundary"]:
# -> add new line / boundary
try:
- map = digit.layers[digit.layerSelectedID].name
+ map = digitToolbar.layers[digitToolbar.layerSelectedID].name
except:
map = None
dlg = wx.MessageDialog(self, _("No vector map layer is selected"),
@@ -1234,22 +1277,22 @@
for coord in self.polycoords:
mapcoords.append(self.Pixel2Cell(coord))
- self.parent.digit.AddLine(map=map,
- type=self.parent.digittoolbar.type,
+ digitClass.AddLine(map=map,
+ type=digitToolbar.type,
coords=mapcoords)
self.UpdateMap(render=False)
# add new record into atribute table
- if self.parent.digit.settings["addRecord"]:
+ if digitClass.settings["addRecord"]:
offset = 5
posWindow = self.ClientToScreen((self.polycoords[-1][0] + offset,
self.polycoords[-1][1] + offset))
# select attributes based on layer and category
addRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map,
- layer=self.parent.digit.settings["layer"],
- cat=self.parent.digit.settings["category"],
+ layer=digitClass.settings["layer"],
+ cat=digitClass.settings["category"],
pos=posWindow,
action="add")
if addRecordDlg.mapInfo and \
@@ -1263,10 +1306,10 @@
"input=%s" % sqlfile.name])
# clean up saved positions
self.polycoords = []
- elif digit.action == "deleteLine":
+ elif digitToolbar.action == "deleteLine":
# -> delete selected vector features
- self.parent.digit.DeleteSelectedLines()
- elif digit.action in ["moveLine", "moveVertex"] and \
+ digitClass.DeleteSelectedLines()
+ elif digitToolbar.action in ["moveLine", "moveVertex"] and \
hasattr(self, "moveBegin"):
# move vector feature
# move = [self.Distance((0,0), (self.moveBegin[0], 0))[0],
@@ -1281,12 +1324,12 @@
pFrom = self.Pixel2Cell(self.moveCoords)
move = (pTo[0]-pFrom[0], pTo[1]-pFrom[1])
- if digit.action == "moveLine":
+ if digitToolbar.action == "moveLine":
# move line
- self.parent.digit.MoveSelectedLines(move)
- elif digit.action == "moveVertex":
+ digitClass.MoveSelectedLines(move)
+ elif digitToolbar.action == "moveVertex":
# move vertex
- self.parent.digit.MoveSelectedVertex(pFrom,
+ digitClass.MoveSelectedVertex(pFrom,
move)
else: # edit line
pass
@@ -1294,62 +1337,77 @@
del self.moveBegin
del self.moveCoords
del self.moveIds
- elif digit.action == "splitLine":
+ elif digitToolbar.action == "splitLine":
# split line
- self.parent.digit.SplitLine(self.Pixel2Cell(self.mouse['begin']))
- elif digit.action == "addVertex":
+ digitClass.SplitLine(self.Pixel2Cell(self.mouse['begin']))
+ elif digitToolbar.action == "addVertex":
# add vertex
- self.parent.digit.AddVertex(self.Pixel2Cell(self.mouse['begin']))
- elif digit.action == "removeVertex":
+ digitClass.AddVertex(self.Pixel2Cell(self.mouse['begin']))
+ elif digitToolbar.action == "removeVertex":
# remove vertex
- self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
- elif digit.action == "copyCats":
+ digitClass.RemoveVertex(self.Pixel2Cell(self.mouse['begin']))
+ elif digitToolbar.action == "copyCats":
try:
- self.parent.digit.CopyCats(self.copyCatsList,
+ digitClass.CopyCats(self.copyCatsList,
self.copyCatsIds)
del self.copyCatsList
del self.copyCatsIds
except:
pass
- elif digit.action == "editLine" and hasattr(self, "moveBegin"):
- line = self.parent.digit.driver.GetSelected()
+ elif digitToolbar.action == "editLine" and hasattr(self, "moveBegin"):
+ line = digitClass.driver.GetSelected()
coords = []
for id in self.moveIds: # avoid last point
x, y = self.pdcVector.GetIdBounds(id)[0:2]
coords.append(self.Pixel2Cell((x, y)))
- self.parent.digit.EditLine(line, coords)
+ digitClass.EditLine(line, coords)
del self.moveBegin
del self.moveCoords
del self.moveIds
- elif digit.action == "flipLine":
- self.parent.digit.FlipLine()
- elif digit.action == "mergeLine":
- self.parent.digit.MergeLine()
- elif digit.action == "snapLine":
- self.parent.digit.SnapLine()
- elif digit.action == "connectLine":
- self.parent.digit.ConnectLine()
- elif digit.action == "copyLine":
- self.parent.digit.CopyLine(self.copyIds)
+ elif digitToolbar.action == "flipLine":
+ digitClass.FlipLine()
+ elif digitToolbar.action == "mergeLine":
+ digitClass.MergeLine()
+ elif digitToolbar.action == "snapLine":
+ digitClass.SnapLine()
+ elif digitToolbar.action == "connectLine":
+ if len(digitClass.driver.GetSelected()) == 2:
+ digitClass.ConnectLine()
+ elif digitToolbar.action == "copyLine":
+ digitClass.CopyLine(self.copyIds)
del self.copyIds
if self.layerTmp:
self.Map.DeleteLayer(self.layerTmp)
self.UpdateMap(render=True, renderVector=False)
del self.layerTmp
- if digit.action != "addLine":
- self.parent.digit.driver.Unselect()
+ elif digitToolbar.action == "zbulkLine" and len(self.polycoords) == 2:
+ pos1 = self.Pixel2Cell(self.polycoords[0])
+ pos2 = self.Pixel2Cell(self.polycoords[1])
+
+ selected = digitClass.driver.GetSelected()
+ dlg = DigitZBulkDialog(parent=self, title=_("Z bulk-labeling dialog"),
+ nselected=len(selected))
+ if dlg.ShowModal() == wx.ID_OK:
+ digitClass.ZBulkLine(pos1, pos2, dlg.value.GetValue(), dlg.step.GetValue())
+
+ self.UpdateMap(render=False, renderVector=True)
+
+ if digitToolbar.action != "addLine":
+ # unselect and re-render
+ digitClass.driver.SetSelected([])
self.UpdateMap(render=False)
event.Skip()
def OnMiddleDown(self, event):
"""Middle mouse button pressed"""
- digit = self.parent.digittoolbar
+ digitToolbar = self.parent.digittoolbar
# digitization tool
- if self.mouse["use"] == "pointer" and digit:
- if (digit.action == "addLine" and digit.type in ["line", "boundary"]) or \
- digit.action == "editLine":
+ if self.mouse["use"] == "pointer" and digitToolbar:
+ digitClass = self.parent.digit
+ if (digitToolbar.action == "addLine" and digitToolbar.type in ["line", "boundary"]) or \
+ digitToolbar.action == "editLine":
# add line or boundary -> remove last point from the line
try:
removed = self.polycoords.pop()
@@ -1360,7 +1418,7 @@
except:
pass
- if digit.action == "editLine" and len(self.moveIds) > 0:
+ if digitToolbar.action == "editLine" and len(self.moveIds) > 0:
# remove last vertex & line
self.pdcVector.RemoveId(self.moveIds[-1]) # remove last vertex
if self.moveIds[-1] > self.moveIds[-2]:
@@ -1372,47 +1430,54 @@
self.ClearLines(pdc=self.pdcTmp)
self.UpdateMap(render=False, renderVector=False)
self.DrawLines(pdc=self.pdcTmp)
- elif digit.action in ["deleteLine", "moveLine", "splitLine",
+ elif digitToolbar.action in ["deleteLine", "moveLine", "splitLine",
"addVertex", "removeVertex", "moveVertex",
"copyCats", "flipLine", "mergeLine",
"snapLine", "connectLine", "copyLine",
"queryLine"]:
# varios tools -> unselected selected features
- self.parent.digit.driver.Unselect()
- if digit.action in ["moveLine", "moveVertex", "editLine"] and \
+ digitClass.driver.SetSelected([])
+ if digitToolbar.action in ["moveLine", "moveVertex", "editLine"] and \
hasattr(self, "moveBegin"):
# move feature -> delete 'move' variables
del self.moveBegin
del self.moveCoords
del self.moveIds
- elif digit.action == "copyCats":
+ elif digitToolbar.action == "copyCats":
try:
del self.copyCatsList
del self.copyCatsIds
except:
pass
- elif digit.action == "copyLine":
+ elif digitToolbar.action == "copyLine":
del self.copyIds
if self.layerTmp:
self.Map.DeleteLayer(self.layerTmp)
self.UpdateMap(render=True, renderVector=False)
del self.layerTmp
- self.UpdateMap(render=False) # render map
+ self.UpdateMap(render=False) # render vector
+ elif digitToolbar.action == "zbulkLine":
+ # reset polyline
+ self.polycoords = []
+ digitClass.driver.SetSelected([])
+ self.UpdateMap(render=False)
+
+
def OnMouseMoving(self, event):
"""Motion event and no mouse buttons were pressed"""
- digit = self.parent.digittoolbar
- if self.mouse["use"] == "pointer" and digit:
+ digitToolbar = self.parent.digittoolbar
+ if self.mouse["use"] == "pointer" and digitToolbar:
+ digitClass = self.parent.digit
self.mouse['end'] = event.GetPositionTuple()[:]
Debug.msg (5, "BufferedWindow.OnMouseMoving(): coords=%f,%f" % \
(self.mouse['end'][0], self.mouse['end'][1]))
- if digit.action == "addLine" and \
- digit.type in ["line", "boundary"]:
+ if digitToolbar.action == "addLine" and digitToolbar.type in ["line", "boundary"]:
if len(self.polycoords) > 0:
# draw mouse moving
self.MouseDraw(self.pdcTmp)
- elif digit.action in ["moveLine", "moveVertex", "editLine"] \
+ elif digitToolbar.action in ["moveLine", "moveVertex", "editLine"] \
and hasattr(self, "moveBegin"):
dx = self.mouse['end'][0] - self.mouse['begin'][0]
dy = self.mouse['end'][1] - self.mouse['begin'][1]
@@ -1420,11 +1485,11 @@
self.moveBegin[1] += dy
if len(self.moveIds) > 0:
# draw lines on new position
- if digit.action == "moveLine":
+ if digitToolbar.action == "moveLine":
# move line
for id in self.moveIds:
self.pdcVector.TranslateId(id, dx, dy)
- elif digit.action in ["moveVertex", "editLine"]:
+ elif digitToolbar.action in ["moveVertex", "editLine"]:
# move vertex ->
# (vertex, left vertex, left line,
# right vertex, right line)
@@ -1432,7 +1497,7 @@
# self.pdcVector.RemoveId(self.moveIds[0])
# do not draw static lines
self.polycoords = []
- if digit.action == "moveVertex":
+ if digitToolbar.action == "moveVertex":
self.pdcVector.TranslateId(self.moveIds[0], dx, dy)
if self.moveIds[1] > 0: # previous vertex
x, y = self.pdcVector.GetIdBounds(self.moveIds[1])[0:2]
@@ -1461,6 +1526,11 @@
self.Refresh() # TODO: use RefreshRect()
self.mouse['begin'] = self.mouse['end']
+
+ elif digitToolbar.action == "zbulkLine":
+ if len(self.polycoords) == 1:
+ # draw mouse moving
+ self.MouseDraw(self.pdcTmp)
event.Skip()
@@ -2108,7 +2178,7 @@
Debug.msg(3, "BufferedWindow.ReRender():")
self.MapWindow.UpdateMap(render=True)
- def Pointer(self, event):
+ def OnPointer(self, event):
"""Pointer button clicled"""
self.MapWindow.mouse['use'] = "pointer"
@@ -2118,6 +2188,19 @@
if self.digittoolbar:
# digitization tool activated
self.MapWindow.SetCursor(self.cursors["cross"])
+
+ # reset mouse['box'] if needed
+ if self.digittoolbar.action in ['addLine']:
+ if digittoolbar.type in ['point', 'centroid']:
+ self.MapWindow.mouse['box'] = 'point'
+ else: # line, boundary
+ self.MapWindow.mouse['box'] = 'line'
+ elif self.digittoolbar.action in ['addVertex', 'removeVertex', 'splitLine',
+ 'editLine', 'displayCats', 'displayAttrs',
+ 'copyCats', 'connectLine']:
+ self.MapWindow.mouse['box'] = 'point'
+ else: # moveLine, deleteLine
+ self.MapWindow.mouse['box'] = 'box'
else:
self.MapWindow.SetCursor(self.cursors["default"])
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -542,9 +542,9 @@
# ("","","", "")
)),
("Help", (
- ("GRASS help", "GRASS help", "self.RunMenuCmd", ['g.manual', '-i']),
- ("GIS Manager help", "GIS Manager help", "self.RunMenuCmd", ['g.manual', 'gis.m']),
- ("About GRASS", "About GRASS", "self.OnAboutGRASS", ""),
+ ("GRASS GIS help", "GRASS GIS help", "self.RunMenuCmd", ['g.manual', '-i']),
+ ("GRASS GIS Layer Manager help", "GRASS GIS Layer Manager help", "self.RunMenuCmd", ['g.manual', 'gis.m']),
+ ("About GRASS GIS", "About GRASS GIS", "self.OnAboutGRASS", ""),
# ("About system (not functional)", "About system", "self.OnMenuCmd", ""),
# ("","","", "")
)))]
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -108,7 +108,7 @@
("", "", "", "", "", "", ""),
(self.pointer, "pointer", Icons["pointer"].GetBitmap(),
wx.ITEM_RADIO, Icons["pointer"].GetLabel(), Icons["pointer"].GetDesc(),
- self.mapdisplay.Pointer),
+ self.mapdisplay.OnPointer),
(self.query, "query", Icons["query"].GetBitmap(),
wx.ITEM_RADIO, Icons["query"].GetLabel(), Icons["query"].GetDesc(),
self.mapdisplay.OnQuery),
@@ -195,7 +195,7 @@
("", "", "", "", "", "", ""),
(self.gcpset, "gcpset", Icons["gcpset"].GetBitmap(),
wx.ITEM_RADIO, Icons["gcpset"].GetLabel(), Icons["gcpset"].GetDesc(),
- self.mapdisplay.Pointer),
+ self.mapdisplay.OnPointer),
(self.pan, "pan", Icons["pan"].GetBitmap(),
wx.ITEM_RADIO, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(),
self.mapdisplay.OnPan),
@@ -420,13 +420,13 @@
def OnDisplayCats(self, event):
"""Display/update categories"""
Debug.msg(2, "Digittoolbar.OnDisplayCats():")
- self.action="displayCategories"
+ self.action="displayCats"
self.parent.MapWindow.mouse['box'] = 'point'
def OnDisplayAttr(self, event):
"""Display/update attributes"""
Debug.msg(2, "Digittoolbar.OnDisplayAttr():")
- self.action="displayAttributes"
+ self.action="displayAttrs"
self.parent.MapWindow.mouse['box'] = 'point'
def OnCopyCats(self, event):
@@ -508,7 +508,7 @@
"""Connect selected lines/boundaries"""
Debug.msg(2, "Digittoolbar.OnConnect():")
self.action="connectLine"
- self.parent.MapWindow.mouse['box'] = 'box'
+ self.parent.MapWindow.mouse['box'] = 'point'
def OnQuery(self, event):
"""Query selected lines/boundaries"""
@@ -520,7 +520,7 @@
"""Z bulk-labeling selected lines/boundaries"""
Debug.msg(2, "Digittoolbar.OnZBulk():")
self.action="zbulkLine"
- self.parent.MapWindow.mouse['box'] = 'box'
+ self.parent.MapWindow.mouse['box'] = 'line'
def OnSelectMap (self, event):
"""
@@ -530,13 +530,20 @@
firstly terminated. The map layer is closed. After this the
selected map layer activated for editing.
"""
- if self.layerSelectedID: # deactive map layer for editing
+
+ if self.layerSelectedID == event.GetSelection():
+ return False
+
+ if self.layerSelectedID != None: # deactive map layer for editing
self.StopEditing(self.layers[self.layerSelectedID])
# select the given map layer for editing
- self.layerSelectedID = self.combo.GetCurrentSelection()
+ self.layerSelectedID = event.GetSelection()
self.StartEditing(self.layers[self.layerSelectedID])
+ event.Skip()
+
+ return True
def StartEditing (self, layerSelected):
"""
Start editing of selected vector map layer.
@@ -587,7 +594,8 @@
(layerSelected.name))
self.combo.SetValue ('Select vector map')
- # re-active layer
+ # re-active layer
+ # TODO: if status doesn't change in layer tree...
self.mapcontent.ChangeLayerActive(layerSelected, True)
self.parent.digit.SetMapName(None)
@@ -637,6 +645,12 @@
self.combo = wx.ComboBox(self.toolbar[0], id=wx.ID_ANY, value=value,
choices=layerNameList, size=(150, -1), style=wx.CB_READONLY)
+
+ # update layer index
+ try:
+ self.layerSelectedID = layerNameList.index(value)
+ except ValueError:
+ self.layerSelectedID = None
self.comboid = self.toolbar[0].InsertControl(0, self.combo)
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -245,7 +245,7 @@
self.popupMenu = wx.Menu()
# general item
- self.popupMenu.Append(self.popupID1, text=_("Delete"))
+ self.popupMenu.Append(self.popupID1, text=_("Remove"))
self.Bind(wx.EVT_MENU, self.gismgr.DeleteLayer, id=self.popupID1)
if ltype != "command": # rename
@@ -279,12 +279,19 @@
layer = self.layers[self.layer_selected].maplayer
# enable editing only for vector map layers available in the current mapset
digit = self.mapdisplay.digittoolbar
- if layer.GetMapset() != grassenv.env["MAPSET"] or \
- (digit and digit.layerSelectedID != None and \
- digit.layers[digit.layerSelectedID] == layer):
+ if layer.GetMapset() != grassenv.env["MAPSET"]:
+ # only vector map in current mapset can be edited
self.popupMenu.Enable (self.popupID5, False)
- if layer.GetMapset() == grassenv.env["MAPSET"]:
- self.popupMenu.Enable (self.popupID6, True)
+ self.popupMenu.Enable (self.popupID6, False)
+ elif digit and digit.layerSelectedID != None:
+ # vector map already edited
+ if digit.layers[digit.layerSelectedID] == layer:
+ self.popupMenu.Enable (self.popupID5, False)
+ self.popupMenu.Enable(self.popupID6, True)
+ self.popupMenu.Enable(self.popupID1, False)
+ else:
+ self.popupMenu.Enable(self.popupID5, False)
+ self.popupMenu.Enable(self.popupID6, False)
# raster
elif mltype and mltype == "raster":
@@ -579,6 +586,9 @@
if self.mapdisplay.autoRender.GetValue():
self.mapdisplay.ReRender(None)
+ if self.mapdisplay.digittoolbar:
+ self.mapdisplay.digittoolbar.UpdateListOfLayers (updateTool=True)
+
def OnLayerChecked(self, event):
"""Enable/disable given layer item"""
item = event.GetItem()
Property changes on: trunk/grassaddons/gui/icons/silk
___________________________________________________________________
Name: svn:ignore
+ __init__.pyc
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-12 19:05:38 UTC (rev 1132)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-13 19:55:37 UTC (rev 1133)
@@ -141,7 +141,7 @@
# self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL)
# do layout
- self.SetTitle(_("GRASS Layer Manager"))
+ self.SetTitle(_("GRASS GIS Layer Manager"))
self.SetMinSize((500, 400))
self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.smlogo.gif'), wx.BITMAP_TYPE_ANY))
@@ -813,12 +813,12 @@
layerName = str(self.curr_page.maptree.GetItemText(self.curr_page.maptree.layer_selected))
if layerName:
- message = _("Are you sure you want delete layer <" + layerName + ">?")
+ message = _("Are you sure you want remove layer <" + layerName + ">?")
else:
- message = _("Are you sure you want delete this layer?")
+ message = _("Are you sure you want remove selected layer?")
dlg = wx.MessageDialog (parent=self, message=message,
- caption=_("Delete layer"),
+ caption=_("Remove layer from layer tree"),
style=wx.YES_NO | wx.NO_DEFAULT | wx.CANCEL | wx.ICON_QUESTION)
if dlg.ShowModal() in [wx.ID_NO, wx.ID_CANCEL]:
From landa at grass.itc.it Sat Oct 13 22:49:15 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Sat Oct 13 22:49:17 2007
Subject: [grass-addons] r1134 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710132049.l9DKnFsH020394@grass.itc.it>
Author: landa
Date: 2007-10-13 22:49:07 +0200 (Sat, 13 Oct 2007)
New Revision: 1134
Modified:
trunk/grassaddons/gui/gui_modules/dbm.py
trunk/grassaddons/gui/gui_modules/debug.py
trunk/grassaddons/gui/gui_modules/georect.py
trunk/grassaddons/gui/gui_modules/profile.py
trunk/grassaddons/gui/gui_modules/render.py
trunk/grassaddons/gui/gui_modules/select.py
trunk/grassaddons/gui/gui_modules/utils.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/location_wizard.py
Log:
Cosmetics: cmd -> gcmd
Modified: trunk/grassaddons/gui/gui_modules/dbm.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/dbm.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -37,7 +37,7 @@
import wx.lib.mixins.listctrl as listmix
import grassenv
-import gcmd as cmd
+import gcmd
from debug import Debug as Debug
class Log:
@@ -94,7 +94,7 @@
# building the columns
i = 0
# FIXME: Maximal number of columns, when the GUI is still usable
- dbDescribe = cmd.Command (cmd = ["db.describe", "-c",
+ dbDescribe = gcmd.Command (cmd = ["db.describe", "-c",
"table=%s" % self.parent.tablename,
"driver=%s" % self.parent.driver,
"database=%s" % self.parent.database])
@@ -171,7 +171,7 @@
"driver=%s" % self.parent.driver]
# run command
- vDbSelect = cmd.Command (cmd=cmdv)
+ vDbSelect = gcmd.Command (cmd=cmdv)
# FIXME: Max. number of rows, while the GUI is still usable
i = 0
@@ -271,9 +271,9 @@
"width=3"]
#print cmd
if self.icon:
- cmd.append("icon=%s" % (self.icon))
+ gcmd.append("icon=%s" % (self.icon))
if self.pointsize:
- cmd.append("size=%s" % (self.pointsize))
+ gcmd.append("size=%s" % (self.pointsize))
self.qlayer = self.map.AddLayer(type="vector", name='qlayer', command=cmd,
l_active=True, l_hidden=True, l_opacity=1, l_render=False)
@@ -492,7 +492,7 @@
pointdata=None):
# get list of attribute tables (TODO: open more tables)
- vDbConnect = cmd.Command (cmd=["v.db.connect", "-g", "map=%s" % vectmap])
+ vDbConnect = gcmd.Command (cmd=["v.db.connect", "-g", "map=%s" % vectmap])
try:
if vDbConnect.returncode == 0:
@@ -875,7 +875,7 @@
def __CheckDBConnection(self):
"""Check DB connection"""
- layerCommand = cmd.Command(cmd=["v.db.connect",
+ layerCommand = gcmd.Command(cmd=["v.db.connect",
"-g", "--q",
"map=%s" % self.map,],
dlgMsg='txt')
@@ -898,7 +898,7 @@
"""Describe linked tables"""
for layer in self.layers.keys():
# determine column names and types
- columnsCommand = cmd.Command (cmd=["v.db.connect", "-c", "--q",
+ columnsCommand = gcmd.Command (cmd=["v.db.connect", "-c", "--q",
"map=%s" % self.map,
"layer=%d" % layer])
table = self.layers[layer]["table"]
@@ -921,7 +921,7 @@
Return line id or None if no line is found"""
line = None
nselected = 0
- cmdWhat = cmd.Command(cmd=['v.what',
+ cmdWhat = gcmd.Command(cmd=['v.what',
'-a', '--q',
'map=%s' % self.map,
'east_north=%f,%f' % \
@@ -965,7 +965,7 @@
table = self.layers[layer]["table"] # get table desc
# select values (only one record)
- selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q",
+ selectCommand = gcmd.Command(cmd=["v.db.select", "-v", "--q",
"map=%s" % self.map,
"layer=%d" % layer,
"where=cat=%d" % cat])
Modified: trunk/grassaddons/gui/gui_modules/debug.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/debug.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/debug.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -62,8 +62,8 @@
# testing
if __name__ == "__main__":
- import cmd
- cmd.Command (cmd=["g.gisenv", "set=DEBUG=3"])
+ import gcmd
+ gcmd.Command (cmd=["g.gisenv", "set=DEBUG=3"])
reload (grassenv) # reload GRASS environments !
for level in range (4):
Modified: trunk/grassaddons/gui/gui_modules/georect.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/georect.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/georect.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -62,7 +62,7 @@
import menuform
import select
import disp_print
-import gcmd as cmd
+import gcmd
from debug import Debug as Debug
from icon import Icons as Icons
@@ -155,15 +155,15 @@
#set environmental variables
cmdlist = ['g.gisenv', 'get=GISDBASE']
global grassdatabase
- grassdatabase = cmd.Command(cmdlist).module_stdout.read().strip()
+ grassdatabase = gcmd.Command(cmdlist).module_stdout.read().strip()
cmdlist = ['g.gisenv', 'get=LOCATION_NAME']
global curr_location
- curr_location = cmd.Command(cmdlist).module_stdout.read().strip()
+ curr_location = gcmd.Command(cmdlist).module_stdout.read().strip()
cmdlist = ['g.gisenv', 'get=MAPSET']
global curr_mapset
- curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip()
+ curr_mapset = gcmd.Command(cmdlist).module_stdout.read().strip()
# define wizard pages
self.wizard = wiz.Wizard(parent, -1, "Setup for georectification")
@@ -234,10 +234,10 @@
def SwitchLocMapset(self, location, mapset):
cmdlist = ['g.gisenv', 'set=LOCATION_NAME=%s' % location]
- cmd.Command(cmdlist)
+ gcmd.Command(cmdlist)
cmdlist = ['g.gisenv', 'set=MAPSET=%s' % mapset]
- cmd.Command(cmdlist)
+ gcmd.Command(cmdlist)
def onWizFinished(self):
global grassdatabase
Modified: trunk/grassaddons/gui/gui_modules/profile.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/profile.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/profile.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -50,7 +50,7 @@
import menuform
import disp_print
import select
-import gcmd as cmd
+import gcmd
import gui_modules.defaultfont as defaultfont
from debug import Debug as Debug
from icon import Icons as Icons
@@ -288,7 +288,7 @@
# set self.ylabel to match units if they exist
cmdlist = ['r.info', 'map=%s' % self.rast1, '-u', '--quiet']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
try:
units1 = p.module_stdout.read().strip().split('=')[1]
except:
@@ -305,7 +305,7 @@
if self.rast2 != '':
self.datalist2 = self.CreateDatalist(self.rast2, self.coordstr)
cmdlist = ['r.info', 'map=%s' % self.rast2, '-u', '--quiet']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
try:
units2 = p.module_stdout.read().strip().split('=')[1]
except:
@@ -324,7 +324,7 @@
if self.rast3 != '':
self.datalist3 = self.CreateDatalist(self.rast3, self.coordstr)
cmdlist = ['r.info', 'map=%s' % self.rast3, '-u', '--quiet']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
try:
units3 = p.module_stdout.read().strip().split('=')[1]
except:
@@ -348,7 +348,7 @@
# get value of raster cell at coordinate point
try:
cmdlist = ['r.what', 'input=%s' % self.rast1, 'east_north=%d,%d' % (east,north)]
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.returncode == 0:
output = p.module_stdout.read().strip().split('|')
val = output[3]
@@ -427,7 +427,7 @@
datalist = []
try:
# cmdlist = ['r.profile', 'input=%s' % raster, 'profile=%s' % coords, 'null=nan', '--quiet']
-# p = cmd.Command(cmdlist, wait=False)
+# p = gcmd.Command(cmdlist, wait=False)
# output = p.module_stdout.read().strip().split('\n')
# if p.returncode == 0:
# for outline in output:
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -19,7 +19,7 @@
import os, sys, glob, math
import utils
-import gcmd as cmd
+import gcmd
from debug import Debug as Debug
class MapLayer(object):
@@ -127,7 +127,7 @@
(self.name, self.cmdlist))
return None
- runcmd = cmd.Command(cmd=self.cmdlist + ['--q']) # run quiet
+ runcmd = gcmd.Command(cmd=self.cmdlist + ['--q']) # run quiet
if runcmd.returncode != 0:
print "Could not execute '%s'" % (self.cmdlist)
for msg in runcmd.msg:
@@ -276,7 +276,7 @@
"in GRASS GIS to run this program\n"))
sys.exit(1)
- gisenvCmd = cmd.Command(["g.gisenv"])
+ gisenvCmd = gcmd.Command(["g.gisenv"])
for line in gisenvCmd.ReadStdOutput():
line = line.strip()
@@ -398,7 +398,7 @@
os.unsetenv("GRASS_REGION")
# do not update & shell style output
- cmdRegion = cmd.Command(["g.region", "-u", "-g", "-p", "-c"])
+ cmdRegion = gcmd.Command(["g.region", "-u", "-g", "-p", "-c"])
for reg in cmdRegion.ReadStdOutput():
reg = reg.strip()
@@ -490,7 +490,7 @@
projinfo = {}
- p = cmd.Command(['g.proj', '-p'])
+ p = gcmd.Command(['g.proj', '-p'])
if p.returncode == 0:
for line in p.ReadStdOutput():
Modified: trunk/grassaddons/gui/gui_modules/select.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/select.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/select.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -24,7 +24,7 @@
GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
sys.path.append(GuiModulePath)
-import gcmd as cmd
+import gcmd
class SelectDialog(wx.Dialog):
def __init__(self, parent, id=wx.ID_ANY, title='Select GIS element',
@@ -156,11 +156,11 @@
"""
#set environmental variables
cmdlist = ['g.gisenv', 'get=MAPSET']
- curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip()
+ curr_mapset = gcmd.Command(cmdlist).module_stdout.read().strip()
#mapsets in current location
cmdlist = ['g.mapsets', '-p']
- mapsets = cmd.Command(cmdlist).module_stdout.read().strip().split(' ')
+ mapsets = gcmd.Command(cmdlist).module_stdout.read().strip().split(' ')
# map element types to g.mlist types
elementdict = {'cell':'rast',
@@ -219,7 +219,7 @@
self.seltree.SetItemTextColour(dir_node, wx.Colour(50,50,200))
try:
cmdlist = ['g.mlist', 'type=%s' % elementdict[element], 'mapset=%s' % dir]
- elem_list = cmd.Command(cmdlist).module_stdout.read().strip().split('\n')
+ elem_list = gcmd.Command(cmdlist).module_stdout.read().strip().split('\n')
elem_list.sort()
for elem in elem_list:
if elem != '': self.AddItem(elem+'@'+dir, parent=dir_node)
@@ -230,7 +230,7 @@
self.seltree.SetItemTextColour(dir_node,wx.Colour(50,50,200))
try:
cmdlist = ['g.mlist', 'type=%s' % elementdict[element], 'mapset=%s' % dir]
- elem_list = cmd.Command(cmdlist).module_stdout.read().strip().split('\n')
+ elem_list = gcmd.Command(cmdlist).module_stdout.read().strip().split('\n')
elem_list.sort()
for elem in elem_list:
if elem != '': self.AddItem(elem+'@'+dir, parent=dir_node)
Modified: trunk/grassaddons/gui/gui_modules/utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/utils.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/utils.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -16,7 +16,7 @@
import os
-import gcmd as cmd
+import gcmd
def GetTempfile(pref=None):
"""
@@ -28,7 +28,7 @@
Path to file name (string) or None
"""
- tempfileCmd = cmd.Command(["g.tempfile",
+ tempfileCmd = gcmd.Command(["g.tempfile",
"pid=%d" %
os.getpid()])
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -35,7 +35,7 @@
import menuform
import mapdisp
import render
-import gcmd as cmd
+import gcmd
import grassenv
import histogram
from debug import Debug as Debug
@@ -1101,7 +1101,7 @@
else:
# process GRASS command with argument
cmdlist.append('--verbose')
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
# deactivate computational region and return to display settings
Modified: trunk/grassaddons/gui/location_wizard.py
===================================================================
--- trunk/grassaddons/gui/location_wizard.py 2007-10-13 19:55:37 UTC (rev 1133)
+++ trunk/grassaddons/gui/location_wizard.py 2007-10-13 20:49:07 UTC (rev 1134)
@@ -27,18 +27,19 @@
License (>=v2). Read the file COPYING that comes with GRASS
for details.
"""
-import gui_modules
-import gui_modules.cmd as cmd
import os
import shutil
import re
import string
import sys
+
import wx
import wx.lib.mixins.listctrl as listmix
import wx.lib.rcsizer as rcs
import wx.wizard as wiz
+import gui_modules
+import gui_modules.gcmd as gcmd
try:
import subprocess
except:
@@ -1186,7 +1187,7 @@
#Set current working environment to PERMANENT mapset in selected location in order to set default region (WIND)
envval = {}
cmdlist = ['g.gisenv']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.returncode == 0:
output = p.module_stdout.read().strip("'").split(';\n')
for line in output:
@@ -1199,7 +1200,7 @@
pass
else:
cmdlist = ['g.mapset', 'location=%s' % self.location, 'mapset=PERMANENT']
- cmd.Command(cmdlist)
+ gcmd.Command(cmdlist)
else:
wx.MessageBox('A valid location must be selected')
return
@@ -1207,7 +1208,7 @@
#Get current region settings
region = {}
cmdlist = ['g.region', '-gp']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.returncode == 0:
output = p.module_stdout.read().split('\n')
for line in output:
@@ -1355,7 +1356,7 @@
def OnSetButton(self,event=None):
cmdlist = ['g.region', '-sgpa', 'n=%s' % self.north, 's=%s' % self.south, \
'e=%s' % self.east, 'w=%s' % self.west, 'res=%s' % self.res]
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.returncode == 0:
output = p.module_stdout.read()
wx.MessageBox('New default region:\n%s' % output)
@@ -1695,7 +1696,7 @@
# Creating location from PROJ.4 string passed to g.proj
try:
cmdlist = ['g.proj', '-c', 'proj4=%s' % proj4string, 'location=%s' % location]
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.module.returncode == 0:
return True
else:
@@ -1724,7 +1725,7 @@
try:
cmdlist = ['g.proj','-c','proj4=%s' % proj4string,'location=%s' % location]
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.module.returncode == 0:
return True
else:
@@ -1767,7 +1768,7 @@
# creating location
try:
cmdlist = ['g.proj','epsg=%s' % epsgcode,'datumtrans=-1']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
dtoptions = p.module_stdout.read()
if dtoptions != None:
dtrans = ''
@@ -1794,7 +1795,7 @@
else:
cmdlist = ['g.proj','-c','epsg=%s' % epsgcode,'location=%s' % location,'datumtrans=1']
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.module.returncode == 0:
return True
else:
@@ -1842,7 +1843,7 @@
# creating location
try:
cmdlist = ['g.proj','-c','georef=%s' % georeffile,'location=%s' % location]
- p = cmd.Command(cmdlist)
+ p = gcmd.Command(cmdlist)
if p.module.returncode == 0:
return True
else:
From landa at grass.itc.it Sun Oct 14 11:30:15 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Sun Oct 14 11:30:17 2007
Subject: [grass-addons] r1135 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710140930.l9E9UF7C016648@grass.itc.it>
Author: landa
Date: 2007-10-14 11:30:12 +0200 (Sun, 14 Oct 2007)
New Revision: 1135
Modified:
trunk/grassaddons/gui/gui_modules/gcmd.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
Log:
Minor fixes in GMConsole & gcmd, command output widget need to be improved...
Modified: trunk/grassaddons/gui/gui_modules/gcmd.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-13 20:49:07 UTC (rev 1134)
+++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-14 09:30:12 UTC (rev 1135)
@@ -1,5 +1,5 @@
"""
-PACKAGE: gcmd
+MODULE: gcmd
CLASSES:
* EndOfCommand
@@ -9,7 +9,7 @@
AUTHORS: The GRASS Development Team
Original author: Jachym Cepicky
- Various updates: Martin Landa
+ Various updates: Martin Landa
COPYRIGHT: (C) 2007 by the GRASS Development Team
This program is free software under the GNU General Public
@@ -50,7 +50,7 @@
Parameters:
cmd - command string (given as list)
stdin - standard input stream
- verbose - verbose mode (GRASS commands '--v') (default: False)
+ verbose - verbose mode [0; 3]
wait - wait for childer execution
dlgMsg - type of error message (None, gui, txt) [only if wait=True]
@@ -66,14 +66,23 @@
"""
def __init__ (self, cmd, stdin=None,
- verbose=False, wait=True, dlgMsg='gui'):
+ verbose=0, wait=True, dlgMsg='gui'):
#
# input
#
self.module_stdin = None
self.cmd = cmd
+ self.dlgMsg = dlgMsg
#
+ # set verbosity level
+ #
+ if verbose == 0 and '--q' not in self.cmd:
+ self.cmd.append('--q')
+ elif verbose == 3 and '--v' not in self.cmd:
+ self.cmd.append('--v')
+
+ #
# GRASS module
#
self.module = None
@@ -82,14 +91,13 @@
# output
#
self.module_stderr = None
- self.module_msg = [] # list of messages (msgtype, content)
#
# set message formatting
#
message_format = os.getenv("GRASS_MESSAGE_FORMAT")
- # os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
- os.environ["GRASS_MESSAGE_FORMAT"] = "txt"
+ os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
+ # os.environ["GRASS_MESSAGE_FORMAT"] = "txt"
#
# run command ...
@@ -121,35 +129,28 @@
else:
os.unsetenv("GRASS_MESSAGE_FORMAT")
- #
- # read stderr
- # ...
- # self.messages = []
- # self.errors = []
- # self.warnings = []
+ # list of messages (<- stderr)
+ # -> [(type, content)] type = (error, warning, message)
+ self.module_msg = self.__ProcessStdErr() # -> self.module_msg
- # try:
- # self.__ProcessMessages() # -> messages, errors, warnings
- # except EndOfCommand:
- # pass
-
if self.module:
if wait:
self.module.wait()
self.returncode = self.module.returncode
# failed?
- if dlgMsg and self.returncode != 0:
- errs = self.ReadErrOutput()
- if dlgMsg == 'gui': # GUI dialog
+ if self.dlgMsg and self.returncode != 0:
+ if self.dlgMsg == 'gui': # GUI dialog
dlg = wx.MessageDialog(None,
- ("Execution failed: '%s'\n\nDetails:\n%s") % (' '.join(self.cmd), '\n'.join(errs)),
+ ("Execution failed: '%s'\n\n"
+ "Details:\n%s") % (' '.join(self.cmd),
+ self.PrintModuleOutput()),
("Error"), wx.OK | wx.ICON_ERROR)
dlg.ShowModal()
dlg.Destroy()
else: # otherwise 'txt'
print >> sys.stderr, "Execution failed: '%s'" % (' '.join(self.cmd))
- print >> sys.stderr, "Details:\n%s" % '\n'.join(errs)
+ print >> sys.stderr, "\nDetails:\n%s" % self.PrintModuleOutput()
else:
self.returncode = None # running ?
@@ -161,28 +162,36 @@
Debug.msg (3, "Command(): cmd='%s', wait=%d, returncode=?" % \
(' '.join(self.cmd), wait))
- def __ProcessMessages(self):
+ def __ProcessStdErr(self):
"""
Read messages/warnings/errors from stderr
"""
- msgtype = None
- content = None
- line = None
+ lines = self.ReadErrOutput()
- while True:
- line = self.module_stderr.readline()
- if not line:
- raise EndOfCommand
- if line.find(':') > -1:
- msgtype, content = line.split(":", 1)
- content = content.strip()
- if msgtype.find("GRASS_INFO_ERROR"):
- self.errors.append(content)
- elif msgtype.find("GRASS_INFO_WARNING") > -1:
- self.warnings.append(content)
- else:
- self.messages.append(content)
+ msg = []
+ type = None
+ content = ""
+ for line in lines:
+ if len(line) == 0:
+ continue
+ if 'GRASS_' in line: # error or warning
+ if 'GRASS_INFO_WARNING' in line: # warning
+ type = "WARNING"
+ elif 'GRASS_INFO_ERROR' in line: # error
+ type = "ERROR"
+ elif 'GRASS_INFO_END': # end of message
+ msg.append((type, content))
+ type = None
+ content = ""
+
+ if type:
+ content += line.split(':')[1].strip()
+ else: # stderr
+ msg.append((None, line.strip()))
+
+ return msg
+
def __ReadOutput(self, stream):
"""Read stream and return list of lines
@@ -207,8 +216,22 @@
"""Read standard error output and return list"""
return self.__ReadOutput(self.module_stderr)
+
+ def PrintModuleOutput(self, error=True, warning=True, message=True, rest=False):
+ """Print module errors, warnings, messages..."""
-
+ msgString = ""
+ for type, msg in self.module_msg:
+ if type:
+ if (type == 'ERROR' and error) or \
+ (type == 'WARNING' and warning) or \
+ (type == 'MESSAGE' and message):
+ msgString += " " + type + ": " + msg + "\n"
+ else:
+ msgString += " " + msg + "\n"
+
+ return msgString
+
# testing ...
if __name__ == "__main__":
SEP = "-----------------------------------------------------------------------------"
@@ -232,7 +255,7 @@
# v.net.path silently, wait for process termination
print "Running v.net.path for 0 593527.6875 4925297.0625 602083.875 4917545.8125..."
- cmd = Command(cmd=["v.net.path", "in=roads@PERMANENT", "out=tmp dmax=100000", "--o"],
+ cmd = Command(cmd=["v.net.path", "in=roads@PERMANENT", "out=tmp", "dmax=100000", "--o"],
stdin="0 593527.6875 4925297.0625 602083.875 4917545.8125",
verbose=False,
wait=True, dlgMsg='txt')
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-13 20:49:07 UTC (rev 1134)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-14 09:30:12 UTC (rev 1135)
@@ -858,11 +858,6 @@
self.layers[layer].AddProperties (propwin)
- def writeDCommand(self, dcmd):
- # echos d.* command to output console
- global goutput
- goutput.write(dcmd+"\n----------\n")
-
def ReorderLayers(self):
"""Add commands from data associated with
any valid layers (checked or not) to layer list in order to
@@ -920,7 +915,7 @@
self.mapdisplay.ReRender(None)
def setNotebookPage(self,pg):
- self.Parent.notebook.SetSelection(pg)
+ self.parent.notebook.SetSelection(pg)
def OnCloseWindow(self, event):
pass
@@ -931,53 +926,55 @@
Create and manage output console for commands entered on the
GIS Manager command line.
"""
- def __init__(self, parent, id=-1,
- pos=wx.DefaultPosition, size=wx.DefaultSize,
- style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE):
+ def __init__(self, parent, id=wx.ID_ANY,
+ pos=wx.DefaultPosition, size=wx.DefaultSize,
+ style=wx.TAB_TRAVERSAL|wx.FULL_REPAINT_ON_RESIZE):
wx.Panel.__init__(self, parent, id, pos, size, style)
- #initialize variables
- self.Map = ''
- self.parent = parent
- self.cmd_output = ""
+
+ # initialize variables
+ self.Map = None
+ self.parent = parent # GMFrame
+ self.cmd_output = ""
self.console_command = ""
- self.console_clear = ""
- self.console_save = ""
- self.gcmdlst = [] #list of commands in bin and scripts
+ self.console_clear = ""
+ self.console_save = ""
+ self.gcmdlst = [] # list of commands in bin and scripts
- #text control for command output
- self.cmd_output = wx.TextCtrl(self, -1, "",
- style=wx.TE_MULTILINE|
- wx.TE_READONLY)
+ # text control for command output
+ self.cmd_output = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="",
+ style=wx.TE_MULTILINE| wx.TE_READONLY)
self.cmd_output.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
- global goutput
- goutput = self.cmd_output
- self.console_clear = wx.Button(self, -1, "Clear")
- self.console_save = wx.Button(self, -1, "Save")
-
- self.console_progressbar = wx.Gauge(self, -1, 100, (110, 50), (250, 25))
-
+ # buttons
+ self.console_clear = wx.Button(parent=self, id=wx.ID_CLEAR)
+ self.console_save = wx.Button(parent=self, id=wx.ID_SAVE)
self.Bind(wx.EVT_BUTTON, self.ClearHistory, self.console_clear)
self.Bind(wx.EVT_BUTTON, self.SaveHistory, self.console_save)
+ # progress bar
+ self.console_progressbar = wx.Gauge(parent=self, id=wx.ID_ANY,
+ range=100, pos=(110, 50), size=(-1, 25))
+
# output control layout
boxsizer1 = wx.BoxSizer(wx.VERTICAL)
- gridsizer1 = wx.GridSizer(1, 2, 0, 0)
- boxsizer1.Add(self.cmd_output, 1,
- wx.EXPAND|wx.ADJUST_MINSIZE, 0)
- gridsizer1.Add(self.console_clear, 0,
- wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
- gridsizer1.Add(self.console_save, 0,
- wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+ gridsizer1 = wx.GridSizer(rows=1, cols=2, vgap=0, hgap=0)
+ boxsizer1.Add(item=self.cmd_output, proportion=1,
+ flag=wx.EXPAND | wx.ADJUST_MINSIZE, border=0)
+ gridsizer1.Add(item=self.console_clear, proportion=0,
+ flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, border=0)
+ gridsizer1.Add(item=self.console_save, proportion=0,
+ flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, border=0)
- boxsizer1.Add((0,5))
- boxsizer1.Add(gridsizer1, 0, wx.EXPAND|wx.ALIGN_CENTRE_VERTICAL)
- boxsizer1.Add((0,5))
- boxsizer1.Add(self.console_progressbar, 0,
- wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+ boxsizer1.Add(item=gridsizer1, proportion=0,
+ flag=wx.EXPAND | wx.ALIGN_CENTRE_VERTICAL | wx.TOP | wx.BOTTOM,
+ border=5)
+ boxsizer1.Add(item=self.console_progressbar, proportion=0,
+ flag=wx.EXPAND | wx.ADJUST_MINSIZE, border=0)
+
boxsizer1.Fit(self)
boxsizer1.SetSizeHints(self)
+
self.SetAutoLayout(True)
self.SetSizer(boxsizer1)
@@ -997,11 +994,10 @@
def RunCmd(self, command):
"""
Run in GUI or shell GRASS (or other) commands typed into
- console command text widget, echo command to
- output text widget, and send stdout output to output
+ console command text widget, and send stdout output to output
text widget.
- Command is transformed into a list for processing
+ Command is transformed into a list for processing.
TODO: Display commands (*.d) are captured and
processed separately by mapdisp.py. Display commands are
@@ -1011,12 +1007,12 @@
# create list of available GRASS commands
gcmdlst = self.GetGRASSCmds()
- # cmd = self.console_command.GetLineText(0)
+
+ # map display window available ?
try:
- curr_disp = self.Parent.Parent.curr_page.maptree.mapdisplay
+ curr_disp = self.parent.curr_page.maptree.mapdisplay
self.Map = curr_disp.GetRender()
except:
- ## disp_idx = None
curr_disp = None
try:
@@ -1028,7 +1024,6 @@
if len(cmdlist) == 1 and cmdlist[0] in gcmdlst:
# send GRASS command without arguments to GUI command interface
# except display commands (they are handled differently)
- global gmpath
if command[0:2] == "d.":
try:
layertype = {'d.rast' : 'raster',
@@ -1047,22 +1042,20 @@
'd.labels' : 'labels'}[command]
except KeyError:
print _('Command type not yet implemented')
- return
+ return False
# add layer
- self.Parent.Parent.curr_page.maptree.AddLayer(layertype)
+ self.parent.curr_page.maptree.AddLayer(layertype)
else:
menuform.GUI().ParseCommand(string.join(cmdlist), parentframe=None)
- self.cmd_output.write(string.join(cmdlist) + "\n----------\n")
+ #self.cmd_output.write(string.join(cmdlist) + "\n----------\n")
elif command[0:2] == "d." and len(cmdlist) > 1:
- """
- Send GRASS display command(s)with arguments
- to the display processor and echo to command output console.
- Accepts a list of d.* commands separated by semi-colons.
- Display with focus receives display command(s).
- """
+ # Send GRASS display command(s)with arguments
+ # to the display processor and echo to command output console.
+ # Accepts a list of d.* commands separated by semi-colons.
+ # Display with focus receives display command(s).
self.cmd_output.write("$" + ' '.join(cmdlist))
@@ -1083,72 +1076,46 @@
else:
# Send any other command to the shell. Send output to
# console output window.
- try:
- os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
- #self.cmd_output.write(command+"\n----------\n")
- self.cmd_output.write("$ " + ' '.join(cmdlist) + "\n")
+
+ if self.parent.notebook.GetSelection() != 1:
+ # select 'Command output' tab
+ self.parent.notebook.SetSelection(1)
+
+ self.cmd_output.write("$ " + ' '.join(cmdlist) + "\n")
+
+ if cmdlist[0] not in gcmdlst:
+ # if command is not a GRASS command, treat it like a shell command
+ generalCmd = subprocess.Popen(cmdlist,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ close_fds=True)
+
+ for outline in runCmd.stdout:
+ self.cmd_output.write(outline)
+ else:
# activate compuational region (set with g.region) for all non-display commands.
tmpreg = os.getenv("GRASS_REGION")
os.unsetenv("GRASS_REGION")
+ # process GRASS command with argument
+ grassCmd = gcmd.Command(cmdlist, verbose=3)
- if cmdlist[0] not in gcmdlst:
- # if command is not a GRASS command, treat it like a shell command
- output = os.popen(command, "r").read().strip().split('\n')
- for outline in output:
- self.cmd_output.write(outline+'\n')
- return
- else:
- # process GRASS command with argument
- cmdlist.append('--verbose')
- p = gcmd.Command(cmdlist)
-
-
+
# deactivate computational region and return to display settings
if tmpreg:
os.environ["GRASS_REGION"] = tmpreg
- oline = p.module_stderr.readline()
- while oline:
- oline = oline.strip()
- oline = p.module_stderr.readline()
- # make some progress
- #GRASS_INFO_PERCENT: 100
- if oline.find("GRASS_INFO_PERCENT")>-1:
- self.console_progressbar.SetValue(int(oline.split()[1]))
- elif oline.find("GRASS_INFO_MESSAGE")>-1:
- self.cmd_output.write(string.split(oline,maxsplit=1)[1]+"\n")
- elif oline.find("GRASS_INFO_WARNING")>-1:
- self.cmd_output.write("WARNING: "+string.split(oline,maxsplit=1)[1]+"\n")
- elif oline.find("GRASS_INFO_ERROR")>-1:
- self.cmd_output.write("ERROR: "+string.split(oline,maxsplit=1)[1]+"\n")
+ if grassCmd.returncode != 0:
+ return False
- oline = p.module_stdout.readline()
- while oline:
- oline = oline.strip()
- if command[0] == 'r.what':
- rastqlist = oline.split('|')
- self.cmd_output.write('East: '+rastqlist[0]+"\n")
- self.cmd_output.write('North: '+rastqlist[1]+"\n")
- self.cmd_output.write(rastqlist[2]+"\n")
- data = rastqlist[3:]
- for x in range(0,len(data),2):
- self.cmd_output.write('Category: '+data[x]+"\n")
- self.cmd_output.write('Label: '+data[x+1]+"\n")
- else:
- self.cmd_output.write(oline+"\n")
- print >> sys.stderr, oline
- oline = p.module_stdout.readline()
- #self.cmd_output.write("\n==========\n")
- self.cmd_output.write("\n")
- if p.module_stdout < 0:
- print >> sys.stderr, "Child was terminated by signal", p.module_stdout
- elif p.module_stdout > 0:
- #print >> sys.stderr, p.module_stdout
- pass
- except OSError, e:
- print >> sys.stderr, "Execution failed:", e
+ # if oline.find("GRASS_INFO_PERCENT")>-1:
+ # self.console_progressbar.SetValue(int(oline.split()[1]))
+ for line in grassCmd.ReadStdOutput():
+ self.cmd_output.write(line + '\n')
+
+ return True
+
def ClearHistory(self, event):
"""Clear history of commands"""
self.cmd_output.Clear()
From landa at grass.itc.it Sun Oct 14 11:34:09 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Sun Oct 14 11:34:10 2007
Subject: [grass-addons] r1136 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710140934.l9E9Y9P3016829@grass.itc.it>
Author: landa
Date: 2007-10-14 11:34:07 +0200 (Sun, 14 Oct 2007)
New Revision: 1136
Modified:
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
Log:
Bugfix for GMConsole.SaveHistory().
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-14 09:30:12 UTC (rev 1135)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-14 09:34:07 UTC (rev 1136)
@@ -1131,16 +1131,17 @@
#Use a standard dialog for this
wildcard = "Text file (*.txt)|*.txt"
dlg = wx.FileDialog(
- self, message="Save file as ...", defaultDir=os.getcwd(),
- defaultFile="grass_cmd_history.txt", wildcard=wildcard, style=wx.SAVE|wx.FD_OVERWRITE_PROMPT
- )
+ self, message=_("Save file as ..."), defaultDir=os.getcwd(),
+ defaultFile="grass_cmd_history.txt", wildcard=wildcard,
+ style=wx.SAVE|wx.FD_OVERWRITE_PROMPT)
# Show the dialog and retrieve the user response. If it is the OK response,
# process the data.
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
- output = open(path,"w")
- output.write(self.history)
- output.close()
+ output = open(path,"w")
+ output.write(self.history)
+ output.close()
+
dlg.Destroy()
From landa at grass.itc.it Tue Oct 16 13:49:22 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Tue Oct 16 13:49:24 2007
Subject: [grass-addons] r1137 - in trunk/grassaddons/gui: . gui_modules icons
icons/silk
Message-ID: <200710161149.l9GBnMPl022158@grass.itc.it>
Author: landa
Date: 2007-10-16 13:49:11 +0200 (Tue, 16 Oct 2007)
New Revision: 1137
Added:
trunk/grassaddons/gui/gui_modules/grass-grc.dtd
trunk/grassaddons/gui/icons/silk/folder.png
trunk/grassaddons/gui/icons/silk/page_save.png
trunk/grassaddons/gui/icons/silk/page_white.png
Modified:
trunk/grassaddons/gui/gui_modules/grass-interface.dtd
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/icons/icon.py
trunk/grassaddons/gui/icons/silk/__init__.py
trunk/grassaddons/gui/wxgui.py
Log:
Support for workspace file added (currently only basic prototype of "Save workspace to file" implemented).
Added: trunk/grassaddons/gui/gui_modules/grass-grc.dtd
===================================================================
--- trunk/grassaddons/gui/gui_modules/grass-grc.dtd (rev 0)
+++ trunk/grassaddons/gui/gui_modules/grass-grc.dtd 2007-10-16 11:49:11 UTC (rev 1137)
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Modified: trunk/grassaddons/gui/gui_modules/grass-interface.dtd
===================================================================
--- trunk/grassaddons/gui/gui_modules/grass-interface.dtd 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/gui_modules/grass-interface.dtd 2007-10-16 11:49:11 UTC (rev 1137)
@@ -1,14 +1,18 @@
-
+
@@ -132,6 +136,7 @@
)?
-->
+
@@ -146,4 +151,6 @@
-
+
+
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-16 11:49:11 UTC (rev 1137)
@@ -25,6 +25,14 @@
def GetMenu(self):
return [(
("File", (
+ ("Workspace (not functional)", (
+ ("Open", "Create new workspace file (erase current workspace settings first", "self.OnWorkspaceNew", ""),
+ ("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
+ ("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
+ ("Save as", "Save current workspace as...", "self.OnWorkspaceSave", ""),
+# ("Close", "Close workspace file", "self.OnWorkspaceClose", ""),
+ )),
+ ("","","", ""),
("Import raster map", (
("Multiple import formats using GDAL", "Import multiple formats using GDAL", "self.OnMenuCmd", "r.in.gdal"),
("","","", ""),
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-16 11:49:11 UTC (rev 1137)
@@ -50,7 +50,7 @@
Abstract layer in LayerTree
Attributes:
- * type - layer type ('cmdlayer', 'group', etc) -- see LayerTree.AddLayer()
+ * type - layer type ('cmdlayer', 'group', etc) -- see LayerTree.AddLayer()
"""
def __init__(self, type):
@@ -499,45 +499,45 @@
ltype)
if ltype == 'raster':
- menuform.GUI().ParseCommand('d.rast', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.rast', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rgb':
- menuform.GUI().ParseCommand('d.rgb', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.rgb', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'his':
- menuform.GUI().ParseCommand('d.his', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.his', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'shaded':
- menuform.GUI().ParseCommand('d.shadedmap', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.shadedmap', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rastarrow':
- menuform.GUI().ParseCommand('d.rast.arrow', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.rast.arrow', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rastnum':
- menuform.GUI().ParseCommand('d.rast.num', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.rast.num', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'vector':
- menuform.GUI().ParseCommand('d.vect', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.vect', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'thememap':
menuform.GUI().ParseCommand('d.vect.thematic',
- completed=(self.getOptData,layer,params),
+ completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'themechart':
menuform.GUI().ParseCommand('d.vect.chart',
- completed=(self.getOptData,layer,params),
+ completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'grid':
- menuform.GUI().ParseCommand('d.grid', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.grid', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'geodesic':
- menuform.GUI().ParseCommand('d.geodesic', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.geodesic', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rhumb':
- menuform.GUI().ParseCommand('d.rhumbline', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.rhumbline', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'labels':
- menuform.GUI().ParseCommand('d.labels', completed=(self.getOptData,layer,params),
+ menuform.GUI().ParseCommand('d.labels', completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'cmdlayer':
pass
@@ -823,7 +823,8 @@
# completed drag and drop
self.drag = False
- def getOptData(self, dcmd, layer, params, propwin):
+ def GetOptData(self, dcmd, layer, params, propwin):
+ """Process layer data"""
for item in dcmd:
if 'map=' in item:
mapname = item.split('=')[1]
Modified: trunk/grassaddons/gui/icons/icon.py
===================================================================
--- trunk/grassaddons/gui/icons/icon.py 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/icons/icon.py 2007-10-16 11:49:11 UTC (rev 1137)
@@ -65,6 +65,9 @@
"digExit" : 'exit.gif',
# gis manager
"newdisplay" : 'gui-startmon.gif',
+ "workspaceNew" : 'file-new.gif',
+ "workspaceOpen" : 'file-open.gif',
+ "workspaceSave" : 'file-save.gif',
"addrast" : 'element-cell.gif',
"addvect" : 'element-vector.gif',
"addcmd" : 'gui-cmd.gif',
@@ -210,6 +213,9 @@
"printmap" : MetaIcon (img=icons_img["printmap"], label="Print display"),
# gis manager
"newdisplay" : MetaIcon (img=icons_img["newdisplay"], label="Start new display"),
+ "workspaceNew" : MetaIcon (img=icons_img["workspaceNew"], label="Create new workspace file"),
+ "workspaceOpen" : MetaIcon (img=icons_img["workspaceOpen"], label="Open existing workspace file"),
+ "workspaceSave" : MetaIcon (img=icons_img["workspaceSave"], label="Save current workspace to file"),
"addrast" : MetaIcon (img=icons_img["addrast"], label="Add raster map layer"),
"addvect" : MetaIcon (img=icons_img["addvect"], label="Add vector map layer"),
"addcmd" : MetaIcon (img=icons_img["addcmd"], label="Add command layer"),
Modified: trunk/grassaddons/gui/icons/silk/__init__.py
===================================================================
--- trunk/grassaddons/gui/icons/silk/__init__.py 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/icons/silk/__init__.py 2007-10-16 11:49:11 UTC (rev 1137)
@@ -57,6 +57,9 @@
"digExit" : 'door_in.png',
# gis manager
"newdisplay" : 'application_add.png',
+ "workspaceNew" : 'page_white.png',
+ "workspaceOpen" : 'folder.png',
+ "workspaceSave" : 'page_save.png',
"addrast" : 'image_add.png',
"addshaded" : 'picture_empty.png',
"addrarrow" : 'arrow_inout.png',
Added: trunk/grassaddons/gui/icons/silk/folder.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/icons/silk/folder.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/icons/silk/page_save.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/icons/silk/page_save.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/grassaddons/gui/icons/silk/page_white.png
===================================================================
(Binary files differ)
Property changes on: trunk/grassaddons/gui/icons/silk/page_white.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-14 09:34:07 UTC (rev 1136)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-16 11:49:11 UTC (rev 1137)
@@ -404,6 +404,81 @@
wx.AboutBox(info)
+ def OnWorkspaceNew(self, event):
+ """Create new workspace file
+
+ Erase current workspace settings first"""
+ pass
+
+ def OnWorkspaceOpen(self, event):
+ """Open file with workspace definition"""
+ dlg = wx.FileDialog(parent=self, message=_("Choose workspace file"),
+ defaultDir=os.getcwd(), wildcard="*.grc")
+
+ filename = ''
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetFilename()
+
+ Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
+
+ def OnWorkspaceSave(self, event):
+ """Save file with workspace definition"""
+
+ filename = "test-out.grc"
+
+ self.SaveLayerTreeToGrcXml(filename)
+
+ def SaveLayerTreeToGrcXml(self, filename):
+ """Save layer tree layout to workspace file"""
+
+ file = open(filename, "w")
+ #file = sys.stderr
+ try:
+ # write header
+ file.write('\n')
+ file.write('\n')
+ file.write('\n')
+ # list of layers
+ mapTree = self.curr_page.maptree
+ root = mapTree.GetRootItem()
+ childitem = mapTree.GetFirstChild(root)
+ item = childitem[0]
+ cookie = childitem[1]
+ for n in range(0, mapTree.GetChildrenCount(root)):
+ layer = mapTree.layers[item]
+ type = layer.type
+ name = mapTree.GetItemText(item)
+ checked = int(item.IsChecked())
+ opacity = layer.maplayer.GetOpacity(float=True)
+ file.write(' \n' % \
+ (type, name, checked, opacity));
+ # layer properties
+ cmd = mapTree.GetPyData(item)[0]
+ file.write(' \n' % cmd[0])
+ for option in cmd[1:]:
+ if option[0] == '-': # flag
+ file.write(' \n' % option[1])
+ else: # parameter
+ key, value = option.split('=')
+ file.write(' \n' % key)
+ file.write(' %s\n' % value)
+ file.write(' \n');
+ file.write(' \n');
+ file.write(' \n');
+ item = mapTree.GetNextChild(item, cookie)[0]
+ file.write('\n')
+ finally:
+ pass
+ #file.close()
+
+ def OnWorkspaceClose(self, event):
+ """Close file with workspace definition
+
+ If workspace has been modified ask user to save the changes.
+ """
+ pass
+
+
def RulesCmd(self, event):
"""
Launches dialog for commands that need rules
@@ -414,8 +489,10 @@
if dlg.ShowModal() == wx.ID_OK:
gtemp = utils.GetTempfile()
output = open(gtemp,"w")
- output.write(dlg.rules)
- output.close()
+ try:
+ output.write(dlg.rules)
+ finally:
+ output.close()
if command == 'r.colors':
cmdlist = [command,'map=%s' % dlg.inmap,'rules=%s' % gtemp,'--verbose']
@@ -425,10 +502,8 @@
if dlg.overwrite == True:
cmdlist.append('--o')
- cmdlist.append('--verbose')
+ gcmd.Command(cmdlist, verbose=3)
- gcmd.Command(cmdlist)
-
dlg.Destroy()
def OnXTerm(self, event):
@@ -523,11 +598,11 @@
"""Creates toolbar"""
toolbar = self.CreateToolBar()
- for each in self.toolbarData():
- self.addToolbarButton(toolbar, *each)
+ for each in self.ToolbarData():
+ self.AddToolbarButton(toolbar, *each)
toolbar.Realize()
- def addToolbarButton(self, toolbar, label, icon, help, handler):
+ def AddToolbarButton(self, toolbar, label, icon, help, handler):
"""Adds button to the given toolbar"""
if not label:
@@ -536,11 +611,15 @@
tool = toolbar.AddLabelTool(id=wx.ID_ANY, label=label, bitmap=icon, shortHelp=help)
self.Bind(wx.EVT_TOOL, handler, tool)
- def toolbarData(self):
+ def ToolbarData(self):
return (
('newdisplay', Icons["newdisplay"].GetBitmap(), Icons["newdisplay"].GetLabel(), self.NewDisplay),
('', '', '', ''),
+ ('workspaceNew', Icons["workspaceNew"].GetBitmap(), Icons["workspaceNew"].GetLabel(), self.OnWorkspaceNew),
+ ('workspaceOpen', Icons["workspaceOpen"].GetBitmap(), Icons["workspaceOpen"].GetLabel(), self.OnWorkspaceOpen),
+ ('workspaceSave', Icons["workspaceSave"].GetBitmap(), Icons["workspaceSave"].GetLabel(), self.OnWorkspaceSave),
+ ('', '', '', ''),
('addrast', Icons["addrast"].GetBitmap(), Icons["addrast"].GetLabel(), self.OnRaster),
('addvect', Icons["addvect"].GetBitmap(), Icons["addvect"].GetLabel(), self.OnVector),
('addcmd', Icons["addcmd"].GetBitmap(), Icons["addcmd"].GetLabel(), self.AddCommand),
@@ -841,15 +920,10 @@
self.DeleteAllPages()
except:
pass
-# self.DestroyChildren()
+ # self.DestroyChildren()
self._auimgr.UnInit()
self.Destroy()
- def Nomethod(self, event):
- '''Stub for testing'''
- pass
- event.Skip()
-
def MsgNoLayerSelected(self):
"""Show dialog message 'No layer selected'"""
dlg = wx.MessageDialog(self, _("No layer selected"), _("Error"), wx.OK | wx.ICON_ERROR)
From landa at grass.itc.it Tue Oct 16 21:52:28 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Tue Oct 16 21:52:29 2007
Subject: [grass-addons] r1138 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710161952.l9GJqS2B031057@grass.itc.it>
Author: landa
Date: 2007-10-16 21:52:16 +0200 (Tue, 16 Oct 2007)
New Revision: 1138
Modified:
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/gui_modules/menuform.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/wxgui.py
Log:
Open workspace file implemented (not fully). Will be fixed.
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-16 11:49:11 UTC (rev 1137)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-16 19:52:16 UTC (rev 1138)
@@ -26,7 +26,7 @@
return [(
("File", (
("Workspace (not functional)", (
- ("Open", "Create new workspace file (erase current workspace settings first", "self.OnWorkspaceNew", ""),
+ ("New", "Create new workspace file (erase current workspace settings first", "self.OnWorkspaceNew", ""),
("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
("Save as", "Save current workspace as...", "self.OnWorkspaceSave", ""),
Modified: trunk/grassaddons/gui/gui_modules/menuform.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-16 11:49:11 UTC (rev 1137)
+++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-16 19:52:16 UTC (rev 1138)
@@ -1152,7 +1152,10 @@
if 'flags' in dcmd_params:
self.grass_task.flags = dcmd_params['flags']
- self.mf = mainFrame(parent=self.parent, ID=wx.ID_ANY, task_description=self.grass_task, get_dcmd=get_dcmd, layer=layer)
+ self.mf = mainFrame(parent=self.parent, ID=wx.ID_ANY,
+ task_description=self.grass_task,
+ get_dcmd=get_dcmd, layer=layer)
+
self.mf.Show(True)
self.mf.MakeModal(modal)
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-16 11:49:11 UTC (rev 1137)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-16 19:52:16 UTC (rev 1138)
@@ -373,7 +373,7 @@
"""Rename layer"""
self.EditLabel(self.layer_selected)
- def AddLayer(self, ltype):
+ def AddLayer(self, ltype, lname=None, lchecked=None, lopacity=None, lproperties=None):
"""Add new item to the layer tree, create corresponding MapLayer instance.
Launch property dialog if needed (raster, vector, etc.)"""
self.first = True
@@ -427,14 +427,14 @@
newlayer = self.layers[layer] = Layer(type=ltype, wxCtrl=ctrl)
# layer is initially unchecked as inactive (beside 'command')
+ # use predefined value if given
+ if lchecked:
+ checked = lchecked
self.CheckItem(layer, checked=checked)
# select item
self.SelectItem(layer)
- # add a data object to hold the layer's command (does not apply to generic command layers)
- self.SetPyData(layer, (None,None))
-
# add text and icons for each layer ltype
if ltype == 'raster':
self.SetItemImage(layer, self.rast_icon)
@@ -481,13 +481,36 @@
self.SetItemImage(layer, self.folder)
self.SetItemText(layer, grouptext)
+ # use predefined layer name if given
+ if lname: self.SetItemText(layer, lname)
+
self.first = False
if ltype != 'group':
- newlayer.AddMapLayer(self.Map.AddLayer(type=ltype, command=[],
- l_active=checked, l_hidden=False, l_opacity=1, l_render=False))
- self.PropertiesDialog(layer)
+ if lopacity:
+ opacity = lopacity
+ else:
+ opacity = 1.0
+ if lproperties:
+ cmd = lproperties
+ render = True
+ name = self.GetLayerNameFromCmd(cmd)
+ else:
+ cmd = []
+ render = False
+ name = None
+ newlayer.AddMapLayer(self.Map.AddLayer(type=ltype, command=cmd, name=name,
+ l_active=checked, l_hidden=False,
+ l_opacity=opacity, l_render=render))
+ if lproperties:
+ self.SetPyData(layer, (cmd,None))
+ else:
+ # add a data object to hold the layer's command (does not apply to generic command layers)
+ self.SetPyData(layer, (None,None))
+ # run properties dialog if no properties given
+ self.PropertiesDialog(layer)
+
def PropertiesDialog (self, layer):
"""Launch the properties dialog"""
global gmpath
@@ -569,19 +592,25 @@
except:
pass
- Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
- (self.GetItemText(item)))
+ if item != self.root:
+ Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
+ (self.GetItemText(item)))
+ else:
+ self.root = None
# unselect item
self.Unselect()
self.layer_selected = None
- layer = self.layers[item]
- if layer.type != 'group':
- self.Map.DeleteLayer(layer.maplayer)
+ try:
+ layer = self.layers[item]
+ if layer.type != 'group':
+ self.Map.DeleteLayer(layer.maplayer)
+
+ self.layers.pop(item)
+ except:
+ pass
- self.layers.pop(item)
-
# redraw map if auto-rendering is enabled
if self.mapdisplay.autoRender.GetValue():
self.mapdisplay.ReRender(None)
@@ -589,6 +618,8 @@
if self.mapdisplay.digittoolbar:
self.mapdisplay.digittoolbar.UpdateListOfLayers (updateTool=True)
+ event.Skip()
+
def OnLayerChecked(self, event):
"""Enable/disable given layer item"""
item = event.GetItem()
@@ -823,8 +854,9 @@
# completed drag and drop
self.drag = False
- def GetOptData(self, dcmd, layer, params, propwin):
- """Process layer data"""
+ def GetLayerNameFromCmd(self, dcmd):
+ """Get layer name from GRASS command"""
+ mapname = ''
for item in dcmd:
if 'map=' in item:
mapname = item.split('=')[1]
@@ -842,8 +874,14 @@
mapname = 'rhumb'
elif 'labels=' in item:
mapname = item.split('=')[1]+' labels'
+
+ return mapname
+ def GetOptData(self, dcmd, layer, params, propwin):
+ """Process layer data"""
+
# set layer text to map name
+ mapname = self.GetLayerNameFromCmd(dcmd)
self.SetItemText(layer, mapname)
# add command to layer's data
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-16 11:49:11 UTC (rev 1137)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-16 19:52:16 UTC (rev 1138)
@@ -7,6 +7,7 @@
* GRasterDialog
* GMFrame
* GMApp
+ * ProcessGrcXml
PURPOSE: Main Python app for GRASS wxPython GUI. Main menu, layer management
toolbar, notebook control for display management and access to
@@ -15,7 +16,7 @@
AUTHORS: The GRASS Development Team
Michael Barton (Arizona State University)
Jachym Cepicky (Mendel University of Agriculture)
- Martin Landa
+ Martin Landa
COPYRIGHT: (C) 2006-2007 by the GRASS Development Team
This program is free software under the GNU General Public
@@ -29,6 +30,15 @@
import time
import traceback
import types
+import re
+# for GRC (workspace file) parsering
+from xml.parsers.xmlproc import xmlproc
+from xml.parsers.xmlproc import xmlval
+from xml.parsers.xmlproc import xmldtd
+import xml.sax
+import xml.sax.handler
+HandlerBase=xml.sax.handler.ContentHandler
+from xml.sax import make_parser
import wx
import wx.aui
@@ -408,8 +418,15 @@
"""Create new workspace file
Erase current workspace settings first"""
- pass
+ # TODO: ask user to save current settings
+
+ maptree = self.curr_page.maptree
+ maptree.DeleteAllItems()
+ # add new root element
+ maptree.root = maptree.AddRoot("Map Layers")
+ self.curr_page.maptree.SetPyData(maptree.root, (None,None))
+
def OnWorkspaceOpen(self, event):
"""Open file with workspace definition"""
dlg = wx.FileDialog(parent=self, message=_("Choose workspace file"),
@@ -421,19 +438,108 @@
Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
+ self.LoadGrcXmlToLayerTree(filename)
+
+ def LoadGrcXmlToLayerTree(self, filename):
+ """Load layer tree definition stored in GRC XML file
+
+ Return True on success
+ Return False on error"""
+
+ # dtd
+ gisbase = os.getenv("GISBASE")
+ dtdFilename = os.path.join(gisbase, "etc", "wx", "gui_modules", "grass-grc.dtd")
+
+ # parse xml agains dtd
+ dtd = xmldtd.load_dtd(dtdFilename)
+ parser = xmlproc.XMLProcessor()
+ parser.set_application(xmlval.ValidatingApp(dtd, parser))
+ parser.dtd = dtd
+ parser.ent = dtd
+ try:
+ # TODO: set_error_handler(self,err)
+ parser.parse_resource(filename)
+ except:
+ dlg = wx.MessageDialog(self, _("Unable to open workspace file <%s>. "
+ "It is not valid GRC XML file.") % filename,
+ _("Error"), wx.OK | wx.ICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ # delete current layer tree content
+ self.OnWorkspaceNew(None)
+
+ # read file and fix patch to dtd
+
+ file = open(filename, "r")
+
+ fileStream = ''.join(file.readlines())
+ p = re.compile( '(grass-grc.dtd)')
+ p.search(fileStream)
+ fileStream = p.sub(dtdFilename, fileStream)
+
+ # sax
+ grcXml = ProcessGrcXml()
+ xml.sax.parseString(fileStream, grcXml)
+
+ maptree = self.curr_page.maptree
+ for layer in grcXml.layers:
+ newItem = maptree.AddLayer(ltype=layer['type'],
+ lname=layer['name'],
+ lchecked=layer['checked'],
+ lopacity=layer['opacity'],
+ lproperties=layer['cmd'])
+
+ file.close()
+# except:
+# dlg = wx.MessageDialog(self, _("Unable to read workspace file <%s>.") % filename,
+# _("Error"), wx.OK | wx.ICON_ERROR)
+# dlg.ShowModal()
+# dlg.Destroy()
+# return False
+
+ return True
+
def OnWorkspaceSave(self, event):
- """Save file with workspace definition"""
+ """Save file with workspace definition
+
+ Return True on success
+ Return False on error"""
- filename = "test-out.grc"
+ dlg = wx.FileDialog(parent=self, message=_("Choose file to save current workspace"),
+ defaultDir=os.getcwd(), wildcard="*.grc", style=wx.FD_SAVE)
+ filename = ''
+ if dlg.ShowModal() == wx.ID_OK:
+ filename = dlg.GetFilename()
+
+ if filename == '':
+ return False
+
+ # check for extension
+ if filename[-4:] != ".grc":
+ filename += ".grc"
+
+ # TODO: overwrite / save as...
+
+ Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % filename)
+
self.SaveLayerTreeToGrcXml(filename)
def SaveLayerTreeToGrcXml(self, filename):
"""Save layer tree layout to workspace file"""
- file = open(filename, "w")
- #file = sys.stderr
try:
+ file = open(filename, "w")
+ except IOError:
+ dlg = wx.MessageDialog(self, _("Unable to open workspace file <%s> for writing.") % filename,
+ _("Error"), wx.OK | wx.ICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ try:
# write header
file.write('\n')
file.write('\n')
@@ -468,9 +574,11 @@
item = mapTree.GetNextChild(item, cookie)[0]
file.write('\n')
finally:
- pass
- #file.close()
+ file.close()
+ return True
+ return False
+
def OnWorkspaceClose(self, event):
"""Close file with workspace definition
@@ -1036,6 +1144,89 @@
return True
+class ProcessGrcXml(HandlerBase):
+ """
+ A SAX handler for the GRC XML file, as
+ defined in grass-grc.dtd.
+ """
+ def __init__(self):
+ self.inGrc = False
+ self.inLayer = False
+ self.inTask = False
+ self.inParameter = False
+ self.inFlag = False
+ self.inValue = False
+
+ # list of layers
+ self.layers = []
+ self.cmd = []
+
+ def startElement(self, name, attrs):
+ if name == 'grc':
+ self.inGrc = True
+
+ elif name == 'layer':
+ self.inLayer = True
+ self.layerType = attrs.get('type', None)
+ self.layerName = attrs.get('name', None)
+ self.layerChecked = attrs.get('checked', None)
+ self.layerOpacity = attrs.get('opacity', None)
+
+ elif name == 'task':
+ self.inTask = True;
+ name = attrs.get('name', None)
+ self.cmd.append(name)
+
+ elif name == 'parameter':
+ self.inParameter = True;
+ self.parameterName = attrs.get('name', None)
+
+ elif name == 'value':
+ self.inValue = True
+ self.value = ''
+
+ elif name == 'flag':
+ self.inFlag = True;
+ name = attrs.get('name', None)
+ self.cmd.append('-' + name)
+
+ def endElement(self, name):
+ if name == 'grc':
+ self.inGrc = False
+
+ elif name == 'layer':
+ self.inLayer = False
+ self.layers.append({
+ "type" : self.layerType,
+ "name" : self.layerName,
+ "checked" : int(self.layerChecked),
+ "opacity" : float(self.layerOpacity),
+ "cmd" : self.cmd})
+
+ self.layerType = self.layerName = self.Checked = \
+ self.Opacity = self.cmd = None
+
+ elif name == 'task':
+ self.inTask = False
+
+ elif name == 'parameter':
+ self.inParameter = False
+ self.cmd.append('%s=%s' % (self.parameterName, self.value))
+ self.parameterName = self.value = None
+
+ elif name == 'value':
+ self.inValue = False
+
+ elif name == 'flag':
+ self.inFlag = False
+
+ def characters(self, ch):
+ self.my_characters(ch)
+
+ def my_characters(self, ch):
+ if self.inValue:
+ self.value += ch
+
def reexec_with_pythonw():
if sys.platform == 'darwin' and\
not sys.executable.endswith('MacOS/Python'):
From landa at grass.itc.it Wed Oct 17 22:39:16 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Wed Oct 17 22:39:19 2007
Subject: [grass-addons] r1139 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710172039.l9HKdGkm016456@grass.itc.it>
Author: landa
Date: 2007-10-17 22:39:08 +0200 (Wed, 17 Oct 2007)
New Revision: 1139
Modified:
trunk/grassaddons/gui/gui_modules/grass-grc.dtd
trunk/grassaddons/gui/gui_modules/grassenv.py
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/gui_modules/menuform.py
trunk/grassaddons/gui/gui_modules/render.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/wxgui.py
Log:
Basic workspace support implemeneted.
Cleaning the code.
Layers can be added also from command prompt (including module options).
Modified: trunk/grassaddons/gui/gui_modules/grass-grc.dtd
===================================================================
--- trunk/grassaddons/gui/gui_modules/grass-grc.dtd 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/grass-grc.dtd 2007-10-17 20:39:08 UTC (rev 1139)
@@ -14,51 +14,39 @@
-
+
-
+
+
+
+
+
+
+
-
+
-
-
-
-
Modified: trunk/grassaddons/gui/gui_modules/grassenv.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -1,5 +1,26 @@
+"""
+MODULE: grassenv
+
+PURPOSE: GRASS environment variable management
+
+AUTHORS: The GRASS Development Team
+ Jachym Cepicky (Mendel University of Agriculture)
+ Martin Landa
+
+COPYRIGHT: (C) 2006-2007 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.
+
+"""
+
import os
+import sys
+gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" )
+sys.path.append(gmpath)
+import gcmd
+
env={}
class NotInGRASSSession(Exception):
@@ -43,3 +64,13 @@
val = val.replace("'","")
val = val.replace(";","")
env[key] = val
+
+def GetGRASSVariable(var):
+ """Return GRASS variable"""
+ gisEnv = gcmd.Command(['g.gisenv'])
+
+ for item in gisEnv.ReadStdOutput():
+ if var in item:
+ return item.split('=')[1].replace("'",'').replace(';','').strip()
+
+ return ''
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -25,12 +25,11 @@
def GetMenu(self):
return [(
("File", (
- ("Workspace (not functional)", (
- ("New", "Create new workspace file (erase current workspace settings first", "self.OnWorkspaceNew", ""),
+ ("Workspace", (
+ ("New", "Create new workspace file (erase current workspace settings first)", "self.OnWorkspaceNew", ""),
("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
- ("Save as", "Save current workspace as...", "self.OnWorkspaceSave", ""),
-# ("Close", "Close workspace file", "self.OnWorkspaceClose", ""),
+ ("Save as", "Save current workspace as", "self.OnWorkspaceSave", ""),
)),
("","","", ""),
("Import raster map", (
Modified: trunk/grassaddons/gui/gui_modules/menuform.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -80,6 +80,7 @@
imagepath = os.path.join(wxbase,"images")
sys.path.append(imagepath)
+import grassenv
import select
import gcmd
try:
@@ -198,10 +199,19 @@
Find and return a param by name.
"""
for p in self.params:
- if p['name'] == aParam:
+ lparam = len(aParam)
+ if p['name'] == aParam or \
+ p['name'][:lparam] == aParam:
return p
- raise ValueError, "Parameter not found : %s" % aParam
+ raise ValueError, _("Parameter not found : %s") % aParam
+ def set_param(self, aParam, aValue):
+ """
+ Set param value/values.
+ """
+ param = self.get_param(aParam)
+ param['value'] = aValue
+
def get_flag( self, aFlag ):
"""
Find and return a flag by name.
@@ -209,8 +219,16 @@
for f in self.flags:
if f['name'] == aFlag:
return f
- raise ValueError, "Flag not found : %s" % aFlag
+ raise ValueError, _("Flag not found : %s") % aFlag
+ def set_flag(self, aFlag, aValue):
+ """
+ Enable / disable flag.
+ """
+ param = self.get_flag(aFlag)
+ param['value'] = aValue
+
+
def getCmd(self, ignoreErrors = False):
"""
Produce an array of command name and arguments for feeding
@@ -243,7 +261,6 @@
return cmd
-
class processTask(HandlerBase):
"""
A SAX handler for the --interface-description output, as
@@ -260,6 +277,7 @@
self.inGispromptContent = False
self.inGuisection = False
self.inKeywordsContent = False
+ self.inFirstParameter = True
self.task = task_description
def startElement(self, name, attrs):
@@ -377,6 +395,10 @@
"values" : self.param_values,
"value" : ''})
+ if self.inFirstParameter:
+ self.task.firstParam = self.param_name # store name of first parameter
+ self.inFirstParameter = False;
+
if name == 'flag':
self.inFlag = False;
self.task.flags.append({
@@ -636,9 +658,12 @@
if cmd is not None and self.get_dcmd is not None:
# return d.* command to layer tree for rendering
- self.get_dcmd(cmd, self.layer, {"params":self.task.params,"flags":self.task.flags}, self )
+ self.get_dcmd(cmd, self.layer, {"params": self.task.params,
+ "flags" :self.task.flags},
+ self)
# echo d.* command to output console
# self.parent.writeDCommand(cmd)
+
return cmd
def OnRun(self, event):
@@ -1112,16 +1137,20 @@
class GUI:
"""
Parses GRASS commands when module is imported and used
- from wxgui.py
+ from Layer Manager.
"""
def __init__(self, parent=-1):
self.parent = parent
- def ParseCommand(self, cmd, gmpath=None, completed=None, parentframe=-1, modal=False):
+ def ParseCommand(self, cmd, gmpath=None, completed=None, parentframe=-1, show=True, modal=False):
"""
Parse command
- Note: cmd is given as string
+ Note: cmd is given as list
+
+ If command is given with options, return validated cmd list:
+ * add key name for first parameter if not given
+ * change mapname to mapname@mapset
"""
dcmd_params = {}
if completed == None:
@@ -1136,29 +1165,61 @@
if parentframe != -1:
self.parent = parentframe
-
- if ' ' in cmd:
- raise ValueError, _("usage: %s ") % cmd
else:
- # parse the interface decription
- self.grass_task = grassTask()
- handler = processTask(self.grass_task)
- xml.sax.parseString( getInterfaceDescription( cmd ) , handler )
+ self.parent = None
- # if layer parameters previously set, re-insert them into dialog
- if completed is not None:
- if 'params' in dcmd_params:
- self.grass_task.params = dcmd_params['params']
- if 'flags' in dcmd_params:
- self.grass_task.flags = dcmd_params['flags']
+ # parse the interface decription
+ self.grass_task = grassTask()
+ handler = processTask(self.grass_task)
+ xml.sax.parseString( getInterfaceDescription(cmd[0]), handler )
+
+ # if layer parameters previously set, re-insert them into dialog
+ if completed is not None:
+ if 'params' in dcmd_params:
+ self.grass_task.params = dcmd_params['params']
+ if 'flags' in dcmd_params:
+ self.grass_task.flags = dcmd_params['flags']
- self.mf = mainFrame(parent=self.parent, ID=wx.ID_ANY,
- task_description=self.grass_task,
- get_dcmd=get_dcmd, layer=layer)
+ # update parameters if needed && validate command
+ if len(cmd) > 1:
+ i = 0
+ cmd_validated = [cmd[0]]
+ for option in cmd[1:]:
+ if option[0] == '-': # flag
+ self.grass_task.set_flag(option[1], True)
+ cmd_validated.append(option)
+ else: # parameter
+ try:
+ key, value = option.split('=')
+ except:
+ if i == 0: # add key name of first parameter if not given
+ key = self.grass_task.firstParam
+ value = option
+ else:
+ raise ValueError, _("Unable to parse command %s") % ''.join(cmd)
- self.mf.Show(True)
+ if self.grass_task.get_param(key)['element'] in ['cell', 'vector']:
+ # mapname -> mapname@mapset
+ if '@' not in value:
+ value = value + '@' + grassenv.GetGRASSVariable('MAPSET')
+ self.grass_task.set_param(key, value)
+ cmd_validated.append(key + '=' + value)
+ i = i + 1
+
+ # update original command list
+ cmd = cmd_validated
+
+ self.mf = mainFrame(parent=self.parent, ID=wx.ID_ANY,
+ task_description=self.grass_task,
+ get_dcmd=get_dcmd, layer=layer)
+
+ if show:
+ self.mf.Show(show)
self.mf.MakeModal(modal)
+ else:
+ self.mf.OnApply(None)
+ return cmd
class StaticWrapText(wx.StaticText):
"""
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -129,9 +129,6 @@
runcmd = gcmd.Command(cmd=self.cmdlist + ['--q']) # run quiet
if runcmd.returncode != 0:
- print "Could not execute '%s'" % (self.cmdlist)
- for msg in runcmd.msg:
- print msg[1]
self.mapfile = None
self.maskfile = None
return None
@@ -647,7 +644,7 @@
item - gis manager layer tree item
type - layer type
name - layer name
- cmd - GRASS command string
+ cmd - GRASS command given as list
l_active - checked/not checked for display in layer tree
l_hidden - not used here
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -45,39 +45,6 @@
except:
from compat import subprocess
-class AbstractLayer:
- """
- Abstract layer in LayerTree
-
- Attributes:
- * type - layer type ('cmdlayer', 'group', etc) -- see LayerTree.AddLayer()
- """
-
- def __init__(self, type):
- self.type = type
-
-class Layer(AbstractLayer):
- """
- This class represents general item in LayerTree
-
- Attributes:
- * maplayer - reference to MapLayer instance
- * properties - menuform properties (needed for PropertiesDialog)
- """
- def __init__ (self, type, wxCtrl=None):
- AbstractLayer.__init__(self, type)
-
- Debug.msg (3, "Layer.__init__(): type=%s" % \
- type)
-
- self.wxCtrl = wxCtrl
-
- # reference to MapLayer instance
- self.maplayer = None
-
- # properties
- self.properties = None
-
def __del__(self):
Debug.msg (3, "Layer.__del__(): type=%s" % \
self.type)
@@ -114,7 +81,6 @@
self.groupnode = 0 # index value for layers
self.optpage = {} # dictionary of notebook option pages for each map layer
self.layer_selected = None # ID of currently selected layer
- self.layers = {} # dictionary of layers (see Layer class)
self.saveitem = {} # dictionary to preserve layer attributes for drag and drop
self.first = True # indicates if a layer is just added or not
self.drag = False # flag to indicate a drag event is in process
@@ -227,7 +193,7 @@
event.Skip()
return
- ltype = self.layers[self.layer_selected].type
+ ltype = self.GetPyData(self.layer_selected)[0]['type']
Debug.msg (4, "LayerTree.OnContextMenu: layertype=%s" % \
ltype)
@@ -261,7 +227,7 @@
# specific items
try:
- mltype = self.layers[self.layer_selected].maplayer.type
+ mltype = self.GetPyData(self.layer_selected)[0]['type']
except:
mltype = None
# vector specific items
@@ -276,7 +242,7 @@
self.Bind (wx.EVT_MENU, self.OnStartEditing, id=self.popupID5)
self.Bind (wx.EVT_MENU, self.OnStopEditing, id=self.popupID6)
- layer = self.layers[self.layer_selected].maplayer
+ layer = self.GetPyData(self.layer_selected)[0]['maplayer']
# enable editing only for vector map layers available in the current mapset
digit = self.mapdisplay.digittoolbar
if layer.GetMapset() != grassenv.env["MAPSET"]:
@@ -307,7 +273,7 @@
"""
Plot histogram for given raster map layer
"""
- rastName = self.layers[self.layer_selected].maplayer.name
+ rastName = self.GetPyData(self.layer_selected)[0]['maplayer'].name
if not hasattr (self, "histogramFrame"):
self.histogramFrame = None
@@ -332,7 +298,7 @@
Start editing vector map layer requested by the user
"""
try:
- maplayer = self.layers[self.layer_selected].maplayer
+ maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
except:
event.Skip()
return
@@ -350,7 +316,7 @@
Stop editing the current vector map layer
"""
try:
- maplayer = self.layers[self.layer_selected].maplayer
+ maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
except:
event.Skip()
return
@@ -373,9 +339,12 @@
"""Rename layer"""
self.EditLabel(self.layer_selected)
- def AddLayer(self, ltype, lname=None, lchecked=None, lopacity=None, lproperties=None):
+ def AddLayer(self, ltype, lname=None, lchecked=None, lopacity=None, lcmd=None, lgroup=None):
"""Add new item to the layer tree, create corresponding MapLayer instance.
- Launch property dialog if needed (raster, vector, etc.)"""
+ Launch property dialog if needed (raster, vector, etc.)
+
+ Note: lcmd is given as a list
+ """
self.first = True
checked = False
params = {} # no initial options parameters
@@ -408,24 +377,21 @@
self.Bind(wx.EVT_SPINCTRL, self.OnOpacity, ctrl)
# add layer to the layer tree
- if (self.layer_selected and self.layer_selected != self.GetRootItem() and \
- self.layers[self.layer_selected].type != 'group'):
- parent = self.GetItemParent(self.layer_selected)
- layer = self.InsertItem(parent, self.GetPrevSibling(self.layer_selected),
- text='', ct_type=1, wnd=ctrl)
- # add layer to the group
- elif (self.layer_selected and self.layer_selected != self.GetRootItem() and \
- self.layers[self.layer_selected].type == 'group'):
- layer = self.PrependItem(parent=self.layer_selected,
- text='', ct_type=1, wnd=ctrl)
- self.Expand(self.layer_selected)
- # add first layer to the layer tree
- else:
+ if self.layer_selected and self.layer_selected != self.GetRootItem():
+ if self.GetPyData(self.layer_selected)[0]['type'] != 'group':
+ if lgroup is None or lgroup is True:
+ parent = self.GetItemParent(self.layer_selected)
+ else:
+ parent = self.root
+ layer = self.InsertItem(parent, self.GetPrevSibling(self.layer_selected),
+ text='', ct_type=1, wnd=ctrl)
+ else: # group
+ layer = self.PrependItem(parent=self.layer_selected,
+ text='', ct_type=1, wnd=ctrl)
+ self.Expand(self.layer_selected)
+ else: # add first layer to the layer tree
layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
- # create Layer instance & add to self.layers dictionary
- newlayer = self.layers[layer] = Layer(type=ltype, wxCtrl=ctrl)
-
# layer is initially unchecked as inactive (beside 'command')
# use predefined value if given
if lchecked:
@@ -434,6 +400,7 @@
# select item
self.SelectItem(layer)
+ self.layer_selected = layer
# add text and icons for each layer ltype
if ltype == 'raster':
@@ -482,7 +449,11 @@
self.SetItemText(layer, grouptext)
# use predefined layer name if given
- if lname: self.SetItemText(layer, lname)
+ if lname:
+ if ltype != 'command':
+ self.SetItemText(layer, lname)
+ else:
+ ctrl.SetValue(lname)
self.first = False
@@ -491,76 +462,99 @@
opacity = lopacity
else:
opacity = 1.0
- if lproperties:
- cmd = lproperties
+ if lcmd and len(lcmd) > 1:
+ cmd = lcmd
render = True
- name = self.GetLayerNameFromCmd(cmd)
+ name = self.GetLayerNameFromCmd(lcmd)
else:
cmd = []
render = False
name = None
- newlayer.AddMapLayer(self.Map.AddLayer(type=ltype, command=cmd, name=name,
- l_active=checked, l_hidden=False,
- l_opacity=opacity, l_render=render))
- if lproperties:
- self.SetPyData(layer, (cmd,None))
+ # add a data object to hold the layer's command (does not apply to generic command layers)
+ self.SetPyData(layer, ({'cmd': cmd,
+ 'type' : ltype,
+ 'ctrl' : ctrl,
+ 'maplayer' : None,
+ 'prowin' : None},
+ None))
+
+ maplayer = self.Map.AddLayer(type=ltype, command=self.GetPyData(layer)[0]['cmd'], name=name,
+ l_active=checked, l_hidden=False,
+ l_opacity=opacity, l_render=render)
+ self.GetPyData(layer)[0]['maplayer'] = maplayer
+
+ # run properties dialog if no properties given
+ if len(cmd) > 1:
+ self.PropertiesDialog(layer, show=False)
else:
- # add a data object to hold the layer's command (does not apply to generic command layers)
- self.SetPyData(layer, (None,None))
- # run properties dialog if no properties given
- self.PropertiesDialog(layer)
+ self.PropertiesDialog(layer, show=True)
- def PropertiesDialog (self, layer):
+ else: # group
+ self.SetPyData(layer, ({'cmd': None,
+ 'type' : ltype,
+ 'ctrl' : None,
+ 'maplayer' : None,
+ 'prowin' : None},
+ None))
+
+ return layer
+
+ def PropertiesDialog (self, layer, show=True):
"""Launch the properties dialog"""
global gmpath
completed = ''
params = self.GetPyData(layer)[1]
- ltype = self.layers[layer].type
+ ltype = self.GetPyData(layer)[0]['type']
Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \
ltype)
- if ltype == 'raster':
- menuform.GUI().ParseCommand('d.rast', completed=(self.GetOptData,layer,params),
+ if self.GetPyData(layer)[0]['cmd']:
+ cmdValidated = menuform.GUI().ParseCommand(self.GetPyData(layer)[0]['cmd'],
+ completed=(self.GetOptData,layer,params),
+ parentframe=self, show=show)
+ self.GetPyData(layer)[0]['cmd'] = cmdValidated
+ elif ltype == 'raster':
+ menuform.GUI().ParseCommand(['d.rast'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rgb':
- menuform.GUI().ParseCommand('d.rgb', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.rgb'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'his':
- menuform.GUI().ParseCommand('d.his', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.his'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'shaded':
- menuform.GUI().ParseCommand('d.shadedmap', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.shadedmap'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rastarrow':
- menuform.GUI().ParseCommand('d.rast.arrow', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.rast.arrow'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rastnum':
- menuform.GUI().ParseCommand('d.rast.num', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.rast.num'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'vector':
- menuform.GUI().ParseCommand('d.vect', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.vect'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'thememap':
- menuform.GUI().ParseCommand('d.vect.thematic',
+ menuform.GUI().ParseCommand(['d.vect.thematic'],
completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'themechart':
- menuform.GUI().ParseCommand('d.vect.chart',
+ menuform.GUI().ParseCommand(['d.vect.chart'],
completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'grid':
- menuform.GUI().ParseCommand('d.grid', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.grid'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'geodesic':
- menuform.GUI().ParseCommand('d.geodesic', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.geodesic'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'rhumb':
- menuform.GUI().ParseCommand('d.rhumbline', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.rhumbline'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'labels':
- menuform.GUI().ParseCommand('d.labels', completed=(self.GetOptData,layer,params),
+ menuform.GUI().ParseCommand(['d.labels'], completed=(self.GetOptData,layer,params),
parentframe=self)
elif ltype == 'cmdlayer':
pass
@@ -576,7 +570,7 @@
self.PropertiesDialog (layer)
- if self.layers[layer].type == 'group':
+ if self.GetPyData(layer)[0]['type'] == 'group':
if self.IsExpanded(layer):
self.Collapse(layer)
else:
@@ -603,11 +597,8 @@
self.layer_selected = None
try:
- layer = self.layers[item]
- if layer.type != 'group':
- self.Map.DeleteLayer(layer.maplayer)
-
- self.layers.pop(item)
+ if self.GetPyData(item)[0]['type'] != 'group':
+ self.Map.DeleteLayer( self.GetPyData(item)[0]['maplayer'])
except:
pass
@@ -624,11 +615,10 @@
"""Enable/disable given layer item"""
item = event.GetItem()
checked = item.IsChecked()
- layer = self.layers[item]
-
+
if self.drag == False and self.first == False:
# change active parameter for item in layers list in render.Map
- if layer.type == 'group':
+ if self.GetPyData(item)[0]['type'] == 'group':
childitem = self.GetFirstChild(item)
child = childitem[0]
cookie = childitem[1]
@@ -637,10 +627,10 @@
childchecked = False
else:
childchecked = child.IsChecked()
- self.Map.ChangeLayerActive(self.layers[child].maplayer, childchecked)
+ self.Map.ChangeLayerActive(self.GetPyData(child)[0]['maplayer'], childchecked)
child = self.GetNextChild(item, cookie)[0]
else:
- self.Map.ChangeLayerActive(self.layers[item].maplayer, checked)
+ self.Map.ChangeLayerActive(self.GetPyData(item)[0]['maplayer'], checked)
# redraw map if auto-rendering is enabled
if self.mapdisplay.autoRender.GetValue():
@@ -650,20 +640,28 @@
"""Change command string"""
ctrl = event.GetEventObject()
cmd = event.GetString()
+ layer = None
- layer = item = None
+ vislayer = self.GetFirstVisibleItem()
- for item, layer in self.layers.iteritems():
- if layer.wxCtrl == ctrl:
+ for item in range(0, self.GetCount()):
+ if self.GetPyData(vislayer)[0]['ctrl'] == ctrl:
+ layer = vislayer
+
+ if not self.GetNextVisible(vislayer):
break
+ else:
+ vislayer = self.GetNextVisible(vislayer)
# change parameters for item in layers list in render.Map
- if item and self.drag == False:
- self.ChangeLayer(item)
- for option in layer.maplayer.GetCmd():
+ if layer and self.drag == False:
+ self.ChangeLayer(layer)
+ self.GetPyData(layer)[0]['cmd'] = cmd.split(' ')
+ maplayer = self.GetPyData(layer)[0]['maplayer']
+ for option in maplayer.GetCmd():
if 'map=' in option:
mapname = option.split('=')[1]
- self.Map.ChangeLayerName(layer.maplayer, mapname)
+ self.Map.ChangeLayerName(maplayer, mapname)
event.Skip()
@@ -675,10 +673,22 @@
ctrl = event.GetEventObject()
maplayer = None
- for layer in self.layers.itervalues():
- if layer.wxCtrl == ctrl:
- maplayer = layer.maplayer
+ vislayer = self.GetFirstVisibleItem()
+
+ layer = None
+ for item in range(0, self.GetCount()):
+ if self.GetPyData(vislayer)[0]['ctrl'] == ctrl:
+ layer = vislayer
+
+ if not self.GetNextVisible(vislayer):
+ break
+ else:
+ vislayer = self.GetNextVisible(vislayer)
+
+ if layer:
+ maplayer = self.GetPyData(layer)[0]['maplayer']
+
opacity = event.GetInt() / 100.
# change opacity parameter for item in layers list in render.Map
if maplayer and self.drag == False:
@@ -702,7 +712,7 @@
"""
Collapse node
"""
- if self.layers[self.layer_selected].type == 'group':
+ if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
self.SetItemImage(self.layer_selected, self.folder)
def OnExpandNode(self, event):
@@ -710,7 +720,7 @@
Expand node
"""
self.layer_selected = event.GetItem()
- if self.layers[self.layer_selected].type == 'group':
+ if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
self.SetItemImage(self.layer_selected, self.folder_open)
def OnBeginDrag(self, event):
@@ -733,29 +743,27 @@
"""
Recreate item (needed for OnEndDrag())
"""
- oldLayer = self.layers[oldItem]
-
Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
self.GetItemText(oldItem))
# recreate spin/text control for layer
- if oldLayer.type == 'command':
+ if self.GetPyData(oldItem)[0]['type'] == 'command':
newctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
pos=wx.DefaultPosition, size=(250,25),
style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
try:
- newctrl.SetValue(oldLayer.maplayer.GetCmd(string=True))
+ newctrl.SetValue(self.GetPyData(oldItem)[0]['maplayer'].GetCmd(string=True))
except:
pass
newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
newctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
- elif oldLayer.type == 'group':
+ elif self.GetPyData(oldItem)[0]['type'] == 'group':
newctrl = None
else:
newctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50),
style=wx.SP_ARROW_KEYS, min=0, max=100)
try:
- newctrl.SetValue(oldLayer.maplayer.GetOpacity())
+ newctrl.SetValue(self.GetPyData(oldItem)[0]['maplayer'].GetOpacity())
except:
newctrl.SetValue(100)
self.Bind(wx.EVT_SPINCTRL, self.OnOpacity, newctrl)
@@ -771,7 +779,7 @@
image = self.GetItemImage(oldItem, 0)
wind = self.GetItemWindow(oldItem)
checked = self.IsItemChecked(oldItem)
- if oldLayer.type == 'group':
+ if self.GetPyData(oldItem)[0]['type'] == 'group':
windval = None
data = None
else:
@@ -780,12 +788,12 @@
# create GenericTreeItem instance
if flag & wx.TREE_HITTEST_ABOVE:
- new = self.PrependItem(self.root, text=text, \
+ newItem = self.PrependItem(self.root, text=text, \
ct_type=1, wnd=newctrl, image=image, \
data=data)
elif (flag & wx.TREE_HITTEST_BELOW) or (flag & wx.TREE_HITTEST_NOWHERE) \
or (flag & wx.TREE_HITTEST_TOLEFT) or (flag & wx.TREE_HITTEST_TORIGHT):
- new = self.AppendItem(self.root, text=text, \
+ newItem = self.AppendItem(self.root, text=text, \
ct_type=1, wnd=newctrl, image=image, \
data=data)
else:
@@ -794,27 +802,27 @@
else:
afteritem = event.GetItem()
- if self.layers[afteritem].type == 'group':
+ if self.GetPyData(afteritem)[0]['type'] == 'group':
parent = afteritem
- new = self.AppendItem(parent, text=text, \
+ newItem = self.AppendItem(parent, text=text, \
ct_type=1, wnd=newctrl, image=image, \
data=data)
self.Expand(afteritem)
else:
parent = self.GetItemParent(afteritem)
- new = self.InsertItem(parent, afteritem, text=text, \
+ newItem = self.InsertItem(parent, afteritem, text=text, \
ct_type=1, wnd=newctrl, image=image, \
data=data)
# add layer at new position
- self.layers[new] = self.layers[oldItem]
- self.layers[new].wxCtrl = newctrl
+ self.SetPyData(newItem, self.GetPyData(oldItem))
+ self.GetPyData(newItem)[0]['ctrl'] = newctrl
- self.CheckItem(new, checked=checked)
+ self.CheckItem(newItem, checked=checked)
event.Skip()
- return new
+ return newItem
def OnEndDrag(self, event):
"""
@@ -831,10 +839,9 @@
Debug.msg (4, "LayerTree.OnEndDrag(): layer=%s" % \
(self.GetItemText(self.dragItem)))
- # recreate item and update self.layers dictionary
newItem = self.RecreateItem (event, self.dragItem)
- if self.layers[newItem].type == 'group':
+ if self.GetPyData(newItem)[0]['type'] == 'group':
(child, cookei) = self.GetFirstChild(self.dragItem)
if child:
while child:
@@ -846,11 +853,13 @@
# delete layer at original position
self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
- # self.layers.pop(old)
# reorder layers in render.Map to match new order after drag and drop
self.ReorderLayers()
+ # select new item
+ self.SelectItem(newItem)
+
# completed drag and drop
self.drag = False
@@ -875,6 +884,9 @@
elif 'labels=' in item:
mapname = item.split('=')[1]+' labels'
+ if mapname != '':
+ break
+
return mapname
def GetOptData(self, dcmd, layer, params, propwin):
@@ -884,8 +896,9 @@
mapname = self.GetLayerNameFromCmd(dcmd)
self.SetItemText(layer, mapname)
- # add command to layer's data
- self.SetPyData(layer, (dcmd,params))
+ # update layer data
+ self.SetPyData(layer, (self.GetPyData(layer)[0], params))
+ self.GetPyData(layer)[0]['propwin'] = propwin
# check layer as active
self.CheckItem(layer, checked=True)
@@ -893,10 +906,6 @@
# change parameters for item in layers list in render.Map
self.ChangeLayer(layer)
- # set the layer properties dialog dictionary entry
- self.layers[layer].AddProperties (propwin)
-
-
def ReorderLayers(self):
"""Add commands from data associated with
any valid layers (checked or not) to layer list in order to
@@ -904,14 +913,18 @@
# make a list of visible layers
treelayers = []
+
vislayer = self.GetFirstVisibleItem()
+
if not vislayer:
return
+
itemList = ""
+
for item in range(0, self.GetCount()):
itemList += self.GetItemText(vislayer) + ','
- if self.layers[vislayer].type != 'group':
- treelayers.append(self.layers[vislayer].maplayer)
+ if self.GetPyData(vislayer)[0]['type'] != 'group':
+ treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
if not self.GetNextVisible(vislayer):
break
@@ -927,24 +940,28 @@
def ChangeLayer(self, item):
"""Change layer"""
- layer = self.layers[item]
- if layer.type == 'command':
+ type = self.GetPyData(item)[0]['type']
+
+ if type == 'command':
if self.GetItemWindow(item).GetValue() != None:
cmdlist = self.GetItemWindow(item).GetValue().split(' ')
opac = 1.0
chk = self.IsItemChecked(item)
hidden = not self.IsVisible(item)
- elif layer.type != 'group':
+ elif type != 'group':
if self.GetPyData(item)[0] != None:
- cmdlist = self.GetPyData(item)[0]
+ cmdlist = self.GetPyData(item)[0]['cmd']
opac = float(self.GetItemWindow(item).GetValue())/100
chk = self.IsItemChecked(item)
hidden = not self.IsVisible(item)
- layer.maplayer = self.Map.ChangeLayer(layer=layer.maplayer, type=layer.maplayer.type, command=cmdlist, name=self.GetItemText(item),
- l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
+ maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
+ command=cmdlist, name=self.GetItemText(item),
+ l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
+ self.GetPyData(item)[0]['maplayer'] = maplayer
+
# if digitization tool enabled -> update list of available vector map layers
if self.mapdisplay.digittoolbar:
self.mapdisplay.digittoolbar.UpdateListOfLayers(updateTool=True)
@@ -1056,14 +1073,14 @@
try:
# if command is not already a list, make it one
- cmdlist = command.split(' ')
+ cmdlist = command.strip().split(' ')
except:
cmdlist = command
- if len(cmdlist) == 1 and cmdlist[0] in gcmdlst:
+ if cmdlist[0] in gcmdlst:
# send GRASS command without arguments to GUI command interface
# except display commands (they are handled differently)
- if command[0:2] == "d.":
+ if cmdlist[0][0:2] == "d.":
try:
layertype = {'d.rast' : 'raster',
'd.rgb' : 'rgb',
@@ -1078,40 +1095,21 @@
'd.grid' : 'grid',
'd.geodesic' : 'geodesic',
'd.rhumbline' : 'rhumb',
- 'd.labels' : 'labels'}[command]
+ 'd.labels' : 'labels'}[cmdlist[0]]
except KeyError:
print _('Command type not yet implemented')
return False
# add layer
- self.parent.curr_page.maptree.AddLayer(layertype)
+ self.parent.curr_page.maptree.AddLayer(ltype=layertype,
+ lcmd=cmdlist)
else:
- menuform.GUI().ParseCommand(string.join(cmdlist), parentframe=None)
- #self.cmd_output.write(string.join(cmdlist) + "\n----------\n")
+ if len(cmdlist) > 1:
+ menuform.GUI().ParseCommand(cmdlist, parentframe=self, show=False)
+ else:
+ menuform.GUI().ParseCommand(cmdlist, parentframe=self, show=True)
- elif command[0:2] == "d." and len(cmdlist) > 1:
- # Send GRASS display command(s)with arguments
- # to the display processor and echo to command output console.
- # Accepts a list of d.* commands separated by semi-colons.
- # Display with focus receives display command(s).
-
- self.cmd_output.write("$" + ' '.join(cmdlist))
-
- dcmds = command.split(';')
- for command in dcmds:
- try:
- # only add the display command to the rendering list if it has arguments
- cmdlist = command.strip().split(' ')
- if cmdlist[0] in gcmdlst and len(cmdlist) > 1:
- self.Map.AddLayer(type='command', command=cmdlist,
- l_active=True, l_hidden=False, l_opacity=1, l_render=False)
- except:
- pass
-
- curr_disp.MapWindow.UpdateMap()
-
-
else:
# Send any other command to the shell. Send output to
# console output window.
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-16 19:52:16 UTC (rev 1138)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-17 20:39:08 UTC (rev 1139)
@@ -148,7 +148,7 @@
toolbar = self.__createToolBar()
#self.panel = wx.Panel(self,-1, style= wx.EXPAND)
self.sizer= wx.BoxSizer(wx.VERTICAL)
-# self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL)
+ # self.cmdsizer = wx.BoxSizer(wx.HORIZONTAL)
# do layout
self.SetTitle(_("GRASS GIS Layer Manager"))
@@ -159,13 +159,14 @@
os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE"
# initialize variables
- self.mapdisplays = {} #dictionary to index open map displays
- self.disp_idx = 0 #index value for map displays and layer trees
- self.maptree = {} #dictionary to index a layer tree to accompanying a map display
- self.mapfocus = 0 #track which display currently has focus
- self.curr_page = '' # currently selected page for layer tree notebook
- self.curr_pagenum = '' # currently selected page number for layer tree notebook
+ self.mapdisplays = {} # dictionary to index open map displays
+ self.disp_idx = 0 # index value for map displays and layer trees
+ self.maptree = {} # dictionary to index a layer tree to accompanying a map display
+ self.mapfocus = 0 # track which display currently has focus
+ self.curr_page = '' # currently selected page for layer tree notebook
+ self.curr_pagenum = '' # currently selected page number for layer tree notebook
self.encoding = 'ISO-8859-1' # default encoding for display fonts
+ self.workspaceFile = None # workspace file
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
self.Bind(wx.EVT_LEFT_DOWN, self.AddRaster)
@@ -371,19 +372,25 @@
self.goutput.RunCmd(cmd)
def GetMenuCmd(self, event):
+ """Get GRASS command from menu item
+
+
+ Return command as a list"""
menuitem = self.menubar.FindItemById(event.GetId())
itemtext = menuitem.GetText()
cmd = menucmd[itemtext]
- return cmd
+ cmdlist = cmd.split(' ')
+ return cmdlist
+
def RunMenuCmd(self, event):
+ """Run command selected from menu"""
cmd = self.GetMenuCmd(event)
self.goutput.RunCmd(cmd)
def OnMenuCmd(self, event):
- """Run menu command"""
+ """Parse command selected from menu"""
cmd = self.GetMenuCmd(event)
- global gmpath
menuform.GUI().ParseCommand(cmd, parentframe=self)
def OnAboutGRASS(self, event):
@@ -419,10 +426,22 @@
Erase current workspace settings first"""
- # TODO: ask user to save current settings
+ maptree = self.curr_page.maptree
- maptree = self.curr_page.maptree
+ # ask user to save current settings
+ if maptree.GetCount() > 0:
+ dlg = wx.MessageDialog(self, message=_("Workspace is not empty. "
+ "Do you want to store current settings "
+ "to workspace file?"),
+ caption=_("Save current settings?"),
+ style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_OK:
+ self.OnWorkspaceSave(None)
+ dlg.Destroy()
+
+ # delete all items
maptree.DeleteAllItems()
+
# add new root element
maptree.root = maptree.AddRoot("Map Layers")
self.curr_page.maptree.SetPyData(maptree.root, (None,None))
@@ -440,6 +459,8 @@
self.LoadGrcXmlToLayerTree(filename)
+ self.workspaceFile = filename
+
def LoadGrcXmlToLayerTree(self, filename):
"""Load layer tree definition stored in GRC XML file
@@ -471,28 +492,29 @@
self.OnWorkspaceNew(None)
# read file and fix patch to dtd
-
+# try:
file = open(filename, "r")
fileStream = ''.join(file.readlines())
p = re.compile( '(grass-grc.dtd)')
p.search(fileStream)
fileStream = p.sub(dtdFilename, fileStream)
-
- # sax
+
+ # sax
grcXml = ProcessGrcXml()
xml.sax.parseString(fileStream, grcXml)
-
maptree = self.curr_page.maptree
for layer in grcXml.layers:
newItem = maptree.AddLayer(ltype=layer['type'],
- lname=layer['name'],
- lchecked=layer['checked'],
- lopacity=layer['opacity'],
- lproperties=layer['cmd'])
-
+ lname=layer['name'],
+ lchecked=layer['checked'],
+ lopacity=layer['opacity'],
+ lcmd=layer['cmd'],
+ lgroup=layer['group'])
+ maptree.PropertiesDialog(newItem, show=False)
+
file.close()
-# except:
+ # except:
# dlg = wx.MessageDialog(self, _("Unable to read workspace file <%s>.") % filename,
# _("Error"), wx.OK | wx.ICON_ERROR)
# dlg.ShowModal()
@@ -500,13 +522,10 @@
# return False
return True
-
- def OnWorkspaceSave(self, event):
- """Save file with workspace definition
- Return True on success
- Return False on error"""
-
+ def OnWorkspaceSaveAs(self, event):
+ """Save workspace definition to selected file"""
+
dlg = wx.FileDialog(parent=self, message=_("Choose file to save current workspace"),
defaultDir=os.getcwd(), wildcard="*.grc", style=wx.FD_SAVE)
@@ -521,15 +540,73 @@
if filename[-4:] != ".grc":
filename += ".grc"
- # TODO: overwrite / save as...
+ if os.path.exists(filename):
+ dlg = wx.MessageDialog(self, message=_("Workspace file <%s> already exists. "
+ "Do you want to overwrite this file?") % filename,
+ caption=_("File exits"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
+ if dlg.ShowModal() != wx.ID_OK:
+ dlg.Destroy()
+ return False
+
+ Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
- Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % filename)
-
self.SaveLayerTreeToGrcXml(filename)
+
+ def OnWorkspaceSave(self, event):
+ """Save file with workspace definition"""
+ if self.workspaceFile:
+ Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
+ self.SaveLayerTreeToGrcXml(self.workspaceFile)
+ else:
+ self.OnWorkspaceSaveAs(None)
+
+ def WriteLayersToGrcXml(self, file, mapTree, item):
+ """Write bunch of layers to GRC XML file"""
+ while item and item.IsOk():
+ type = mapTree.GetPyData(item)[0]['type']
+ if type != 'group':
+ maplayer = mapTree.GetPyData(item)[0]['maplayer']
+ else:
+ maplayer = None
+
+ checked = int(item.IsChecked())
+ cmd = mapTree.GetPyData(item)[0]['cmd']
+ if type == 'command':
+ file.write(' \n' % \
+ (type, ' '.join(cmd), checked));
+ elif type == 'group':
+ name = mapTree.GetItemText(item)
+ file.write(' \n' % \
+ (name, checked));
+ subItem = mapTree.GetFirstChild(item)[0]
+ self.WriteLayersToGrcXml(file, mapTree, subItem)
+ file.write(' \n');
+ else:
+ name = mapTree.GetItemText(item)
+ opacity = maplayer.GetOpacity(float=True)
+ file.write(' \n' % \
+ (type, name, checked, opacity));
+ # layer properties
+ file.write(' \n' % cmd[0])
+ for option in cmd[1:]:
+ if option[0] == '-': # flag
+ file.write(' \n' % option[1])
+ else: # parameter
+ key, value = option.split('=')
+ file.write(' \n' % key)
+ file.write(' %s\n' % value)
+ file.write(' \n');
+ file.write(' \n');
+ file.write(' \n');
+ item = mapTree.GetNextSibling(item)
+
def SaveLayerTreeToGrcXml(self, filename):
- """Save layer tree layout to workspace file"""
+ """Save layer tree layout to workspace file
+ Return True on success, False on error
+ """
+
try:
file = open(filename, "w")
except IOError:
@@ -546,39 +623,20 @@
file.write('\n')
# list of layers
mapTree = self.curr_page.maptree
- root = mapTree.GetRootItem()
- childitem = mapTree.GetFirstChild(root)
- item = childitem[0]
- cookie = childitem[1]
- for n in range(0, mapTree.GetChildrenCount(root)):
- layer = mapTree.layers[item]
- type = layer.type
- name = mapTree.GetItemText(item)
- checked = int(item.IsChecked())
- opacity = layer.maplayer.GetOpacity(float=True)
- file.write(' \n' % \
- (type, name, checked, opacity));
- # layer properties
- cmd = mapTree.GetPyData(item)[0]
- file.write(' \n' % cmd[0])
- for option in cmd[1:]:
- if option[0] == '-': # flag
- file.write(' \n' % option[1])
- else: # parameter
- key, value = option.split('=')
- file.write(' \n' % key)
- file.write(' %s\n' % value)
- file.write(' \n');
- file.write(' \n');
- file.write(' \n');
- item = mapTree.GetNextChild(item, cookie)[0]
+ item = mapTree.GetFirstChild(mapTree.root)[0]
+ self.WriteLayersToGrcXml(file, mapTree, item)
file.write('\n')
- finally:
- file.close()
- return True
+ except:
+ dlg = wx.MessageDialog(self, _("Writing current settings to workspace file failed."),
+ _("Error"), wx.OK | wx.ICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
- return False
+ file.close()
+ return True
+
def OnWorkspaceClose(self, event):
"""Close file with workspace definition
@@ -751,7 +809,7 @@
# available only for vector map layers
try:
- maptype = self.curr_page.maptree.layers[layer].maplayer.type
+ maptype = self.curr_page.maptree.GetPyData(layer)['maplayer'].type
except:
maptype = None
if not maptype or maptype != 'vector':
@@ -1015,7 +1073,7 @@
dlg.Destroy()
for layer in self.curr_page.maptree.GetSelections():
- if self.curr_page.maptree.layers[layer].type == 'group':
+ if self.curr_page.maptree.GetPyData(layer)[0]['type'] == 'group':
self.curr_page.maptree.DeleteChildren(layer)
self.curr_page.maptree.Delete(layer)
@@ -1156,6 +1214,7 @@
self.inParameter = False
self.inFlag = False
self.inValue = False
+ self.inGroup = False
# list of layers
self.layers = []
@@ -1164,13 +1223,26 @@
def startElement(self, name, attrs):
if name == 'grc':
self.inGrc = True
-
+
+ elif name == 'group':
+ self.inGroup = True
+ self.groupName = attrs.get('name', None)
+ self.groupChecked = attrs.get('checked', None)
+ self.layers.append({
+ "type" : 'group',
+ "name" : self.groupName,
+ "checked" : int(self.groupChecked),
+ "opacity" : None,
+ "cmd" : None,
+ "group" : None})
+
elif name == 'layer':
self.inLayer = True
self.layerType = attrs.get('type', None)
self.layerName = attrs.get('name', None)
self.layerChecked = attrs.get('checked', None)
self.layerOpacity = attrs.get('opacity', None)
+ self.cmd = []
elif name == 'task':
self.inTask = True;
@@ -1194,15 +1266,24 @@
if name == 'grc':
self.inGrc = False
+ elif name == 'group':
+ self.inGroup = False
+ self.groupName = self.groupChecked = None
+
elif name == 'layer':
self.inLayer = False
self.layers.append({
"type" : self.layerType,
"name" : self.layerName,
"checked" : int(self.layerChecked),
- "opacity" : float(self.layerOpacity),
- "cmd" : self.cmd})
-
+ "opacity" : None,
+ "cmd" : None,
+ "group" : self.inGroup})
+ if self.layerOpacity:
+ self.layers[-1]["opacity"] = float(self.layerOpacity)
+ if self.cmd:
+ self.layers[-1]["cmd"] = self.cmd
+
self.layerType = self.layerName = self.Checked = \
self.Opacity = self.cmd = None
@@ -1230,7 +1311,7 @@
def reexec_with_pythonw():
if sys.platform == 'darwin' and\
not sys.executable.endswith('MacOS/Python'):
- print >>sys.stderr,'re-executing using pythonw'
+ print >> sys.stderr, _('re-executing using pythonw')
os.execvp('pythonw',['pythonw',__file__] + sys.argv[1:])
if __name__ == "__main__":
From landa at grass.itc.it Thu Oct 18 16:49:34 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 18 16:49:35 2007
Subject: [grass-addons] r1140 - in trunk/grassaddons/gui: . gui_modules icons
Message-ID: <200710181449.l9IEnYid031850@grass.itc.it>
Author: landa
Date: 2007-10-18 16:49:05 +0200 (Thu, 18 Oct 2007)
New Revision: 1140
Modified:
trunk/grassaddons/gui/README
trunk/grassaddons/gui/gui_modules/dbm.py
trunk/grassaddons/gui/gui_modules/debug.py
trunk/grassaddons/gui/gui_modules/georect.py
trunk/grassaddons/gui/gui_modules/grassenv.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/sqlbuilder.py
trunk/grassaddons/gui/gui_modules/toolbars.py
trunk/grassaddons/gui/gui_modules/utils.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/icons/icon.py
Log:
Bugfix in wxgui_utils.GetOptData().
Use environment variable GRASS_WX_DEBUG instead of GRASS variable DEBUG.
Cleaning of grassenv module.
Modified: trunk/grassaddons/gui/README
===================================================================
--- trunk/grassaddons/gui/README 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/README 2007-10-18 14:49:05 UTC (rev 1140)
@@ -121,19 +121,11 @@
5 - DEBUGGING
-To enable debugging messages use "GRASS standard way", e.g.
+To enable GUI debugging messages on given level set GRASS_DEBUG_WX
+environment variables, e.g.
-$ g.gisenv set=DEBUG=3
+$ export GRASS_WX_DEBUG=3
-This enables all debug messages (GRASS modules + GUI). GUI debug
-messages starts with 'GUI', e.g.
-
- GUI D1/1: MapFrame.__init__()
-
-If you want to enable *only* GUI debug messages set DEBUG variable to 'GUI:level', e.g.
-
-$ g.gisenv set=DEBUG=GUI:3
-
6 - ICON THEMES
Currently only two icon themes are available:
Modified: trunk/grassaddons/gui/gui_modules/dbm.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/dbm.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -61,7 +61,7 @@
self.vectmap = vectmap
if not "@" in self.vectmap:
- self.vectmap = self.vectmap+"@"+grassenv.env["MAPSET"]
+ self.vectmap = self.vectmap + "@" + grassenv.GetGRASSVariable("MAPSET")
self.mapname, self.mapset = self.vectmap.split("@")
self.icon = ''
Modified: trunk/grassaddons/gui/gui_modules/debug.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/debug.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/debug.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -18,14 +18,18 @@
for details.
"""
-import grassenv
+import os
+import sys
+gmpath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
+sys.path.append(gmpath)
+
class DebugMsg:
"""
GRASS Debugging
Usage:
- import cmd
+ import cmd
cmd.Command (cmd=["g.gisenv", "set=DEBUG=3"]) # only GUI debug messages DEBUG=GUI:3
@@ -41,8 +45,8 @@
self._update_level()
def _update_level(self):
- if grassenv.env.has_key ("DEBUG"):
- debug = grassenv.env["DEBUG"].strip()
+ debug = os.getenv("GRASS_WX_DEBUG")
+ if debug is not None:
try:
# only GUI debug messages [GUI:level]
level = int (debug[-1])
@@ -64,7 +68,6 @@
if __name__ == "__main__":
import gcmd
gcmd.Command (cmd=["g.gisenv", "set=DEBUG=3"])
- reload (grassenv) # reload GRASS environments !
for level in range (4):
Debug.msg (level, "message level=%d" % level)
Modified: trunk/grassaddons/gui/gui_modules/georect.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/georect.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/georect.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -58,7 +58,6 @@
import mapdisp
import render
import toolbars
-import grassenv
import menuform
import select
import disp_print
Modified: trunk/grassaddons/gui/gui_modules/grassenv.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -17,56 +17,12 @@
import os
import sys
-gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" )
+gmpath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
sys.path.append(gmpath)
import gcmd
-env={}
-
-class NotInGRASSSession(Exception):
- def __str__(self):
- return "You must be in running GRASS session"
-
-class CouldNotStartMonitor(Exception):
- def __init__(self,monitor):
- self.monitor = monitor
-
- def __str__(self):
- return "Could not start GRASS monitor <%s>" % self.monitor
-
-class CouldNotStopMonitor(Exception):
- def __init__(self,monitor):
- self.monitor = monitor
-
- def __str__(self):
- return "Could not start GRASS monitor <%s>" % self.monitor
-
-class CouldNotExecute(Exception):
- def __init__(self,command):
- self.command = command
- def __str__(self):
- return "Could not execute GRASS command: %s" % self.command
-
-
-if not os.getenv("GISBASE"):
- raise NotInGRASSSession()
-else:
- env["GISBASE"] = os.getenv("GISBASE")
- env["GIS_LOCK"] = os.getenv("GIS_LOCK")
- env["GISRC"] = os.getenv("GISRC")
-
-for key in os.environ.keys():
- if key.find("GRASS") > -1:
- env[key] = os.getenv(key)
-
-for line in os.popen("g.gisenv").readlines():
- key,val = line.strip().split("=")
- val = val.replace("'","")
- val = val.replace(";","")
- env[key] = val
-
def GetGRASSVariable(var):
- """Return GRASS variable"""
+ """Return GRASS variable or '' if variable is not defined"""
gisEnv = gcmd.Command(['g.gisenv'])
for item in gisEnv.ReadStdOutput():
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -3201,11 +3201,12 @@
gm_map = MapApp(0)
# set title
- gm_map.mapFrm.SetTitle ("GRASS GIS - Map Display: " + title + " - Location: " + grassenv.env["LOCATION_NAME"])
+ gm_map.mapFrm.SetTitle ("GRASS GIS - Map Display: " + title + " - Location: " + \
+ grassenv.GetGRASSVariable("LOCATION_NAME"))
gm_map.MainLoop()
if grassenv.env.has_key("MONITOR"):
- os.system("d.mon sel=%s" % grassenv.env["MONITOR"])
+ os.system("d.mon sel=%s" % grassenv.GetGRASSVariable("MONITOR"))
os.remove(cmdfilename)
os.system("""g.gisenv set="GRASS_PYCMDFILE" """)
Modified: trunk/grassaddons/gui/gui_modules/sqlbuilder.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/sqlbuilder.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -28,7 +28,7 @@
self.vectmap = vectmap
print self.vectmap
if not "@" in self.vectmap:
- self.vectmap = self.vectmap+"@"+grassenv.env["MAPSET"]
+ self.vectmap = self.vectmap + "@" + grassenv.GetGRASSVariable ("MAPSET")
self.mapname, self.mapset = self.vectmap.split("@")
self.layer,self.tablename, self.column, self.database, self.driver =\
os.popen("v.db.connect -g map=%s" %\
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -628,7 +628,8 @@
# select vector map layer in the current mapset
layerNameList = []
- self.layers = self.mapcontent.GetListOfLayers(l_type="vector", l_mapset=grassenv.env["MAPSET"])
+ self.layers = self.mapcontent.GetListOfLayers(l_type="vector",
+ l_mapset=grassenv.GetGRASSVariable('MAPSET'))
for layer in self.layers:
if not layer.name in layerNameList: # do not duplicate layer
layerNameList.append (layer.name)
Modified: trunk/grassaddons/gui/gui_modules/utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/utils.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/utils.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -41,3 +41,14 @@
return os.path.join(path, file)
except:
return Node
+
+def GetGRASSVariable(var):
+ """Return GRASS environment variable"""
+
+ gisEnv = gcmd.Command(['g.gisenv'])
+
+ for item in gisEnv.ReadStdOutput():
+ if var in item:
+ return item.split('=')[1].replace("'",'').replace(';','').strip()
+
+ return ''
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -101,7 +101,7 @@
# title
self.mapdisplay.SetTitle(_("GRASS GIS - Map Display: " + \
str(self.disp_idx) + \
- " - Location: " + grassenv.env["LOCATION_NAME"]))
+ " - Location: " + grassenv.GetGRASSVariable("LOCATION_NAME")))
#show new display
self.mapdisplay.Show()
@@ -245,7 +245,7 @@
layer = self.GetPyData(self.layer_selected)[0]['maplayer']
# enable editing only for vector map layers available in the current mapset
digit = self.mapdisplay.digittoolbar
- if layer.GetMapset() != grassenv.env["MAPSET"]:
+ if layer.GetMapset() != grassenv.GetGRASSVariable("MAPSET"):
# only vector map in current mapset can be edited
self.popupMenu.Enable (self.popupID5, False)
self.popupMenu.Enable (self.popupID6, False)
@@ -898,6 +898,7 @@
# update layer data
self.SetPyData(layer, (self.GetPyData(layer)[0], params))
+ self.GetPyData(layer)[0]['cmd'] = dcmd
self.GetPyData(layer)[0]['propwin'] = propwin
# check layer as active
@@ -950,12 +951,11 @@
chk = self.IsItemChecked(item)
hidden = not self.IsVisible(item)
elif type != 'group':
- if self.GetPyData(item)[0] != None:
+ if self.GetPyData(item)[0] is not None:
cmdlist = self.GetPyData(item)[0]['cmd']
opac = float(self.GetItemWindow(item).GetValue())/100
chk = self.IsItemChecked(item)
hidden = not self.IsVisible(item)
-
maplayer = self.Map.ChangeLayer(layer=self.GetPyData(item)[0]['maplayer'], type=type,
command=cmdlist, name=self.GetItemText(item),
l_active=chk, l_hidden=hidden, l_opacity=opac, l_render=False)
Modified: trunk/grassaddons/gui/icons/icon.py
===================================================================
--- trunk/grassaddons/gui/icons/icon.py 2007-10-17 20:39:08 UTC (rev 1139)
+++ trunk/grassaddons/gui/icons/icon.py 2007-10-18 14:49:05 UTC (rev 1140)
@@ -18,6 +18,8 @@
"""
import os
+import sys
+
import wx
iconpath_default = os.path.join(os.getenv("GISBASE"), "etc", "gui", "icons")
@@ -111,23 +113,30 @@
}
# merge icons dictionaries, join paths
-if iconpath and iconpath.find('silk') > -1: # silk icon theme
- from silk import IconsSilk as icons_img
- # use default icons if needed
- for key, img in icons_default.iteritems():
- if not icons_img.has_key(key): # add key
- icons_img[key] = img
- if key[0:3] == 'dig':
- iconpath_tmp = iconpath_vdigit
+try:
+ if not os.path.exists(iconpath):
+ raise OSError
+ if iconpath is not None and iconpath.find('silk') > -1: # silk icon theme
+ from silk import IconsSilk as icons_img
+ # use default icons if needed
+ for key, img in icons_default.iteritems():
+ if not icons_img.has_key(key): # add key
+ icons_img[key] = img
+ if key[0:3] == 'dig':
+ iconpath_tmp = iconpath_vdigit
+ else:
+ iconpath_tmp = iconpath_default
else:
- iconpath_tmp = iconpath_default
- else:
- iconpath_tmp = iconpath
+ iconpath_tmp = iconpath
- if icons_img[key]: # join paths
- if type (icons_img[key]) == type(''):
- icons_img[key] = os.path.join(iconpath_tmp, icons_img[key])
-else: # default icons
+ if icons_img[key]: # join paths
+ if type (icons_img[key]) == type(''):
+ icons_img[key] = os.path.join(iconpath_tmp, icons_img[key])
+except:
+ print >> sys.stderr, _("Unable to load icon theme, using default icon theme...")
+ iconpath = None
+
+if iconpath is None: # default icons
icons_img = icons_default
for key, img in icons_img.iteritems():
if img and type (icons_img[key]) == type(''):
From landa at grass.itc.it Thu Oct 18 18:47:06 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 18 18:47:07 2007
Subject: [grass-addons] r1141 - trunk/grassaddons/gui
Message-ID: <200710181647.l9IGl6WV000430@grass.itc.it>
Author: landa
Date: 2007-10-18 18:46:53 +0200 (Thu, 18 Oct 2007)
New Revision: 1141
Modified:
trunk/grassaddons/gui/gis_set.py
Log:
cmd -> gcmd
Modified: trunk/grassaddons/gui/gis_set.py
===================================================================
--- trunk/grassaddons/gui/gis_set.py 2007-10-18 14:49:05 UTC (rev 1140)
+++ trunk/grassaddons/gui/gis_set.py 2007-10-18 16:46:53 UTC (rev 1141)
@@ -1,6 +1,4 @@
#!/usr/bin/env python
-# -*- coding: UTF-8 -*-
-# generated by wxGlade 0.4.1 on Mon Feb 26 18:29:42 2007
"""
MODULE: gis_set.py
@@ -32,7 +30,7 @@
import glob
import shutil
import wx.lib.rcsizer as rcs
-import gui_modules.cmd as cmd
+import gui_modules.gcmd as gcmd
import shutil
def read_grassrc():
From landa at grass.itc.it Fri Oct 19 15:04:00 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 19 15:04:02 2007
Subject: [grass-addons] r1142 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710191304.l9JD404W015220@grass.itc.it>
Author: landa
Date: 2007-10-19 15:03:56 +0200 (Fri, 19 Oct 2007)
New Revision: 1142
Modified:
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/wxgui.py
Log:
Minor fixes for workspace file support.
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-18 16:46:53 UTC (rev 1141)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-19 13:03:56 UTC (rev 1142)
@@ -29,7 +29,7 @@
("New", "Create new workspace file (erase current workspace settings first)", "self.OnWorkspaceNew", ""),
("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
- ("Save as", "Save current workspace as", "self.OnWorkspaceSave", ""),
+ ("Save as", "Save current workspace as", "self.OnWorkspaceSaveAs", ""),
)),
("","","", ""),
("Import raster map", (
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-18 16:46:53 UTC (rev 1141)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-19 13:03:56 UTC (rev 1142)
@@ -379,17 +379,21 @@
# add layer to the layer tree
if self.layer_selected and self.layer_selected != self.GetRootItem():
if self.GetPyData(self.layer_selected)[0]['type'] != 'group':
- if lgroup is None or lgroup is True:
+ if lgroup is False:
+ # last child of root
+ layer = self.AppendItem(parentId=self.root,
+ text='', ct_type=1, wnd=ctrl)
+ elif lgroup is None or lgroup is True:
+ # insert item on given position
parent = self.GetItemParent(self.layer_selected)
- else:
- parent = self.root
- layer = self.InsertItem(parent, self.GetPrevSibling(self.layer_selected),
- text='', ct_type=1, wnd=ctrl)
- else: # group
+ layer = self.InsertItem(parentId=parent, input=self.GetPrevSibling(self.layer_selected),
+ text='', ct_type=1, wnd=ctrl)
+
+ else: # group (first child of self.layer_selected)
layer = self.PrependItem(parent=self.layer_selected,
text='', ct_type=1, wnd=ctrl)
self.Expand(self.layer_selected)
- else: # add first layer to the layer tree
+ else: # add first layer to the layer tree (first child of root)
layer = self.PrependItem(parent=self.root, text='', ct_type=1, wnd=ctrl)
# layer is initially unchecked as inactive (beside 'command')
@@ -398,8 +402,8 @@
checked = lchecked
self.CheckItem(layer, checked=checked)
- # select item
- self.SelectItem(layer)
+ # select new item
+ self.SelectItem(layer, select=True)
self.layer_selected = layer
# add text and icons for each layer ltype
@@ -448,13 +452,6 @@
self.SetItemImage(layer, self.folder)
self.SetItemText(layer, grouptext)
- # use predefined layer name if given
- if lname:
- if ltype != 'command':
- self.SetItemText(layer, lname)
- else:
- ctrl.SetValue(lname)
-
self.first = False
if ltype != 'group':
@@ -497,7 +494,14 @@
'maplayer' : None,
'prowin' : None},
None))
-
+
+ # use predefined layer name if given
+ if lname:
+ if ltype != 'command':
+ self.SetItemText(layer, lname)
+ else:
+ ctrl.SetValue(lname)
+
return layer
def PropertiesDialog (self, layer, show=True):
@@ -642,16 +646,13 @@
cmd = event.GetString()
layer = None
- vislayer = self.GetFirstVisibleItem()
+ layer = self.GetFirstVisibleItem()
- for item in range(0, self.GetCount()):
- if self.GetPyData(vislayer)[0]['ctrl'] == ctrl:
- layer = vislayer
-
- if not self.GetNextVisible(vislayer):
+ while layer and layer.IsOk():
+ if self.GetPyData(layer)[0]['ctrl'] == ctrl:
break
- else:
- vislayer = self.GetNextVisible(vislayer)
+
+ layer = self.GetNextVisible(layer)
# change parameters for item in layers list in render.Map
if layer and self.drag == False:
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-18 16:46:53 UTC (rev 1141)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-19 13:03:56 UTC (rev 1142)
@@ -436,7 +436,7 @@
caption=_("Save current settings?"),
style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_OK:
- self.OnWorkspaceSave(None)
+ self.OnWorkspaceSaveAs(None)
dlg.Destroy()
# delete all items
@@ -455,6 +455,9 @@
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetFilename()
+ if filename == '':
+ return
+
Debug.msg(4, "GMFrame.OnWorkspaceOpen(): filename=%s" % filename)
self.LoadGrcXmlToLayerTree(filename)
@@ -492,34 +495,35 @@
self.OnWorkspaceNew(None)
# read file and fix patch to dtd
-# try:
- file = open(filename, "r")
+ try:
+ file = open(filename, "r")
- fileStream = ''.join(file.readlines())
- p = re.compile( '(grass-grc.dtd)')
- p.search(fileStream)
- fileStream = p.sub(dtdFilename, fileStream)
+ fileStream = ''.join(file.readlines())
+ p = re.compile( '(grass-grc.dtd)')
+ p.search(fileStream)
+ fileStream = p.sub(dtdFilename, fileStream)
- # sax
- grcXml = ProcessGrcXml()
- xml.sax.parseString(fileStream, grcXml)
- maptree = self.curr_page.maptree
- for layer in grcXml.layers:
- newItem = maptree.AddLayer(ltype=layer['type'],
- lname=layer['name'],
- lchecked=layer['checked'],
- lopacity=layer['opacity'],
- lcmd=layer['cmd'],
- lgroup=layer['group'])
- maptree.PropertiesDialog(newItem, show=False)
+ # sax
+ grcXml = ProcessGrcXml()
+ xml.sax.parseString(fileStream, grcXml)
+
+ maptree = self.curr_page.maptree
+ for layer in grcXml.layers:
+ newItem = maptree.AddLayer(ltype=layer['type'],
+ lname=layer['name'],
+ lchecked=layer['checked'],
+ lopacity=layer['opacity'],
+ lcmd=layer['cmd'],
+ lgroup=layer['group'])
+ maptree.PropertiesDialog(newItem, show=False)
- file.close()
- # except:
-# dlg = wx.MessageDialog(self, _("Unable to read workspace file <%s>.") % filename,
-# _("Error"), wx.OK | wx.ICON_ERROR)
-# dlg.ShowModal()
-# dlg.Destroy()
-# return False
+ file.close()
+ except:
+ dlg = wx.MessageDialog(self, _("Unable to read workspace file <%s>.") % filename,
+ _("Error"), wx.OK | wx.ICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
return True
@@ -551,13 +555,21 @@
Debug.msg(4, "GMFrame.OnWorkspaceSaveAs(): filename=%s" % filename)
self.SaveLayerTreeToGrcXml(filename)
-
+ self.workspaceFile = filename
+
def OnWorkspaceSave(self, event):
"""Save file with workspace definition"""
if self.workspaceFile:
- Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
- self.SaveLayerTreeToGrcXml(self.workspaceFile)
+ dlg = wx.MessageDialog(self, message=_("Workspace file <%s> already exists. "
+ "Do you want to overwrite this file?") % \
+ self.workspaceFile,
+ caption=_("File exits"), style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
+ if dlg.ShowModal() != wx.ID_OK:
+ dlg.Destroy()
+ else:
+ Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
+ self.SaveLayerTreeToGrcXml(self.workspaceFile)
else:
self.OnWorkspaceSaveAs(None)
@@ -575,6 +587,7 @@
if type == 'command':
file.write(' \n' % \
(type, ' '.join(cmd), checked));
+ file.write(' \n');
elif type == 'group':
name = mapTree.GetItemText(item)
file.write(' \n' % \
@@ -1225,7 +1238,6 @@
self.inGrc = True
elif name == 'group':
- self.inGroup = True
self.groupName = attrs.get('name', None)
self.groupChecked = attrs.get('checked', None)
self.layers.append({
@@ -1234,7 +1246,8 @@
"checked" : int(self.groupChecked),
"opacity" : None,
"cmd" : None,
- "group" : None})
+ "group" : self.inGroup})
+ self.inGroup = True
elif name == 'layer':
self.inLayer = True
From landa at grass.itc.it Fri Oct 19 15:47:52 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 19 15:47:54 2007
Subject: [grass-addons] r1143 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710191347.l9JDlqQ0019005@grass.itc.it>
Author: landa
Date: 2007-10-19 15:47:48 +0200 (Fri, 19 Oct 2007)
New Revision: 1143
Modified:
trunk/grassaddons/gui/gui_modules/render.py
trunk/grassaddons/gui/wxgui.py
Log:
Workspace file support: fix order of map layers.
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-19 13:03:56 UTC (rev 1142)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-19 13:47:48 UTC (rev 1143)
@@ -905,7 +905,11 @@
return 1
self.layers = []
+ def ReverseListOfLayers(self):
+ """Reverse list of layers"""
+ return self.layers.reverse()
+
if __name__ == "__main__":
"""
Test of Display class.
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-19 13:03:56 UTC (rev 1142)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-19 13:47:48 UTC (rev 1143)
@@ -161,7 +161,6 @@
# initialize variables
self.mapdisplays = {} # dictionary to index open map displays
self.disp_idx = 0 # index value for map displays and layer trees
- self.maptree = {} # dictionary to index a layer tree to accompanying a map display
self.mapfocus = 0 # track which display currently has focus
self.curr_page = '' # currently selected page for layer tree notebook
self.curr_pagenum = '' # currently selected page number for layer tree notebook
@@ -506,7 +505,6 @@
# sax
grcXml = ProcessGrcXml()
xml.sax.parseString(fileStream, grcXml)
-
maptree = self.curr_page.maptree
for layer in grcXml.layers:
newItem = maptree.AddLayer(ltype=layer['type'],
@@ -516,7 +514,10 @@
lcmd=layer['cmd'],
lgroup=layer['group'])
maptree.PropertiesDialog(newItem, show=False)
-
+
+ # reverse list of map layers
+ maptree.Map.ReverseListOfLayers()
+
file.close()
except:
dlg = wx.MessageDialog(self, _("Unable to read workspace file <%s>.") % filename,
From landa at grass.itc.it Fri Oct 19 20:43:21 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 19 20:43:23 2007
Subject: [grass-addons] r1144 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710191843.l9JIhL3c024817@grass.itc.it>
Author: landa
Date: 2007-10-19 20:43:16 +0200 (Fri, 19 Oct 2007)
New Revision: 1144
Modified:
trunk/grassaddons/gui/gui_modules/grass-grc.dtd
trunk/grassaddons/gui/gui_modules/menudata.py
trunk/grassaddons/gui/wxgui.py
Log:
Workspace file support:
* multiple displays implemented
* Close file implemented
Modified: trunk/grassaddons/gui/gui_modules/grass-grc.dtd
===================================================================
--- trunk/grassaddons/gui/gui_modules/grass-grc.dtd 2007-10-19 13:47:48 UTC (rev 1143)
+++ trunk/grassaddons/gui/gui_modules/grass-grc.dtd 2007-10-19 18:43:16 UTC (rev 1144)
@@ -14,8 +14,13 @@
-
+
+
+
+
Modified: trunk/grassaddons/gui/gui_modules/menudata.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-19 13:47:48 UTC (rev 1143)
+++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-10-19 18:43:16 UTC (rev 1144)
@@ -30,6 +30,7 @@
("Open", "Open existing workspace file", "self.OnWorkspaceOpen", ""),
("Save", "Save current workspace to file", "self.OnWorkspaceSave", ""),
("Save as", "Save current workspace as", "self.OnWorkspaceSaveAs", ""),
+ ("Close", "Close selected workspace file", "self.OnWorkspaceClose", ""),
)),
("","","", ""),
("Import raster map", (
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-19 13:47:48 UTC (rev 1143)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-19 18:43:16 UTC (rev 1144)
@@ -159,9 +159,7 @@
os.environ["GRASS_RENDER_IMMEDIATE"] = "TRUE"
# initialize variables
- self.mapdisplays = {} # dictionary to index open map displays
self.disp_idx = 0 # index value for map displays and layer trees
- self.mapfocus = 0 # track which display currently has focus
self.curr_page = '' # currently selected page for layer tree notebook
self.curr_pagenum = '' # currently selected page number for layer tree notebook
self.encoding = 'ISO-8859-1' # default encoding for display fonts
@@ -420,11 +418,13 @@
wx.AboutBox(info)
- def OnWorkspaceNew(self, event):
+ def OnWorkspaceNew(self, event=None):
"""Create new workspace file
Erase current workspace settings first"""
+ Debug.msg(4, "GMFrame.OnWorkspaceNew():")
+
maptree = self.curr_page.maptree
# ask user to save current settings
@@ -435,7 +435,7 @@
caption=_("Save current settings?"),
style=wx.OK | wx.CANCEL | wx.ICON_QUESTION)
if dlg.ShowModal() == wx.ID_OK:
- self.OnWorkspaceSaveAs(None)
+ self.OnWorkspaceSaveAs()
dlg.Destroy()
# delete all items
@@ -445,7 +445,7 @@
maptree.root = maptree.AddRoot("Map Layers")
self.curr_page.maptree.SetPyData(maptree.root, (None,None))
- def OnWorkspaceOpen(self, event):
+ def OnWorkspaceOpen(self, event=None):
"""Open file with workspace definition"""
dlg = wx.FileDialog(parent=self, message=_("Choose workspace file"),
defaultDir=os.getcwd(), wildcard="*.grc")
@@ -491,7 +491,7 @@
return False
# delete current layer tree content
- self.OnWorkspaceNew(None)
+ self.OnWorkspaceNew()
# read file and fix patch to dtd
try:
@@ -505,8 +505,11 @@
# sax
grcXml = ProcessGrcXml()
xml.sax.parseString(fileStream, grcXml)
- maptree = self.curr_page.maptree
for layer in grcXml.layers:
+ if layer['display'] >= self.disp_idx:
+ # create new map display window if needed
+ self.NewDisplay()
+ maptree = self.gm_cb.GetPage(layer['display']).maptree
newItem = maptree.AddLayer(ltype=layer['type'],
lname=layer['name'],
lchecked=layer['checked'],
@@ -528,7 +531,7 @@
return True
- def OnWorkspaceSaveAs(self, event):
+ def OnWorkspaceSaveAs(self, event=None):
"""Save workspace definition to selected file"""
dlg = wx.FileDialog(parent=self, message=_("Choose file to save current workspace"),
@@ -558,7 +561,7 @@
self.SaveLayerTreeToGrcXml(filename)
self.workspaceFile = filename
- def OnWorkspaceSave(self, event):
+ def OnWorkspaceSave(self, event=None):
"""Save file with workspace definition"""
if self.workspaceFile:
@@ -572,10 +575,11 @@
Debug.msg(4, "GMFrame.OnWorkspaceSave(): filename=%s" % self.workspaceFile)
self.SaveLayerTreeToGrcXml(self.workspaceFile)
else:
- self.OnWorkspaceSaveAs(None)
+ self.OnWorkspaceSaveAs()
def WriteLayersToGrcXml(self, file, mapTree, item):
"""Write bunch of layers to GRC XML file"""
+ self.indent += 4
while item and item.IsOk():
type = mapTree.GetPyData(item)[0]['type']
if type != 'group':
@@ -586,34 +590,46 @@
checked = int(item.IsChecked())
cmd = mapTree.GetPyData(item)[0]['cmd']
if type == 'command':
- file.write(' \n' % \
- (type, ' '.join(cmd), checked));
- file.write(' \n');
+ file.write('%s\n' % \
+ (' ' * self.indent, type, ' '.join(cmd), checked));
+ file.write('%s\n' % (' ' * self.indent));
elif type == 'group':
name = mapTree.GetItemText(item)
- file.write(' \n' % \
- (name, checked));
+ file.write('%s\n' % \
+ (' ' * self.indent, name, checked));
+ self.indent += 4
subItem = mapTree.GetFirstChild(item)[0]
self.WriteLayersToGrcXml(file, mapTree, subItem)
- file.write(' \n');
+ self.indent -= 4
+ file.write('%s\n' % (' ' * self.indent));
else:
name = mapTree.GetItemText(item)
opacity = maplayer.GetOpacity(float=True)
- file.write(' \n' % \
- (type, name, checked, opacity));
+ file.write('%s\n' % \
+ (' ' * self.indent, type, name, checked, opacity));
# layer properties
- file.write(' \n' % cmd[0])
+ self.indent += 4
+ file.write('%s\n' % (' ' * self.indent, cmd[0]))
+ self.indent += 4
for option in cmd[1:]:
if option[0] == '-': # flag
- file.write(' \n' % option[1])
+ file.write('%s\n' %
+ (' ' * self.indent, option[1]))
else: # parameter
key, value = option.split('=')
- file.write(' \n' % key)
- file.write(' %s\n' % value)
- file.write(' \n');
- file.write(' \n');
- file.write(' \n');
+ file.write('%s\n' %
+ (' ' * self.indent, key))
+ self.indent += 4
+ file.write('%s%s\n' %
+ (' ' * self.indent, value))
+ self.indent -= 4
+ file.write('%s\n' % (' ' * self.indent));
+ self.indent -= 4
+ file.write('%s\n' % (' ' * self.indent));
+ self.indent -= 4
+ file.write('%s\n' % (' ' * self.indent));
item = mapTree.GetNextSibling(item)
+ self.indent -= 4
def SaveLayerTreeToGrcXml(self, filename):
"""Save layer tree layout to workspace file
@@ -631,15 +647,23 @@
return False
try:
+ self.indent = 0 # number of spaces
# write header
file.write('\n')
file.write('\n')
- file.write('\n')
- # list of layers
- mapTree = self.curr_page.maptree
- item = mapTree.GetFirstChild(mapTree.root)[0]
- self.WriteLayersToGrcXml(file, mapTree, item)
- file.write('\n')
+ file.write('%s\n' % (' ' * self.indent))
+ # list of displays
+ for page in range(0, self.gm_cb.GetPageCount()):
+ self.indent =+ 4
+ file.write('%s\n' % (' ' * self.indent))
+ mapTree = self.gm_cb.GetPage(page).maptree
+ # list of layers
+ item = mapTree.GetFirstChild(mapTree.root)[0]
+ self.WriteLayersToGrcXml(file, mapTree, item)
+ file.write('%s\n' % (' ' * self.indent))
+ self.indent =- 4
+ file.write('%s\n' % (' ' * self.indent))
+ del self.indent
except:
dlg = wx.MessageDialog(self, _("Writing current settings to workspace file failed."),
_("Error"), wx.OK | wx.ICON_ERROR)
@@ -651,14 +675,16 @@
return True
- def OnWorkspaceClose(self, event):
+ def OnWorkspaceClose(self, event=None):
"""Close file with workspace definition
If workspace has been modified ask user to save the changes.
"""
- pass
+ Debug.msg(4, "GMFrame.OnWorkspaceClose(): file=%s" % self.workspaceFile)
+ self.workspaceFile = None
+
def RulesCmd(self, event):
"""
Launches dialog for commands that need rules
@@ -861,6 +887,8 @@
create an associated map display frame
"""
+ Debug.msg(3, "GMFrame.NewDisplay(): idx=%d" % self.disp_idx)
+
# make a new page in the bookcontrol for the layer tree (on page 0 of the notebook)
self.pg_panel = wx.Panel(self.gm_cb, id=wx.ID_ANY, style= wx.EXPAND)
self.gm_cb.AddPage(self.pg_panel, text="Display "+ str(self.disp_idx), select = True)
@@ -884,15 +912,15 @@
self.disp_idx += 1
-# self._auimgr.SetManagedWindow(self.curr_page.maptree.testframe)
-#
-# self._auimgr.AddPane(self.curr_page.maptree.testframe,
-# wx.aui.AuiPaneInfo().Right().
-# BestSize((-1,-1)).
-# CloseButton(True).MinimizeButton(True).
-# DestroyOnClose(True).Layer(2))
-#
-# self._auimgr.Update()
+ # self._auimgr.SetManagedWindow(self.curr_page.maptree.testframe)
+ #
+ # self._auimgr.AddPane(self.curr_page.maptree.testframe,
+ # wx.aui.AuiPaneInfo().Right().
+ # BestSize((-1,-1)).
+ # CloseButton(True).MinimizeButton(True).
+ # DestroyOnClose(True).Layer(2))
+ #
+ # self._auimgr.Update()
# toolBar button handlers
def OnRaster(self, event):
@@ -1229,15 +1257,21 @@
self.inFlag = False
self.inValue = False
self.inGroup = False
+ self.inDisplay = False
# list of layers
self.layers = []
self.cmd = []
+ self.displayIndex = -1 # first display has index '0'
def startElement(self, name, attrs):
if name == 'grc':
self.inGrc = True
-
+
+ elif name == 'display':
+ self.inDisplay = True
+ self.displayIndex += 1
+
elif name == 'group':
self.groupName = attrs.get('name', None)
self.groupChecked = attrs.get('checked', None)
@@ -1247,7 +1281,8 @@
"checked" : int(self.groupChecked),
"opacity" : None,
"cmd" : None,
- "group" : self.inGroup})
+ "group" : self.inGroup,
+ "display" : self.displayIndex})
self.inGroup = True
elif name == 'layer':
@@ -1280,6 +1315,9 @@
if name == 'grc':
self.inGrc = False
+ elif name == 'display':
+ self.inDisplay = False
+
elif name == 'group':
self.inGroup = False
self.groupName = self.groupChecked = None
@@ -1292,7 +1330,9 @@
"checked" : int(self.layerChecked),
"opacity" : None,
"cmd" : None,
- "group" : self.inGroup})
+ "group" : self.inGroup,
+ "display" : self.displayIndex})
+
if self.layerOpacity:
self.layers[-1]["opacity"] = float(self.layerOpacity)
if self.cmd:
From landa at grass.itc.it Fri Oct 19 21:05:41 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 19 21:05:42 2007
Subject: [grass-addons] r1145 - trunk/grassaddons/gui
Message-ID: <200710191905.l9JJ5feX024842@grass.itc.it>
Author: landa
Date: 2007-10-19 21:05:38 +0200 (Fri, 19 Oct 2007)
New Revision: 1145
Modified:
trunk/grassaddons/gui/README
Log:
README updated.
Modified: trunk/grassaddons/gui/README
===================================================================
--- trunk/grassaddons/gui/README 2007-10-19 18:43:16 UTC (rev 1144)
+++ trunk/grassaddons/gui/README 2007-10-19 19:05:38 UTC (rev 1145)
@@ -1,14 +1,10 @@
-GRASS graphical user interface
-==============================
+wxPython GRASS graphical user interface
+=======================================
-AUTHORS: Michael Barton, Jachym Cepicky, Martin Landa
+0 - REQUIREMENTS
-$LastChangedDate$
+ Python >= 2.4 and wxPython >= 2.8.1.1
----------------------------------------------------------------------
-Requirements:
- Python >=2.4 and wxPython >=2.8.1.1
-
Get wxPython 2.8.x packages from:
* Source: http://www.wxpython.org/download.php
* Debian GNU/Linux: http://wiki.wxpython.org/InstallingOnUbuntuOrDebian
@@ -29,51 +25,48 @@
Get Python from:
* Python.org for Source, MS-Windows, OS X: http://www.python.org/download/
* ActiveStates for AIX, HP-UX, Linux (x86), Linux 64-bit (x86_64 AMD64), Mac OS X,
- Solaris (SPARC), Windows: http://www.activestate.com/store/download.aspx?prdGUID=b08b04e0-6872-4d9d-a722-7a0c2dea2758
----------------------------------------------------------------------
+ Solaris (SPARC), Windows:
+ http://www.activestate.com/store/download.aspx?prdGUID=b08b04e0-6872-4d9d-a722-7a0c2dea2758
-How to start:
+1 - INSTALLATION
-Download fresh source code from subversion:
-$~ svn co https://grasssvn.itc.it/svn/grassaddons/trunk/grassaddons/gui grassaddons/gui
+Download fresh source code from Subversion repository:
+$ svn co https://grasssvn.itc.it/svn/grassaddons/trunk/grassaddons/gui grassaddons/gui
+
Or update your local repository
-$~ svn up grassaddons/gui
+$ svn up grassaddons/gui
Change to GUI devel directory:
-$~ cd grassaddons/gui
+$ cd grassaddons/gui
-
-1 - INSTALLATION
-
-1.a) Put everything from gui into a new directory $GISBASE/etc/wx.
- Or, easier, in GRASS:
+1) Copy everything from gui directory into a new directory $GISBASE/etc/wx.
+ Or easier, create symlink (in running GRASS session):
cd /path/to/grassaddons/gui
- ln -s `pwd` $GISBASE/etc/wx
+ ln -s `pwd` $GISBASE/etc/wx
-1.b) Move the script "wxgrass" into $GISBASE/scripts.
- Or, easier, in GRASS:
+2) Move the script "wxgrass" into $GISBASE/scripts.
+ Or easier, create symlink (in running GRASS session):
cd /path/to/grassaddons/gui
ln -s `pwd`/wxgrass $GISBASE/scripts
2 - STARTUP WITH GRASS INITIALIZATION
-If you want to start the wxgrass GUI automatically when you start
+If you want to run wxPython GUI automatically when you start
GRASS, edit your .grassrc6 file to replace...
GRASS_GUI: tcktk (or whatever you have here)
-...with...
+with
GRASS_GUI: wx
3 - STARTUP FROM GRASS TERMINAL
-Simply type wxgrass& from the GRASS terminal to start the GUI using the wxgrass script.
+Simply type wxgrass from the GRASS terminal.
-
4 - CLI Display scripts
This is going to be replacement for command line tools like d.rast and
From landa at grass.itc.it Sat Oct 20 00:17:35 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:46 2007
Subject: [grass-addons] r1146 - in trunk/grassaddons/gui: . icons
Message-ID: <200710192217.l9JMHZeb026959@grass.itc.it>
Author: landa
Date: 2007-10-20 00:17:26 +0200 (Sat, 20 Oct 2007)
New Revision: 1146
Modified:
trunk/grassaddons/gui/gis_set.py
trunk/grassaddons/gui/icons/icon.py
Log:
Code cleaning (basic) of GRASS start-up screen.
Modified: trunk/grassaddons/gui/gis_set.py
===================================================================
--- trunk/grassaddons/gui/gis_set.py 2007-10-19 19:05:38 UTC (rev 1145)
+++ trunk/grassaddons/gui/gis_set.py 2007-10-19 22:17:26 UTC (rev 1146)
@@ -7,16 +7,13 @@
* GRASSStartup
* StartUp
-PURPOSE: Initialization module for wxPython GUI for GRASS GIS. Includes
- location/mapset selection, location/mapset creation,
- location/mapset management.
+PURPOSE: Initialization module for wxPython GRASS GUI.
+ Location/mapset management (selection, creation, etc.).
- Usage:
- python "$GISBASE/etc/wx/wxgui.py" -name wxgui_py
-
AUTHORS: The GRASS Development Team
Michael Barton
Jachym Cepicky
+ Martin Landa
COPYRIGHT: (C) 2006-2007 by the GRASS Development Team
This program is free software under the GNU General Public
@@ -24,130 +21,140 @@
for details.
"""
-
-import wx
import os
+import sys
import glob
import shutil
-import wx.lib.rcsizer as rcs
-import gui_modules.gcmd as gcmd
-import shutil
-def read_grassrc():
- """
- Read variables from $HOME/.grassrc6 file
- """
+import wx
+import wx.lib.rcsizer as rcs
+import wx.lib.filebrowsebutton as filebrowse
- grassrc = {}
-
- if os.path.isfile(os.getenv("GISRC")):
- rc = open(os.getenv("GISRC"), "r")
- for line in rc.readlines():
- key,val = line.split(":")
- grassrc[key.strip()] = val.strip()
- rc.close()
-
- return grassrc
-
class GRASSStartup(wx.Frame):
- def __init__(self, *args, **kwds):
- kwds["style"] = wx.DEFAULT_FRAME_STYLE
- wx.Frame.__init__(self, *args, **kwds)
+ """GRASS start-up screen"""
+ def __init__(self, parent=None, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE):
#
- # variables
+ # GRASS variables
#
- self.grassrc = read_grassrc()
- self.gisbase=os.getenv("GISBASE")
- self.gisdbase=self._getRCValue("GISDBASE")
+ self.gisbase = os.getenv("GISBASE")
+ self.grassrc = self._read_grassrc()
+ self.gisdbase = self._getRCValue("GISDBASE")
+
+ #
+ # list of locations/mapsets
+ #
self.listOfLocations = []
self.listOfMapsets = []
+ wx.Frame.__init__(self, parent=parent, id=id, style=style)
+
#
# graphical elements
#
+ # image
try:
- self.hbitmap = wx.StaticBitmap(self, -1,
- wx.Bitmap(os.path.join(self.gisbase,"etc","gintro.gif"), wx.BITMAP_TYPE_ANY))
+ name = os.path.join(self.gisbase, "etc", "gintro.gif")
+ self.hbitmap = wx.StaticBitmap(self, wx.ID_ANY,
+ wx.Bitmap(name=name,
+ type=wx.BITMAP_TYPE_GIF))
except:
- self.hbitmap = wx.StaticBitmap(self, -1, wx.EmptyBitmap(530,150))
+ self.hbitmap = wx.StaticBitmap(self, wx.ID_ANY, wx.EmptyBitmap(530,150))
# labels
- self.lwelcome = wx.StaticText(self, -1,
- "Welcome to GRASS GIS Version 6.3.cvs\n"+\
- "The world's leading open source GIS",
- style=wx.ALIGN_CENTRE)
- self.ltitle = wx.StaticText(self, -1,
- "Select an existing project location and mapset\n"+\
- "or define a new location",
- style=wx.ALIGN_CENTRE)
- self.ldbase = wx.StaticText(self, -1, "GIS Data Directory:")
- self.llocation = wx.StaticText(self, -1, "Project Location\n(projection/coordinate system)", style=wx.ALIGN_CENTRE)
- self.lmapset = wx.StaticText(self, -1, "Accessible Mapsets\n(directories of GIS files)", style=wx.ALIGN_CENTRE)
- self.lmanage = wx.StaticText(self, -1, "Manage Locations\nand Mapsets", style=wx.ALIGN_CENTRE)
- self.lcreate = wx.StaticText(self, -1, "Create new mapset\nin selected location", style=wx.ALIGN_CENTRE)
- self.ldefine = wx.StaticText(self, -1, "Define new location", style=wx.ALIGN_CENTRE)
- self.lmanageloc = wx.StaticText(self, -1, "Rename/delete selected\nmapset or location", style=wx.ALIGN_CENTRE)
+ versionCmd = gcmd.Command(['g.version'])
+ grassVersion = versionCmd.ReadStdOutput()[0].replace('GRASS', '').strip()
+ self.lwelcome = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Welcome to GRASS GIS %s\n"
+ "The world's leading open source GIS") % grassVersion,
+ style=wx.ALIGN_CENTRE)
+ self.ltitle = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Select an existing project location and mapset\n"
+ "or define a new location"),
+ style=wx.ALIGN_CENTRE)
+ self.ldbase = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("GIS Data Directory:"))
+ self.llocation = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Project location\n(projection/coordinate system)"),
+ style=wx.ALIGN_CENTRE)
+ self.lmapset = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Accessible mapsets\n(directories of GIS files)"),
+ style=wx.ALIGN_CENTRE)
+ self.lcreate = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Create new mapset\nin selected location"),
+ style=wx.ALIGN_CENTRE)
+ self.ldefine = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Define new location"),
+ style=wx.ALIGN_CENTRE)
+ self.lmanageloc = wx.StaticText(parent=self, id=wx.ID_ANY,
+ label=_("Rename/delete selected\nmapset or location"),
+ style=wx.ALIGN_CENTRE)
+
# buttons
- buttonsize1 = (150,-1)
- buttonsize2 = (150, -1)
-
- self.bstart = wx.Button(self, -1, "Start GRASS", size=buttonsize2)
+ self.bstart = wx.Button(parent=self, id=wx.ID_ANY,
+ label=_("Start GRASS"), size=(200, -1))
self.bstart.SetDefault()
- self.bexit = wx.Button(self, -1, "Exit", size=buttonsize2)
- self.bhelp = wx.Button(self, -1, "Help", size=buttonsize2)
- self.bbrowse = wx.Button(self, -1, "Browse ...", size=(-1,-1))
- self.bmapset = wx.Button(self, -1, "Create mapset", size=buttonsize1)
- self.bwizard = wx.Button(self, -1, "Location wizard", size=buttonsize1)
- choicelist = ['Rename mapset','Rename location', 'Delete mapset', 'Delete location']
- self.manageloc = wx.Choice(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, choices=choicelist)
+ self.bexit = wx.Button(parent=self, id=wx.ID_EXIT)
+ self.bhelp = wx.Button(parent=self, id=wx.ID_HELP)
+ self.bbrowse = wx.Button(parent=self, id=wx.ID_ANY,
+ label=_("Browse"))
+ self.bmapset = wx.Button(parent=self, id=wx.ID_ANY,
+ label=_("Create mapset"))
+ self.bwizard = wx.Button(parent=self, id=wx.ID_ANY,
+ label=_("Location wizard"))
+ self.manageloc = wx.Choice(parent=self, id=wx.ID_ANY,
+ choices=['Rename mapset','Rename location',
+ 'Delete mapset', 'Delete location'])
# textinputs
- self.tgisdbase = wx.TextCtrl(self, -1, "", size=(300, 20),
- style=wx.TE_LEFT)
- self.tnewmapset = wx.TextCtrl(self,-1, "", size=(150,20))
+ self.tgisdbase = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(300, -1),
+ style=wx.TE_LEFT)
# Locations
- self.lpanel = wx.Panel(self,-1)
- self.lblocations = wx.ListBox(self.lpanel,
- id=26, pos=wx.DefaultPosition, size=(150, 200),
- choices=self.listOfLocations, style=wx.LB_SINGLE)
+ self.lpanel = wx.Panel(parent=self,id=wx.ID_ANY)
+ self.lblocations = wx.ListBox(parent=self.lpanel,
+ id=wx.ID_ANY, size=(150, 200),
+ choices=self.listOfLocations,
+ style=wx.LB_SINGLE)
# Mapsets
- self.mpanel = wx.Panel(self,-1)
- self.lbmapsets = wx.ListBox(self.mpanel,
- id=26, pos=wx.DefaultPosition, size=(150, 200),
- choices=self.listOfMapsets, style=wx.LB_SINGLE)
+ self.mpanel = wx.Panel(parent=self,id=wx.ID_ANY)
+ self.lbmapsets = wx.ListBox(parent=self.mpanel,
+ id=wx.ID_ANY, size=(150, 200),
+ choices=self.listOfMapsets,
+ style=wx.LB_SINGLE)
# layout & properties
- self.__set_properties()
- self.__do_layout()
+ self._set_properties()
+ self._do_layout()
# events
- self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
- self.bstart.Bind(wx.EVT_BUTTON, self.OnStart)
- self.bexit.Bind(wx.EVT_BUTTON, self.OnExit)
- self.bhelp.Bind(wx.EVT_BUTTON, self.OnHelp)
- self.bmapset.Bind(wx.EVT_BUTTON, self.OnCreateMapset)
- self.bwizard.Bind(wx.EVT_BUTTON, self.OnWizard)
- self.manageloc.Bind(wx.EVT_CHOICE, self.OnManageLoc)
+ self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
+ self.bstart.Bind(wx.EVT_BUTTON, self.OnStart)
+ self.bexit.Bind(wx.EVT_BUTTON, self.OnExit)
+ self.bhelp.Bind(wx.EVT_BUTTON, self.OnHelp)
+ self.bmapset.Bind(wx.EVT_BUTTON, self.OnCreateMapset)
+ self.bwizard.Bind(wx.EVT_BUTTON, self.OnWizard)
+ self.manageloc.Bind(wx.EVT_CHOICE, self.OnManageLoc)
self.lblocations.Bind(wx.EVT_LISTBOX, self.OnSelectLocation)
- self.lbmapsets.Bind(wx.EVT_LISTBOX, self.OnSelectMapset)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressedInDbase, self.tgisdbase)
- self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressedInMapset, self.tnewmapset)
- self.Bind(wx.EVT_CLOSE, self.onCloseWindow)
+ self.lbmapsets.Bind(wx.EVT_LISTBOX, self.OnSelectMapset)
+ self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressedInDbase, self.tgisdbase)
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
- def __set_properties(self):
- self.SetTitle("Welcome to GRASS GIS")
- self.SetIcon(wx.Icon(os.path.join(self.gisbase,"etc","dm","grass.gif"),
- wx.BITMAP_TYPE_GIF))
+ def _set_properties(self):
+ """Set frame properties"""
+ self.SetTitle(_("Welcome to GRASS GIS"))
+ self.SetIcon(wx.Icon(os.path.join(self.gisbase, "etc", "dm", "grass.gif"),
+ wx.BITMAP_TYPE_GIF))
+
self.lwelcome.SetForegroundColour(wx.Colour(35, 142, 35))
self.lwelcome.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD, 0, ""))
+
self.bstart.SetForegroundColour(wx.Colour(35, 142, 35))
- self.bstart.SetToolTipString("Enter GRASS session")
- #self.bstart.Enable(False)
- #self.bmapset.Enable(False)
+ self.bstart.SetToolTipString(_("Enter GRASS session"))
+ # self.bstart.Enable(False)
+ # self.bmapset.Enable(False)
# set database
if not self.gisdbase:
@@ -172,98 +179,183 @@
mapset =self._getRCValue("MAPSET")
if mapset:
self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset))
- #self.bstart.Enable(True)
+ # self.bstart.Enable(True)
- def __do_layout(self):
+ def _do_layout(self):
label_style = wx.ADJUST_MINSIZE | wx.ALIGN_CENTER_HORIZONTAL
- sizer = wx.BoxSizer(wx.VERTICAL)
- dbase_sizer=wx.BoxSizer(wx.HORIZONTAL)
- grid_sizer = wx.FlexGridSizer(4, 3, 4, 4)
- mapset_sizer = wx.BoxSizer(wx.VERTICAL)
- dbase_sizer.Add(self.ldbase, 0, wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5)
- dbase_sizer.Add(self.tgisdbase, 0, wx.ALIGN_CENTER_VERTICAL
- |wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5)
- dbase_sizer.Add(self.bbrowse, 0, wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 5)
+ sizer = wx.BoxSizer(wx.VERTICAL)
+ dbase_sizer = wx.BoxSizer(wx.HORIZONTAL)
+ location_sizer = wx.FlexGridSizer(rows=1, cols=2, vgap=4, hgap=4)
+ select_box = wx.StaticBox (parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Choose location and mapset"))
+ select_boxsizer = wx.StaticBoxSizer(select_box, wx.VERTICAL)
+ select_sizer = wx.FlexGridSizer(rows=2, cols=2, vgap=4, hgap=4)
+ manage_box = wx.StaticBox (parent=self, id=wx.ID_ANY,
+ label=" %s " % _("Manage"))
+ manage_boxsizer = wx.StaticBoxSizer(manage_box, wx.VERTICAL)
+ manage_sizer = wx.BoxSizer(wx.VERTICAL)
+ btns_sizer = wx.BoxSizer(wx.HORIZONTAL)
- mapset_sizer.Add(self.ldefine, 0, label_style|wx.RIGHT|wx.LEFT|wx.BOTTOM, 5)
- mapset_sizer.Add(self.bwizard, 0, label_style|wx.BOTTOM, 8)
- mapset_sizer.Add(self.lcreate, 0, label_style|wx.TOP|wx.RIGHT|wx.LEFT, 5)
- mapset_sizer.Add(self.tnewmapset, 0, label_style|wx.ALL, 5)
- mapset_sizer.Add(self.bmapset, 0, label_style|wx.BOTTOM, 8)
- mapset_sizer.Add(self.lmanageloc, 0, label_style|wx.TOP|wx.RIGHT|wx.LEFT, 5)
- mapset_sizer.Add(self.manageloc, 0, label_style|wx.ALL, 5)
- mapset_sizer.Add((5,0))
+ # gis data directory
+ dbase_sizer.Add(item=self.ldbase, proportion=0,
+ flag=wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
+ border=5)
+ dbase_sizer.Add(item=self.tgisdbase, proportion=0,
+ flag=wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
+ border=5)
+ dbase_sizer.Add(item=self.bbrowse, proportion=0,
+ flag=wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
+ border=5)
- grid_sizer.Add(self.llocation, 0,label_style|wx.ALL, 5)
- grid_sizer.Add(self.lmapset, 0,label_style|wx.ALL, 5)
- grid_sizer.Add(self.lmanage, 0,label_style|wx.ALL, 5)
+ # select sizer
+ select_sizer.Add(item=self.llocation, proportion=0,
+ flag=label_style | wx.ALL,
+ border=5)
+ select_sizer.Add(item=self.lmapset, proportion=0,
+ flag=label_style | wx.ALL,
+ border=5)
+ select_sizer.Add(item=self.lpanel, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL)
+ select_sizer.Add(item=self.mpanel, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL)
- grid_sizer.Add(self.lpanel, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL, 0)
- grid_sizer.Add(self.mpanel, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL, 0)
- grid_sizer.Add(mapset_sizer, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL, 0)
+ select_boxsizer.Add(item=select_sizer, proportion=0)
- grid_sizer.Add(self.bstart, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_TOP|
- wx.ALIGN_CENTER_HORIZONTAL|
- wx.BOTTOM, 10)
- grid_sizer.Add(self.bexit, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL|
- wx.BOTTOM, 10)
- grid_sizer.Add(self.bhelp, 0, wx.ADJUST_MINSIZE|
- wx.ALIGN_CENTER_VERTICAL|
- wx.ALIGN_CENTER_HORIZONTAL|
- wx.BOTTOM, 10)
+ # define new location and mapset
+ manage_sizer.Add(item=self.ldefine, proportion=0,
+ flag=label_style | wx.ALL,
+ border=5)
+ manage_sizer.Add(item=self.bwizard, proportion=0,
+ flag=label_style | wx.BOTTOM,
+ border=8)
+ manage_sizer.Add(item=self.lcreate, proportion=0,
+ flag=label_style | wx.ALL,
+ border=5)
+ manage_sizer.Add(item=self.bmapset, proportion=0,
+ flag=label_style | wx.BOTTOM,
+ border=8)
+ manage_sizer.Add(item=self.lmanageloc, proportion=0,
+ flag=label_style | wx.ALL,
+ border=5)
+ manage_sizer.Add(item=self.manageloc, proportion=0,
+ flag=label_style | wx.BOTTOM,
+ border=8)
+
+ manage_boxsizer.Add(item=manage_sizer, proportion=0)
- # adding to main VERTICAL sizer
- sizer.Add(self.hbitmap, 0, wx.ADJUST_MINSIZE |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.BOTTOM, 5) # image
- sizer.Add(self.lwelcome, # welcome message
- 0,wx.ADJUST_MINSIZE |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.EXPAND |
- wx.BOTTOM, 10)
- sizer.Add(self.ltitle, # controls title
- 0,wx.ADJUST_MINSIZE |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.EXPAND |
- wx.BOTTOM, 5)
- sizer.Add(dbase_sizer,0,wx.ADJUST_MINSIZE |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.RIGHT | wx.LEFT, 5) # GISDBASE setting
- sizer.Add(grid_sizer, 1, wx.ADJUST_MINSIZE |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.RIGHT | wx.LEFT, 5)
+ # location sizer
+ location_sizer.Add(item=select_boxsizer, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.RIGHT | wx.LEFT,
+ border=5) # GISDBASE setting
+ location_sizer.Add(item=manage_boxsizer, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_TOP |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.RIGHT,
+ border=5)
+
+ # buttons
+ btns_sizer.Add(item=self.bstart, proportion=0,
+ flag=wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALL,
+ border=10)
+ btns_sizer.Add(item=self.bexit, proportion=0,
+ flag=wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALL,
+ border=10)
+ btns_sizer.Add(item=self.bhelp, proportion=0,
+ flag=wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALL,
+ border=10)
+
+ # main sizer
+ sizer.Add(item=self.hbitmap, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.BOTTOM | wx.TOP,
+ border=5) # image
+ sizer.Add(item=self.lwelcome, # welcome message
+ proportion=0,
+ flag= wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.EXPAND |
+ wx.BOTTOM,
+ border=10)
+ sizer.Add(item=self.ltitle, # title
+ proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.EXPAND |
+ wx.BOTTOM,
+ border=5)
+ sizer.Add(item=dbase_sizer, proportion=0,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.RIGHT | wx.LEFT,
+ border=5) # GISDBASE setting
+ sizer.Add(item=location_sizer, proportion=1,
+ flag=wx.ADJUST_MINSIZE |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.RIGHT | wx.LEFT,
+ border=5)
+ sizer.Add(item=btns_sizer, proportion=0,
+ flag=wx.ALIGN_CENTER_VERTICAL |
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.RIGHT | wx.LEFT,
+ border=5)
+
self.SetAutoLayout(True)
self.SetSizer(sizer)
sizer.Fit(self)
sizer.SetSizeHints(self)
self.Layout()
- # end wxGlade
- def _getRCValue(self,value):
+ def _read_grassrc(self):
+ """
+ Read variables from $HOME/.grassrc6 file
+ """
+ grassrc = {}
+
+ gisrc = os.getenv("GISRC")
+
+ if gisrc and os.path.isfile(gisrc):
+ try:
+ rc = open(gisrc, "r")
+ for line in rc.readlines():
+ key, val = line.split(":")
+ grassrc[key.strip()] = val.strip()
+ finally:
+ rc.close()
+
+ return grassrc
+
+ def _getRCValue(self, value):
+ "Return GRASS variable (read from GISRC)"""
+
if self.grassrc.has_key(value):
return self.grassrc[value]
else:
return None
def OnWizard(self,event):
+ """Location wizard started"""
import location_wizard
reload(location_wizard)
gWizard = location_wizard.GWizard(self, self.tgisdbase.GetValue())
@@ -290,7 +382,7 @@
def RenameMapset(self):
"""
- Renames selected mapset
+ Rename selected mapset
"""
location = location=self.listOfLocations[self.lblocations.GetSelection()]
@@ -313,7 +405,7 @@
def RenameLocation(self):
"""
- Renames selected location
+ Rename selected location
"""
location = location=self.listOfLocations[self.lblocations.GetSelection()]
@@ -337,7 +429,7 @@
def DeleteMapset(self):
"""
- Deletes selected mapset
+ Delete selected mapset
"""
location = location=self.listOfLocations[self.lblocations.GetSelection()]
@@ -357,7 +449,7 @@
def DeleteLocation(self):
"""
- Deletes selected location
+ Delete selected location
"""
location = location=self.listOfLocations[self.lblocations.GetSelection()]
@@ -374,7 +466,7 @@
dlg.Destroy()
def UpdateLocations(self,dbase):
-
+ """Update list of locations"""
self.listOfLocations = []
for location in glob.glob(os.path.join(dbase,"*")):
try:
@@ -387,7 +479,7 @@
return self.listOfLocations
def UpdateMapsets(self,location):
-
+ """Update list of mapsets"""
self.listOfMapsets = []
for mapset in glob.glob(os.path.join(location,"*")):
if os.path.isdir(mapset):
@@ -397,6 +489,7 @@
return self.listOfMapsets
def OnSelectLocation(self,event):
+ """Location selected"""
if self.lblocations.GetSelection() > -1:
self.UpdateMapsets(os.path.join(
self.gisdbase,self.listOfLocations[self.lblocations.GetSelection()]))
@@ -406,10 +499,12 @@
self.lbmapsets.InsertItems(self.listOfMapsets,0)
def OnSelectMapset(self,event):
+ """Mapset selected"""
#self.bstart.Enable(True)
pass
def OnSetDatabase(self,event):
+ """Database set"""
self.gisdbase = self.tgisdbase.GetValue()
self.UpdateLocations(self.gisdbase)
self.lblocations.Clear()
@@ -418,7 +513,7 @@
self.OnSelectLocation(event)
def OnBrowse(self, event):
-
+ """'Browse' button clicked"""
grassdata = None
dlg = wx.DirDialog(self, "Choose a GRASS directory:",
@@ -437,31 +532,33 @@
event.Skip()
def OnCreateMapset(self,event):
+ """Create new mapset"""
self.gisdbase = self.tgisdbase.GetValue()
location = self.listOfLocations[self.lblocations.GetSelection()]
- try:
- mapset = self.tnewmapset.GetValue()
- os.mkdir(os.path.join(self.gisdbase,location,mapset))
- # copy WIND file and its permissions from PERMANENT and set permissions to u+rw,go+r
- shutil.copy(os.path.join(self.gisdbase,location,'PERMANENT','WIND'),
- os.path.join(self.gisdbase,location,mapset))
-# os.chmod(os.path.join(database,location,mapset,'WIND'), 0644)
- self.OnSelectLocation(None)
- self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset))
- except StandardError, e:
- dlg = wx.MessageDialog(self, "Could not create new mapset: %s"
- % e,"Can not create mapset", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
+ dlg = wx.TextEntryDialog(parent=self,
+ message=_('Enter name for new mapset:'),
+ caption='Rename selected mapset')
- def OnKeyPressedInMapset(self,event):
- if wx.WXK_RETURN == event.KeyCode:
- self.OnCreateMapset(None)
- else:
- #self.bmapset.Enable(True)
- event.Skip()
+ if dlg.ShowModal() == wx.ID_OK:
+ mapset = dlg.GetValue()
+ try:
+ os.mkdir(os.path.join(self.gisdbase, location, mapset))
+ # copy WIND file and its permissions from PERMANENT and set permissions to u+rw,go+r
+ shutil.copy(os.path.join(self.gisdbase, location, 'PERMANENT', 'WIND'),
+ os.path.join(self.gisdbase, location, mapset))
+ # os.chmod(os.path.join(database,location,mapset,'WIND'), 0644)
+ self.OnSelectLocation(None)
+ self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset))
+ except StandardError, e:
+ dlg = wx.MessageDialog(parent=self, message=_("Unable to create new mapset: %s") % e,
+ caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+ return True
+
def OnStart(self, event):
print "g.gisenv set=GISDBASE='%s';" % self.tgisdbase.GetValue()
print "g.gisenv set=LOCATION_NAME='%s';" % self.listOfLocations[self.lblocations.GetSelection()]
@@ -469,28 +566,37 @@
self.Destroy()
def OnExit(self, event):
- print "exit"
+ """'Exit' button clicked"""
self.Destroy()
def OnHelp(self, event):
+ """'Help' button clicked"""
wx.MessageBox("Help not yet implemented")
event.Skip()
- def onCloseWindow(self, event):
- print "exit"
+ def OnCloseWindow(self, event):
+ """Close window event"""
event.Skip()
class StartUp(wx.App):
+ """Start-up application"""
+
def OnInit(self):
wx.InitAllImageHandlers()
- StartUp = GRASSStartup(None, -1, "")
+ StartUp = GRASSStartup()
self.SetTopWindow(StartUp)
StartUp.Show()
return 1
-# end of class StartUp
-
if __name__ == "__main__":
+
+ if os.getenv("GISBASE") is None:
+ print >> sys.stderr, "Failed to start GUI, GRASS GIS is not running."
+ else:
+ import gettext
+ gettext.install("GRASSStartUp") # replace with the appropriate catalog name
+
+ import gui_modules.gcmd as gcmd
- GRASSStartUp = StartUp(0)
- GRASSStartUp.MainLoop()
+ GRASSStartUp = StartUp(0)
+ GRASSStartUp.MainLoop()
Modified: trunk/grassaddons/gui/icons/icon.py
===================================================================
--- trunk/grassaddons/gui/icons/icon.py 2007-10-19 19:05:38 UTC (rev 1145)
+++ trunk/grassaddons/gui/icons/icon.py 2007-10-19 22:17:26 UTC (rev 1146)
@@ -114,7 +114,7 @@
# merge icons dictionaries, join paths
try:
- if not os.path.exists(iconpath):
+ if iconpath and not os.path.exists(iconpath):
raise OSError
if iconpath is not None and iconpath.find('silk') > -1: # silk icon theme
from silk import IconsSilk as icons_img
From landa at grass.itc.it Sat Oct 20 00:25:12 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:46 2007
Subject: [grass-addons] r1147 - trunk/grassaddons/gui
Message-ID: <200710192225.l9JMPCK9027002@grass.itc.it>
Author: landa
Date: 2007-10-20 00:25:07 +0200 (Sat, 20 Oct 2007)
New Revision: 1147
Modified:
trunk/grassaddons/gui/gis_set.py
Log:
Center on screen
Modified: trunk/grassaddons/gui/gis_set.py
===================================================================
--- trunk/grassaddons/gui/gis_set.py 2007-10-19 22:17:26 UTC (rev 1146)
+++ trunk/grassaddons/gui/gis_set.py 2007-10-19 22:25:07 UTC (rev 1147)
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
"""
MODULE: gis_set.py
@@ -584,6 +582,7 @@
def OnInit(self):
wx.InitAllImageHandlers()
StartUp = GRASSStartup()
+ StartUp.CenterOnScreen()
self.SetTopWindow(StartUp)
StartUp.Show()
return 1
From landa at grass.itc.it Sat Oct 20 00:28:25 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:46 2007
Subject: [grass-addons] r1148 - trunk/grassaddons/gui
Message-ID: <200710192228.l9JMSPRq027024@grass.itc.it>
Author: landa
Date: 2007-10-20 00:28:09 +0200 (Sat, 20 Oct 2007)
New Revision: 1148
Modified:
trunk/grassaddons/gui/gis_set.py
trunk/grassaddons/gui/wxgui.py
Log:
Delete prop:executable.
Property changes on: trunk/grassaddons/gui/gis_set.py
___________________________________________________________________
Name: svn:executable
- *
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-19 22:25:07 UTC (rev 1147)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-19 22:28:09 UTC (rev 1148)
@@ -1,5 +1,3 @@
-#!/usr/bin python
-
"""
MODULE: wxgui.py
Property changes on: trunk/grassaddons/gui/wxgui.py
___________________________________________________________________
Name: svn:executable
- *
From landa at grass.itc.it Sat Oct 20 11:51:52 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:46 2007
Subject: [grass-addons] r1149 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710200951.l9K9pq1n026747@grass.itc.it>
Author: landa
Date: 2007-10-20 11:51:46 +0200 (Sat, 20 Oct 2007)
New Revision: 1149
Added:
trunk/grassaddons/gui/gui_modules/location_wizard.py
trunk/grassaddons/gui/gui_modules/states.txt
Removed:
trunk/grassaddons/gui/location_wizard.py
trunk/grassaddons/gui/states.txt
Modified:
trunk/grassaddons/gui/gis_set.py
Log:
Cleaning of gis_set.py, some bugs fixed.
location_wizard module moved to gui_modules directory.
Modified: trunk/grassaddons/gui/gis_set.py
===================================================================
--- trunk/grassaddons/gui/gis_set.py 2007-10-19 22:28:09 UTC (rev 1148)
+++ trunk/grassaddons/gui/gis_set.py 2007-10-20 09:51:46 UTC (rev 1149)
@@ -3,6 +3,7 @@
CLASSES:
* GRASSStartup
+ * HelpWindow
* StartUp
PURPOSE: Initialization module for wxPython GRASS GUI.
@@ -25,9 +26,12 @@
import shutil
import wx
+import wx.html
import wx.lib.rcsizer as rcs
import wx.lib.filebrowsebutton as filebrowse
+from gui_modules import location_wizard
+
class GRASSStartup(wx.Frame):
"""GRASS start-up screen"""
def __init__(self, parent=None, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE):
@@ -354,7 +358,6 @@
def OnWizard(self,event):
"""Location wizard started"""
- import location_wizard
reload(location_wizard)
gWizard = location_wizard.GWizard(self, self.tgisdbase.GetValue())
if gWizard.location != None:
@@ -383,21 +386,23 @@
Rename selected mapset
"""
- location = location=self.listOfLocations[self.lblocations.GetSelection()]
- mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
- dlg = wx.TextEntryDialog(
- self, 'Current name: %s\nEnter new name:' % mapset,
- 'Rename selected mapset')
+ location = self.listOfLocations[self.lblocations.GetSelection()]
+ mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
+ dlg = wx.TextEntryDialog(parent=self,
+ message=_('Current name: %s\nEnter new name:') % mapset,
+ caption=_('Rename selected mapset'))
+
if dlg.ShowModal() == wx.ID_OK:
newmapset = dlg.GetValue()
- try:
- os.rename(os.path.join(self.gisdbase,location,mapset),\
- os.path.join(self.gisdbase,location,newmapset))
- self.OnSelectLocation(None)
- self.lbmapsets.SetSelection(self.listOfMapsets.index(newmapset))
- except:
- wx.MessageBox('Mapset could not be renamed')
+ if newmapset != mapset:
+ try:
+ os.rename(os.path.join(self.gisdbase, location, mapset),
+ os.path.join(self.gisdbase, location, newmapset))
+ self.OnSelectLocation(None)
+ self.lbmapsets.SetSelection(self.listOfMapsets.index(newmapset))
+ except:
+ wx.MessageBox(message=_('Unable to rename mapset'))
dlg.Destroy()
@@ -406,23 +411,25 @@
Rename selected location
"""
- location = location=self.listOfLocations[self.lblocations.GetSelection()]
- dlg = wx.TextEntryDialog(
- self, 'Current name: %s\nEnter new name:' % location,
- 'Rename selected location')
+ location = self.listOfLocations[self.lblocations.GetSelection()]
+ dlg = wx.TextEntryDialog(parent=self,
+ message=_('Current name: %s\nEnter new name:') % location,
+ caption=_('Rename selected location'))
+
if dlg.ShowModal() == wx.ID_OK:
newlocation = dlg.GetValue()
- mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
- try:
- os.rename(os.path.join(self.gisdbase,location),\
- os.path.join(self.gisdbase,newlocation))
- self.UpdateLocations(self.gisdbase)
- self.lblocations.SetSelection(self.listOfLocations.index(newlocation))
+ if newlocation != location:
+ mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
+ try:
+ os.rename(os.path.join(self.gisdbase, location),
+ os.path.join(self.gisdbase, newlocation))
+ self.UpdateLocations(self.gisdbase)
+ self.lblocations.SetSelection(self.listOfLocations.index(newlocation))
+ self.UpdateMapsets(newlocation)
+ except:
+ wx.MessageBox(message=_('Unable to rename location'))
- except:
- wx.MessageBox('Location could not be renamed')
-
dlg.Destroy()
def DeleteMapset(self):
@@ -430,18 +437,23 @@
Delete selected mapset
"""
- location = location=self.listOfLocations[self.lblocations.GetSelection()]
- mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
- dlg = wx.MessageDialog(self, "Do you want to continue with deleting the mapset?",
- "WARNING! Mapset '%s', and ALL MAPS it contains will be PERMANENTLY DELETED!"
- % mapset,wx.YES_NO|wx.NO_DEFAULT|wx.ICON_EXCLAMATION)
+ location = self.listOfLocations[self.lblocations.GetSelection()]
+ mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
+
+ dlg = wx.MessageDialog(parent=self, message=_("Do you want to continue with deleting mapset <%s> "
+ "from location <%s>?\n\n"
+ "ALL MAPS included in this mapset will be "
+ "PERMANENTLY DELETED!") % (mapset, location),
+ caption=_("Delete selected mapset"),
+ style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
+
if dlg.ShowModal() == wx.ID_YES:
try:
- shutil.rmtree(os.path.join(self.gisdbase,location,mapset))
+ shutil.rmtree(os.path.join(self.gisdbase, location, mapset))
self.OnSelectLocation(None)
self.lbmapsets.SetSelection(0)
except:
- wx.MessageBox('Mapset could not be deleted')
+ wx.MessageBox(message=_('Unable to delete mapset'))
dlg.Destroy()
@@ -450,64 +462,84 @@
Delete selected location
"""
- location = location=self.listOfLocations[self.lblocations.GetSelection()]
- dlg = wx.MessageDialog(self, "Do you want to continue with deleting the location?",
- "WARNING! Location '%s', and ALL MAPSETS and MAPS it contains will be PERMANENTLY DELETED!"
- % location,wx.YES_NO|wx.NO_DEFAULT|wx.ICON_EXCLAMATION)
+ location = self.listOfLocations[self.lblocations.GetSelection()]
+
+ dlg = wx.MessageDialog(parent=self, message=_("Do you want to continue with deleting "
+ "location <%s>?\n\n"
+ "ALL MAPS included in this location will be "
+ "PERMANENTLY DELETED!") % (location),
+ caption=_("Delete selected location"),
+ style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
+
if dlg.ShowModal() == wx.ID_YES:
try:
- shutil.rmtree(os.path.join(self.gisdbase,location))
+ shutil.rmtree(os.path.join(self.gisdbase, location))
self.UpdateLocations(self.gisdbase)
+ self.lblocations.SetSelection(0)
+ self.OnSelectLocation(None)
+ self.lbmapsets.SetSelection(0)
except:
- wx.MessageBox('Location could not be deleted')
+ wx.MessageBox(message=_('Unable to delete location'))
dlg.Destroy()
- def UpdateLocations(self,dbase):
+ def UpdateLocations(self, dbase):
"""Update list of locations"""
self.listOfLocations = []
- for location in glob.glob(os.path.join(dbase,"*")):
+
+ for location in glob.glob(os.path.join(dbase, "*")):
try:
- if os.path.join(location,"PERMANENT") in glob.glob(os.path.join(location,"*")):
+ if os.path.join(location, "PERMANENT") in glob.glob(os.path.join(location, "*")):
self.listOfLocations.append(os.path.basename(location))
except:
pass
+
self.lblocations.Clear()
- self.lblocations.InsertItems(self.listOfLocations,0)
+ self.lblocations.InsertItems(self.listOfLocations, 0)
+
return self.listOfLocations
- def UpdateMapsets(self,location):
+ def UpdateMapsets(self, location):
"""Update list of mapsets"""
self.listOfMapsets = []
- for mapset in glob.glob(os.path.join(location,"*")):
+
+ for mapset in glob.glob(os.path.join(self.gisdbase, location, "*")):
if os.path.isdir(mapset):
self.listOfMapsets.append(os.path.basename(mapset))
+
self.lbmapsets.Clear()
self.lbmapsets.InsertItems(self.listOfMapsets,0)
+
return self.listOfMapsets
- def OnSelectLocation(self,event):
+ def OnSelectLocation(self, event):
"""Location selected"""
if self.lblocations.GetSelection() > -1:
- self.UpdateMapsets(os.path.join(
- self.gisdbase,self.listOfLocations[self.lblocations.GetSelection()]))
+ self.UpdateMapsets(os.path.join(self.gisdbase,
+ self.listOfLocations[self.lblocations.GetSelection()]))
else:
self.listOfMapsets = []
+
self.lbmapsets.Clear()
- self.lbmapsets.InsertItems(self.listOfMapsets,0)
-
+ self.lbmapsets.InsertItems(self.listOfMapsets, 0)
+ self.lbmapsets.SetSelection(0)
+
def OnSelectMapset(self,event):
"""Mapset selected"""
- #self.bstart.Enable(True)
- pass
+ # self.bstart.Enable(True)
+ event.Skip()
def OnSetDatabase(self,event):
"""Database set"""
self.gisdbase = self.tgisdbase.GetValue()
+
self.UpdateLocations(self.gisdbase)
self.lblocations.Clear()
self.lblocations.InsertItems(self.listOfLocations,0)
- if self.listOfLocations != []: self.lblocations.SetSelection(0)
+
+ if self.listOfLocations != []:
+ self.lblocations.SetSelection(0)
+
self.OnSelectLocation(event)
def OnBrowse(self, event):
@@ -515,7 +547,7 @@
grassdata = None
dlg = wx.DirDialog(self, "Choose a GRASS directory:",
- style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
+ style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
if dlg.ShowModal() == wx.ID_OK:
self.gisdbase = dlg.GetPath()
self.tgisdbase.SetValue(self.gisdbase)
@@ -524,6 +556,7 @@
self.OnSetDatabase(event)
def OnKeyPressedInDbase(self,event):
+ """GIS data directory changed"""
if wx.WXK_RETURN == event.KeyCode:
self.OnSetDatabase(event)
else:
@@ -558,24 +591,64 @@
return True
def OnStart(self, event):
- print "g.gisenv set=GISDBASE='%s';" % self.tgisdbase.GetValue()
- print "g.gisenv set=LOCATION_NAME='%s';" % self.listOfLocations[self.lblocations.GetSelection()]
- print "g.gisenv set=MAPSET='%s';" % self.listOfMapsets[self.lbmapsets.GetSelection()]
+ """'Start GRASS' button clicked"""
+ gcmd.Command(["g.gisenv",
+ "set=GISDBASE=%s" % self.tgisdbase.GetValue()])
+ gcmd.Command(["g.gisenv",
+ "set=LOCATION_NAME=%s" % self.listOfLocations[self.lblocations.GetSelection()]])
+ gcmd.Command(["g.gisenv",
+ "set=MAPSET=%s" % self.listOfMapsets[self.lbmapsets.GetSelection()]])
+
self.Destroy()
+ sys.exit(0)
def OnExit(self, event):
"""'Exit' button clicked"""
self.Destroy()
+ sys.exit (2)
def OnHelp(self, event):
"""'Help' button clicked"""
- wx.MessageBox("Help not yet implemented")
+ file=os.path.join(self.gisbase, "docs", "html", "helptext.html")
+
+ helpFrame = HelpWindow(parent=self, id=wx.ID_ANY,
+ title=_("GRASS Quickstart"),
+ size=(640, 480),
+ file=file)
+ helpFrame.Show(True)
+
event.Skip()
def OnCloseWindow(self, event):
"""Close window event"""
event.Skip()
+ sys.exit(2)
+class HelpWindow(wx.Frame):
+ """GRASS Quickstart help window"""
+ def __init__(self, parent, id, title, size, file):
+
+ wx.Frame.__init__(self, parent=parent, id=id, title=title, size=size)
+
+ sizer = wx.BoxSizer(wx.VERTICAL)
+
+ # text
+ helpFrame = wx.html.HtmlWindow(parent=self, id=wx.ID_ANY)
+ helpFrame.SetStandardFonts (size = 10)
+ helpFrame.SetBorders(10)
+ wx.InitAllImageHandlers()
+
+ helpFrame.LoadFile(file)
+ self.Ok = True
+
+ sizer.Add(item=helpFrame, proportion=1, flag=wx.EXPAND)
+
+ self.SetAutoLayout(True)
+ self.SetSizer(sizer)
+ # sizer.Fit(self)
+ # sizer.SetSizeHints(self)
+ self.Layout()
+
class StartUp(wx.App):
"""Start-up application"""
Copied: trunk/grassaddons/gui/gui_modules/location_wizard.py (from rev 1148, trunk/grassaddons/gui/location_wizard.py)
===================================================================
--- trunk/grassaddons/gui/gui_modules/location_wizard.py (rev 0)
+++ trunk/grassaddons/gui/gui_modules/location_wizard.py 2007-10-20 09:51:46 UTC (rev 1149)
@@ -0,0 +1,1863 @@
+"""
+MODULE: location_wizard.py
+
+CLASSES:
+ * TitledPage
+ * DatabasePage
+ * CoordinateSystemPage
+ * ProjectionsPage
+ * ProjTypePage
+ * DatumPage
+ * EllipsePage
+ * GeoreferencedFilePage
+ * EPSGPage
+ * CustomPage
+ * SummaryPage
+ * RegionDef
+ * GWizard
+
+PURPOSE: Create a new GRASS location. User can choose from multiple methods
+
+AUTHORS: The GRASS Development Team
+ Michael Barton
+ Jachym Cepicky
+
+COPYRIGHT: (C) 2006-2007 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.
+"""
+import os
+import shutil
+import re
+import string
+import sys
+
+import wx
+import wx.lib.mixins.listctrl as listmix
+import wx.lib.rcsizer as rcs
+import wx.wizard as wiz
+
+import gui_modules
+import gui_modules.gcmd as gcmd
+try:
+ import subprocess
+except:
+ from compat import subprocess
+
+
+gmpath = gui_modules.__path__[0]
+sys.path.append(gmpath)
+
+
+global coordsys
+global north
+global south
+global east
+global west
+global resolution
+global wizerror
+
+coordsys = ''
+north = ''
+south = ''
+east = ''
+west = ''
+resolution = ''
+
+class TitledPage(wiz.WizardPageSimple):
+ """
+ Class to make wizard pages. Generic methods to make
+ labels, text entries, and buttons.
+ """
+ def __init__(self, parent, title):
+ wiz.WizardPageSimple.__init__(self, parent)
+
+ self.title = wx.StaticText(self,-1,title)
+ self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD))
+
+ self.sizer = rcs.RowColSizer()
+ tmpsizer = wx.BoxSizer(wx.VERTICAL)
+
+ tmpsizer.Add(self.title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
+ tmpsizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0)
+ tmpsizer.Add(self.sizer, wx.EXPAND)
+
+ self.SetSizer(tmpsizer)
+ self.SetAutoLayout(True)
+
+ def MakeRLabel(self, text=""):
+ """Make right-aligned label"""
+ try:
+ if text[-1] != " ":
+ text += " "
+ except:
+ pass
+ return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT)
+
+ def MakeLLabel(self, text=""):
+ """Make left-aligned label"""
+ try:
+ if text[-1] != " ":
+ text += " "
+ except:
+ pass
+ return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT)
+
+ def MakeTextCtrl(self,text='', size=(100,-1)):
+ """Generic text control"""
+ return wx.TextCtrl(self,-1, text, size=size)
+
+ def MakeButton(self,text, size=(75,25)):
+ """Generic button"""
+ return wx.Button(self, -1, text,
+ style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL,
+ size=size)
+
+
+class DatabasePage(TitledPage):
+ """
+ Wizard page for setting GIS data directory and location name
+ """
+ def __init__(self, wizard, parent, grassdatabase):
+ TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name")
+
+ self.grassdatabase = grassdatabase
+ self.location = ''
+
+ # buttons
+ self.bbrowse = self.MakeButton("Browse...")
+
+ # text controls
+ self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1))
+ self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1))
+
+ # layout
+ self.sizer.Add(self.MakeRLabel("GIS Data Directory:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=1, col=2)
+ self.sizer.Add(self.tgisdbase,0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=1, col=3)
+ self.sizer.Add(self.bbrowse, 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=1, col=4)
+ #
+ self.sizer.Add(self.MakeRLabel("Project Location"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=2, col=2)
+ self.sizer.Add(self.tlocation,0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=2, col=3)
+ self.sizer.Add(self.MakeRLabel("(projection/coordinate system)"), 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5,
+ row=2, col=4)
+
+ # bindings
+ self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
+
+ def OnBrowse(self, event):
+ dlg = wx.DirDialog(self, "Choose GRASS data directory:", os.getcwd(),wx.DD_DEFAULT_STYLE)
+ if dlg.ShowModal() == wx.ID_OK:
+ self.grassdatabase = dlg.GetPath()
+ self.tgisdbase.SetValue(self.grassdatabase)
+ dlg.Destroy()
+
+ def onPageChanging(self,event=None):
+ if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())):
+ dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\
+ % str(self.tlocation.GetValue()),"Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ event.Veto()
+ return
+
+ if not self.tlocation.GetValue():
+ dlg = wx.MessageDialog(self, "Could not create new location: location not set "\
+ ,"Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ event.Veto()
+ return
+
+ self.location = self.tlocation.GetValue()
+ self.grassdatabase = self.tgisdbase.GetValue()
+
+ def OnPageChanged(self,event=None):
+ self.grassdatabase = self.tgisdbase.GetValue()
+ self.location = self.tlocation.GetValue()
+
+
+class CoordinateSystemPage(TitledPage):
+ """
+ Wizard page for choosing method for location creation
+ """
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Choose method for creating a new location")
+
+ self.parent = parent
+ global coordsys
+
+ # toggles
+ self.radio1 = wx.RadioButton( self, -1, " Select coordinate system " , style = wx.RB_GROUP)
+ self.radio2 = wx.RadioButton( self, -1, " Select EPSG code for coordinate system " )
+ self.radio3 = wx.RadioButton( self, -1, " Use coordinate system of selected georeferenced file " )
+ self.radio4 = wx.RadioButton( self, -1, " Create custom PROJ.4 parameters string for coordinate system " )
+ self.radio5 = wx.RadioButton( self, -1, " Create arbitrary non-earth coordinate system (XY)" )
+
+ # layout
+ self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2)
+ self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2)
+ self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2)
+ self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2)
+ self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2)
+
+ # bindings
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId())
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId())
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId())
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId())
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId())
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+
+ def OnPageChange(self,event=None):
+ global coordsys
+ if event.GetDirection() and not coordsys:
+ wx.MessageBox('You must select a coordinate system')
+ event.Veto()
+
+ def SetVal(self,event):
+ global coordsys
+ if event.GetId() == self.radio1.GetId():
+ coordsys = "proj"
+ self.SetNext(self.parent.projpage)
+ self.parent.sumpage.SetPrev(self.parent.datumpage)
+ elif event.GetId() == self.radio2.GetId():
+ coordsys = "epsg"
+ self.SetNext(self.parent.epsgpage)
+ self.parent.sumpage.SetPrev(self.parent.epsgpage)
+ elif event.GetId() == self.radio3.GetId():
+ coordsys = "file"
+ self.SetNext(self.parent.filepage)
+ self.parent.sumpage.SetPrev(self.parent.filepage)
+ elif event.GetId() == self.radio4.GetId():
+ coordsys = "custom"
+ self.SetNext(self.parent.custompage)
+ self.parent.sumpage.SetPrev(self.parent.custompage)
+ elif event.GetId() == self.radio5.GetId():
+ coordsys = "xy"
+ self.SetNext(self.parent.sumpage)
+ set.parent.sumpage.SetPrev(self.parent.csystemspage)
+
+class ProjectionsPage(TitledPage):
+ """
+ Wizard page for selecting projection (select coordinate system option)
+ """
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Choose projection")
+
+ self.parent = parent
+ self.proj = ''
+ self.projdesc = ''
+
+ # text input
+ self.tproj = self.MakeTextCtrl("", size=(200,-1))
+
+ # search box
+ self.searchb = wx.SearchCtrl(self, size=(200,-1),
+ style=wx.TE_PROCESS_ENTER)
+
+ self.projlist = wx.ListCtrl(self, id=wx.ID_ANY,
+ size=(650,275),
+ style=wx.LC_REPORT |
+ wx.LC_HRULES |
+ wx.EXPAND)
+ self.projlist.InsertColumn(0, 'Code')
+ self.projlist.InsertColumn(1, 'Description')
+ self.projlist.SetColumnWidth(0, 100)
+ self.projlist.SetColumnWidth(1, 500)
+
+ # layout
+ self.sizer.Add(self.MakeRLabel("Projection code:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=2)
+ self.sizer.Add(self.tproj, 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=3)
+
+ self.sizer.Add(self.MakeRLabel("Search in projection description"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=2)
+ self.sizer.Add(self.searchb, 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=3)
+
+ self.sizer.Add(self.projlist,
+ wx.EXPAND |
+ wx.ALIGN_LEFT |
+ wx.ALL, 5, row=3, col=1, colspan=4)
+
+ # events
+ self.Bind(wx.EVT_TEXT, self.OnText, self.tproj)
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.projlist)
+ self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+
+ self._onBrowseProj(None, None)
+
+ def OnPageChange(self,event):
+ if event.GetDirection() and self.proj not in self.parent.projections:
+ wx.MessageBox('You must select a valid projection in order to continue')
+ event.Veto()
+ if self.proj == 'utm':
+ self.parent.projtypepage.text_utm.SetEditable(True)
+ self.parent.projtypepage.hemischoices = ['north','south']
+ else:
+ self.parent.projtypepage.text_utm.SetValue('')
+ self.parent.projtypepage.text_utm.SetEditable(False)
+ self.parent.projtypepage.hemischoices = []
+
+ def OnText(self, event):
+ self.proj = event.GetString()
+ if self.proj in self.parent.projections:
+ self.projdesc = self.parent.projections[self.proj]
+
+ def OnDoSearch(self,event):
+ str = self.searchb.GetValue()
+ listItem = self.projlist.GetColumn(1)
+
+ for i in range(self.projlist.GetItemCount()):
+ listItem = self.projlist.GetItem(i,1)
+ if listItem.GetText().find(str) > -1:
+ self.proj = self.projlist.GetItem(i, 0).GetText()
+ self.tproj.SetValue(self.proj)
+ break
+
+ self._onBrowseProj(None,str)
+
+ def OnItemSelected(self,event):
+ index = event.m_itemIndex
+ item = event.GetItem()
+
+ self.proj = item.GetText()
+ self.projdesc = self.projlist.GetItem(index, 1).GetText()
+ self.tproj.SetValue(self.proj)
+
+ def _onBrowseProj(self,event,search=None):
+ try:
+ projlist = self.parent.projections.items()
+ projlist.sort()
+ self.projlist.DeleteAllItems()
+ for proj,desc in projlist:
+ entry = self.projlist.GetItemCount()
+ if search and (proj.lower().find(search.lower()) > -1 or \
+ desc.lower().find(search.lower()) > -1) or \
+ not search:
+ index = self.projlist.InsertStringItem(entry,proj)
+ self.projlist.SetStringItem(index,1,desc)
+
+ self.projlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.projlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.projlist.SendSizeEvent()
+
+ except StandardError, e:
+ dlg = wx.MessageDialog(self, "Could not read projections list: %s " % e,
+ "Could not read projections", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+class ProjTypePage(TitledPage):
+ """
+ Wizard page for selecting method of setting coordinate system parameters
+ (select coordinate system option)
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters")
+ global coordsys
+
+ self.utmzone = ''
+ self.utmhemisphere = ''
+ self.hemischoices = ["north","south"]
+ self.parent = parent
+
+ self.radio1 = wx.RadioButton( self, -1, " Select datum with associated ellipsoid", style = wx.RB_GROUP )
+ self.radio2 = wx.RadioButton( self, -1, " Select ellipsoid" )
+ self.title_utm = self.MakeLLabel("Set zone for UTM projection")
+ self.text_utm = self.MakeTextCtrl(size=(100,-1))
+ self.label_utm = self.MakeRLabel("Zone: ")
+ self.hemisphere = wx.Choice(self, -1, (100, 50), choices = self.hemischoices)
+ self.label_hemisphere = self.MakeRLabel("Hemisphere for zone: ")
+
+ # layout
+ self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2)
+ self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2)
+ self.sizer.Add(self.title_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=4,col=2)
+ self.sizer.Add(self.label_utm, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1)
+ self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2)
+ self.sizer.Add(self.label_hemisphere, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=6,col=1)
+ self.sizer.Add(self.hemisphere, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=6,col=2)
+
+ self.title_utm.Hide()
+ self.text_utm.Hide()
+ self.label_utm.Hide()
+ self.hemisphere.Hide()
+ self.label_hemisphere.Hide()
+
+ # bindings
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId())
+ self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId())
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
+
+ def OnPageChange(self,event=None):
+ if event.GetDirection() and self.parent.projpage.proj == 'utm' and self.utmzone == '':
+ wx.MessageBox('You must set a zone for a UTM projection')
+ event.Veto()
+ self.title_utm.Hide()
+ self.text_utm.Hide()
+ self.label_utm.Hide()
+ self.hemisphere.Hide()
+ self.label_hemisphere.Hide()
+
+ def OnEnterPage(self,event):
+ if self.parent.projpage.proj == 'utm':
+ self.title_utm.Show()
+ self.text_utm.Show()
+ self.label_utm.Show()
+ self.hemisphere.Show()
+ self.label_hemisphere.Show()
+
+ self.Bind(wx.EVT_CHOICE, self.OnHemisphere, self.hemisphere)
+ self.Bind(wx.EVT_TEXT, self.GetUTM, self.text_utm)
+
+ def SetVal(self, event):
+ global coordsys
+ if event.GetId() == self.radio1.GetId():
+ self.SetNext(self.parent.datumpage)
+ self.parent.sumpage.SetPrev(self.parent.datumpage)
+ elif event.GetId() == self.radio2.GetId():
+ self.SetNext(self.parent.ellipsepage)
+ self.parent.sumpage.SetPrev(self.parent.ellipsepage)
+
+ def GetUTM(self, event):
+ self.utmzone = event.GetString()
+
+ def OnHemisphere(self, event):
+ self.utmhemisphere = event.GetString()
+
+
+class DatumPage(TitledPage):
+ """
+ Wizard page for selecting datum (with associated ellipsoid)
+ and datum transformation parameters (select coordinate system option)
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Specify geodetic datum")
+
+ self.parent = parent
+ self.datum = ''
+ self.datumdesc = ''
+ self.ellipsoid = ''
+ self.datumparams = ''
+ self.transform = ''
+ self.transregion = ''
+ self.transparams = ''
+ self.hastransform = False
+ self.proj4params = ''
+
+ # text input
+ self.tdatum = self.MakeTextCtrl("", size=(200,-1))
+ self.ttrans = self.MakeTextCtrl("", size=(200,-1))
+
+ # search box
+ self.searchb = wx.SearchCtrl(self, size=(200,-1),
+ style=wx.TE_PROCESS_ENTER)
+
+ # button
+# self.bupdate = self.MakeButton("Update trans. parms.",
+# size=(-1,-1))
+
+ # create list control for datum/elipsoid list
+ self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY,
+ size=(650,150),
+ style=wx.LC_REPORT|
+ wx.LC_HRULES|
+ wx.EXPAND)
+ self.datumlist.InsertColumn(0, 'Code')
+ self.datumlist.InsertColumn(1, 'Description')
+ self.datumlist.InsertColumn(2, 'Ellipsoid')
+ self.datumlist.SetColumnWidth(0, 100)
+ self.datumlist.SetColumnWidth(1, 250)
+ self.datumlist.SetColumnWidth(2, 100)
+
+ # create list control for datum transformation parameters list
+ self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY,
+ size=(650,125),
+ style=wx.LC_REPORT |
+ wx.LC_HRULES |
+ wx.EXPAND)
+ self.transformlist.InsertColumn(0, 'Code')
+ self.transformlist.InsertColumn(1, 'Datum')
+ self.transformlist.InsertColumn(2, 'Description')
+ self.transformlist.SetColumnWidth(0, 50)
+ self.transformlist.SetColumnWidth(1, 125)
+ self.transformlist.SetColumnWidth(2, 250)
+
+ # layout
+ self.sizer.Add(self.MakeRLabel("Datum code:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=1)
+ self.sizer.Add(self.tdatum, 0 ,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=2)
+# self.sizer.Add(self.bupdate, 0 ,
+# wx.ALIGN_LEFT |
+# wx.ALIGN_CENTER_VERTICAL |
+# wx.ALL, 5, row=1, col=3)
+ self.sizer.Add(self.MakeRLabel("Search in description:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=2)
+ self.sizer.Add(self.searchb, 0 ,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=2)
+
+ self.sizer.Add(self.datumlist,
+ wx.EXPAND |
+ wx.ALIGN_LEFT |
+ wx.ALL, 5, row=3, col=1, colspan=4)
+
+ self.sizer.Add(self.MakeRLabel("Transformation parameters:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=5)
+ self.sizer.Add(self.ttrans, 0 ,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=5, col=2)
+
+ self.sizer.Add(self.transformlist,
+ wx.EXPAND |
+ wx.ALIGN_LEFT |
+ wx.ALL, 5, row=6, col=1, colspan=4)
+
+ # events
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnDatumSelected, self.datumlist)
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+# self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams)
+ self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
+ self.Bind(wx.EVT_TEXT, self.OnDText, self.tdatum)
+
+ self._onBrowseDatums(None,None)
+
+ def OnPageChange(self,event):
+ self.proj4params = ''
+ if event.GetDirection() and self.datum not in self.parent.datums:
+ wx.MessageBox('You must select a valid datum in order to continue')
+ event.Veto()
+# if self.hastransform == True and self.transform == '':
+# wx.MessageBox('You must select a datum transform')
+# event.Veto()
+ self.GetNext().SetPrev(self)
+ self.parent.ellipsepage.ellipseparams = self.parent.ellipsoids[self.ellipsoid][1]
+ self.GetNext().SetPrev(self)
+
+ def OnDText(self, event):
+ self.datum = event.GetString()
+ if self.datum in self.parent.datums:
+ self.datumdesc = self.parent.datums[self.datum][0]
+ self.ellipsoid = self.parent.datums[self.datum][1]
+ self.datumparams = self.parent.datums[self.datum][2]
+
+ self._onBrowseParams(None,self.datum)
+
+ def OnTText(self, event):
+ self.transform = event.GetString()
+ if self.transform in self.parent.transforms:
+ self.transdatum = self.parent.transforms[self.transform][0]
+ self.transregion = self.parent.transforms[self.transform][1]
+ self.transparams = self.parent.transforms[self.transform][2]
+
+ def OnDoSearch(self,event):
+ str = self.searchb.GetValue()
+ listItem = self.datumlist.GetColumn(1)
+
+ for i in range(self.datumlist.GetItemCount()):
+ listItem = self.datumlist.GetItem(i,1)
+ if listItem.GetText().find(str) > -1:
+ datum = self.datumlist.GetItem(i, 0)
+ self.tdatum.SetValue(datum.GetText())
+ break
+
+ self._onBrowseDatums(None,str)
+
+ def OnTransformSelected(self,event):
+ index = event.m_itemIndex
+ item = event.GetItem()
+
+ self.transform = item.GetText()
+ self.transdatum = self.parent.transforms[self.transform][0]
+ self.transregion = self.parent.transforms[self.transform][1]
+ self.transparams = self.parent.transforms[self.transform][2]
+
+ self.ttrans.SetValue(str(self.transform))
+
+ def OnDatumSelected(self,event):
+ index = event.m_itemIndex
+ item = event.GetItem()
+
+ self.datum = item.GetText()
+ self.datumdesc = self.parent.datums[self.datum][0]
+ self.ellipsoid = self.parent.datums[self.datum][1]
+ self.datumparams = self.parent.datums[self.datum][2]
+
+ self.tdatum.SetValue(self.datum)
+ self._onBrowseParams(None, self.datum)
+ event.Skip()
+
+ def _onBrowseParams(self, event=None, search=None):
+ search = self.datum.strip()
+ try:
+ self.transform = ''
+ self.transformlist.DeleteAllItems()
+ for item in self.parent.transforms:
+ transdatum = self.parent.transforms[item][0]
+ transregion = self.parent.transforms[item][1]
+ entry = self.transformlist.GetItemCount()
+ if (transdatum.lower() == search.lower()):
+ index = self.transformlist.InsertStringItem(entry,item)
+ self.transformlist.SetStringItem(index,1,transdatum)
+ self.transformlist.SetStringItem(index,2,transregion)
+ self.hastransform = True
+
+ self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
+ self.transformlist.SendSizeEvent()
+
+ except IOError, e:
+ self.transformlist.DeleteAllItems()
+ dlg = wx.MessageDialog(self, "Could not read datum params: %s " % e,
+ "Could not read file", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+ def _onBrowseDatums(self,event,search=None):
+ try:
+ self.datum = ''
+ self.datumlist.DeleteAllItems()
+
+ datumlist = self.parent.datums.items()
+ datumlist.sort()
+ for datum,info in datumlist:
+ datumdesc = info[0]
+ ellipse = info[1]
+ entry = self.datumlist.GetItemCount()
+ if search and (datum.lower().find(search.lower()) > -1 or\
+ datumdesc.lower().find(search.lower()) > -1 or\
+ ellipse.lower().find(search.lower()) > -1) or\
+ not search:
+ index = self.datumlist.InsertStringItem(entry,datum)
+ self.datumlist.SetStringItem(index,1,datumdesc)
+ self.datumlist.SetStringItem(index,2,ellipse)
+
+ self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
+ self.datumlist.SendSizeEvent()
+
+ except IOError, e:
+ dlg = wx.MessageDialog(self, "Could not read datums: %s " % e,
+ "Could not read datums list", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+class EllipsePage(TitledPage):
+ """
+ Wizard page for selecting ellipsoid (select coordinate system option)
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Specify ellipsoid")
+
+ self.parent = parent
+ self.ellipse = ''
+ self.ellipsedesc = ''
+ self.ellipseparams = ''
+ self.proj4params = ''
+
+ # text input
+ self.tellipse = self.MakeTextCtrl("", size=(200,-1))
+
+ # search box
+ self.searchb = wx.SearchCtrl(self, size=(200,-1),
+ style=wx.TE_PROCESS_ENTER)
+
+ # create list control for ellipse list
+ self.ellipselist = wx.ListCtrl(self, id=wx.ID_ANY,
+ size=(650,250),
+ style=wx.LC_REPORT|
+ wx.LC_HRULES|
+ wx.EXPAND)
+ self.ellipselist.InsertColumn(0, 'Code')
+ self.ellipselist.InsertColumn(1, 'Description')
+ self.ellipselist.SetColumnWidth(0, 100)
+ self.ellipselist.SetColumnWidth(1, 250)
+
+ # layout
+ self.sizer.Add(self.MakeRLabel("Ellipse code:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=1)
+ self.sizer.Add(self.tellipse, 0 ,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=2)
+ self.sizer.Add(self.MakeRLabel("Search in description:"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=1)
+ self.sizer.Add(self.searchb, 0 ,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=2)
+
+ self.sizer.Add(self.ellipselist, 0 ,
+ wx.EXPAND |
+ wx.ALIGN_LEFT |
+ wx.ALL, 5, row=3, col=1, colspan=3)
+
+ # events
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEllipseSelected, self.ellipselist)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+ self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
+ self.Bind(wx.EVT_TEXT, self.OnText, self.tellipse)
+
+ self._onBrowseEllipse(None,None)
+
+ def OnPageChange(self,event):
+ self.proj4params = ''
+ if event.GetDirection() and self.ellipse not in self.parent.ellipsoids:
+ wx.MessageBox('You must select a valid ellipsoid in order to continue')
+ event.Veto()
+ self.GetNext().SetPrev(self)
+ self.parent.datumpage.datumparams = ''
+ self.parent.datumpage.transparams = ''
+ self.GetNext().SetPrev(self)
+
+ def OnText(self, event):
+ self.ellipse = event.GetString()
+ if self.ellipse in self.parent.ellipsoids:
+ self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0]
+ self.ellipseparams = self.parent.ellipsoids[self.ellipse][1]
+
+ def OnDoSearch(self,event):
+ str = self.searchb.GetValue()
+ listItem = self.ellipselist.GetColumn(1)
+
+ for i in range(self.ellipselist.GetItemCount()):
+ item = self.ellipselist.GetItem(i,0)
+ itemdesc = self.ellipselist.GetItem(i,1)
+ if itemdesc.GetText().find(str) > -1:
+ self.ellipse = item.GetText()
+ self.tellipse.SetValue(self.ellipse)
+ self.ellipselist.EnsureVisible(long(self.ellipselist.GetItem(i)))
+ break
+
+ self._onBrowseEllipse(None,str)
+
+ def OnEllipseSelected(self,event):
+ index = event.m_itemIndex
+ item = event.GetItem()
+
+ self.ellipse = item.GetText()
+ self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0]
+ self.ellipseparams = self.parent.ellipsoids[self.ellipse][1]
+
+ self.tellipse.SetValue(self.ellipse)
+ self._onBrowseEllipse(None)
+
+ def _onBrowseEllipse(self,event,search=None):
+ try:
+ ellipselist = self.parent.ellipsoids.items()
+ ellipselist.sort()
+ self.ellipselist.DeleteAllItems()
+ for ellipsoid,info in ellipselist:
+ desc = info[0]
+ entry = self.ellipselist.GetItemCount()
+ if search and (ellipsoid.lower().find(search.lower()) > -1 or \
+ desc.lower().find(search.lower()) > -1) or \
+ not search:
+ index = self.ellipselist.InsertStringItem(entry,ellipsoid)
+ self.ellipselist.SetStringItem(index,1,desc)
+
+ self.ellipselist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
+ self.ellipselist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.ellipselist.SendSizeEvent()
+ except IOError, e:
+ dlg = wx.MessageDialog(self, "Could not read ellipse information: %s " % e,
+ "Problem parsing ellipse list", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+class GeoreferencedFilePage(TitledPage):
+ """
+ Wizard page for selecting georeferenced file to use
+ for setting coordinate system parameters
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Select georeferenced file")
+
+ self.georeffile = ''
+
+ # create controls
+ self.lfile= wx.StaticText(self, -1, "Georeferenced file: ",
+ style=wx.ALIGN_RIGHT)
+ self.tfile = wx.TextCtrl(self,-1, "", size=(300,-1))
+ self.bbrowse = wx.Button(self, -1, "Browse...")
+
+ # do layout
+ self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTRE_VERTICAL |
+ wx.ALL, 5, row=1, col=2)
+ self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT |
+ wx.ALIGN_CENTRE_VERTICAL |
+ wx.ALL, 5, row=1, col=3)
+ self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT |
+ wx.ALL, 5, row=1, col=4)
+
+ self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
+ self.Bind(wx.EVT_TEXT, self.OnText, self.tfile)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+
+ def OnPageChange(self, event):
+ if event.GetDirection() and self.georeffile == '':
+ wx.MessageBox('You must select a georeferenced file in order to continue')
+ event.Veto()
+ self.GetNext().SetPrev(self)
+
+ def OnText(self, event):
+ self.georeffile = event.GetString()
+
+ def OnBrowse(self, event):
+
+ dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN)
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ self.tfile.SetValue(path)
+ dlg.Destroy()
+
+ def OnCreate(self, event):
+ pass
+
+
+class EPSGPage(TitledPage):
+ """
+ Wizard page for selecting EPSG code for
+ setting coordinate system parameters
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Choose EPSG Code")
+ self.parent = parent
+ self.epsgcode = ''
+ self.epsgdesc = ''
+
+
+ # labels
+ self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ",
+ style=wx.ALIGN_RIGHT)
+ self.lcode= wx.StaticText(self, -1, "EPSG code: ",
+ style=wx.ALIGN_RIGHT)
+ self.lsearch= wx.StaticText(self, -1, "Search in code description: ",
+ style=wx.ALIGN_RIGHT)
+
+ # text input
+ epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg')
+ self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1))
+ self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1))
+
+ # buttons
+ self.bbrowse = wx.Button(self, -1, "Browse...")
+ self.bbcodes = wx.Button(self, -1, "Browse Codes...")
+
+ # search box
+ self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER)
+
+ self.epsglist = wx.ListCtrl(self, id=wx.ID_ANY,
+ size=(650,275),
+ style=wx.LC_REPORT|
+ wx.LC_HRULES|
+ wx.EXPAND)
+ self.epsglist.InsertColumn(0, 'Code', wx.LIST_FORMAT_CENTRE)
+ self.epsglist.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT)
+ self.epsglist.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT)
+ self.epsglist.SetColumnWidth(0, 50)
+ self.epsglist.SetColumnWidth(1, 300)
+ self.epsglist.SetColumnWidth(2, 325)
+
+ # layout
+ self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=1)
+ self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=2)
+ self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=1, col=3)
+
+ self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=2)
+ self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2, col=2)
+
+ self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, col=1, row=3)
+ self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=3, col=2)
+ self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=3, col=3)
+
+ self.sizer.Add(self.epsglist, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5)
+
+ # events
+ self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse)
+ self.Bind(wx.EVT_BUTTON, self.OnBrowseCodes, self.bbcodes)
+ self.Bind(wx.EVT_TEXT, self.OnText, self.tcode)
+ self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsglist)
+ self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+
+ def OnPageChange(self, event):
+ if event.GetDirection() and not self.epsgcode:
+ wx.MessageBox('You must select an EPSG code')
+ event.Veto()
+ self.GetNext().SetPrev(self)
+
+ def OnText(self, event):
+ self.epsgcode = event.GetString()
+
+ def OnDoSearch(self,event):
+ str = self.searchb.GetValue()
+ listItem = self.epsglist.GetColumn(1)
+
+ for i in range(self.epsglist.GetItemCount()):
+ listItem = self.epsglist.GetItem(i,1)
+ if listItem.GetText().find(str) > -1:
+ self.epsgcode = self.epsglist.GetItem(i, 0)
+ self.tcode.SetValue(self.epsgcode.GetText())
+ break
+
+ self.OnBrowseCodes(None,str)
+
+ def OnBrowse(self, event):
+
+ dlg = wx.FileDialog(self, "Choose EPSG codes file:",
+ "/", "", "*.*", wx.OPEN)
+ if dlg.ShowModal() == wx.ID_OK:
+ path = dlg.GetPath()
+ self.tfile.SetValue(path)
+ dlg.Destroy()
+
+ def OnItemSelected(self,event):
+ index = event.m_itemIndex
+ item = event.GetItem()
+
+ self.epsgcode = item.GetText()
+ self.epsgdesc = self.epsglist.GetItem(index, 1).GetText()
+ self.tcode.SetValue(str(self.epsgcode))
+
+ def OnBrowseCodes(self,event,search=None):
+ try:
+ self.epsglist.DeleteAllItems()
+ f = open(self.tfile.GetValue(),"r")
+ i=1
+ j = 0
+ descr = None
+ code = None
+ params = ""
+ #self.epsglist.ClearAll()
+ for line in f.readlines():
+ line = line.strip()
+ if line.find("#") == 0:
+ descr = line[1:].strip()
+ elif line.find("<") == 0:
+ code = line.split(" ")[0]
+ for par in line.split(" ")[1:]:
+ params += par + " "
+ code = code[1:-1]
+ if code == None: code = 'no code'
+ if descr == None: descr = 'no description'
+ if params == None: params = 'no parameters'
+ if i%2 == 0:
+ if search and descr.lower().find(search.lower()) > -1 or\
+ not search:
+ index = self.epsglist.InsertStringItem(j, code)
+ self.epsglist.SetStringItem(index, 1, descr)
+ self.epsglist.SetStringItem(index, 2, params)
+ j += 1
+ # reset
+ descr = None; code = None; params = ""
+# if i%2 == 0:
+# self.epsglist.SetItemBackgroundColour(i, "grey")
+ i += 1
+ f.close()
+ self.epsglist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
+ self.epsglist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
+ self.SendSizeEvent()
+ except StandardError, e:
+ dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " % e,
+ "Could not read file", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+
+
+class CustomPage(TitledPage):
+ """
+ Wizard page for entering custom PROJ.4 string
+ for setting coordinate system parameters
+ """
+
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters")
+ global coordsys
+ self.customstring = ''
+ self.parent = parent
+
+ self.text_proj4string = self.MakeTextCtrl(size=(400,100))
+ self.label_proj4string = self.MakeRLabel("Enter PROJ.4 parameters string: ")
+ self.sizer.Add(self.label_proj4string, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1)
+ self.sizer.Add(self.text_proj4string, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2)
+
+ self.Bind(wx.EVT_TEXT, self.GetProjstring, self.text_proj4string)
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
+
+ def OnPageChange(self, event):
+ if event.GetDirection() and not self.customstring:
+ wx.MessageBox('You must enter a PROJ.4 string')
+ event.Veto()
+ self.GetNext().SetPrev(self)
+
+ def GetProjstring(self, event):
+ self.customstring = event.GetString()
+
+
+class SummaryPage(TitledPage):
+ """
+ Shows summary result of choosing coordinate system parameters
+ prior to creating location
+ """
+ def __init__(self, wizard, parent):
+ TitledPage.__init__(self, wizard, "Summary")
+
+ self.parent = parent
+
+ # labels
+ self.ldatabase = self.MakeLLabel("")
+ self.llocation = self.MakeLLabel("")
+ self.lprojection = self.MakeLLabel("")
+
+ self.lprojection.Wrap(500)
+
+ self.sizer.Add(self.MakeRLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=1, col=0)
+ self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=1, col=1)
+ self.sizer.Add(self.MakeRLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=2, col=0)
+ self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=2, col=1)
+ self.sizer.Add(wx.StaticLine(self, -1), 0, wx.ALIGN_RIGHT|wx.EXPAND|wx.ALL, 0, row=3, col=0, colspan=2)
+ self.sizer.Add((10,10), 1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5, row=4, col=0)
+ self.sizer.Add(self.MakeRLabel("Projection: "), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=5, col=0)
+ self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=5, col=1)
+ self.sizer.Add((10,20), 1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5, row=6, col=0)
+ self.sizer.Add(self.MakeLLabel("You can set the default extents and resolution after creating new location"), \
+ 1, flag=wx.ALIGN_CENTRE|wx.ALL, border=5, row=7, col=0, colspan=2)
+ self.sizer.Add(self.MakeLLabel("or you can set them during a working session."), \
+ 1, flag=wx.ALIGN_CENTRE|wx.ALL, border=5, row=8, col=0, colspan=2)
+
+ self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChange)
+
+ def OnPageChange(self,event):
+ """
+ Insert values into text controls for summary of location creation options
+ """
+
+ database = self.parent.startpage.grassdatabase
+ location = self.parent.startpage.location
+
+ global coordsys
+ if not coordsys:
+ coordsys = 0
+
+ projection = self.parent.projpage.proj
+ projdesc = self.parent.projpage.projdesc
+ utmzone = self.parent.projtypepage.utmzone
+ utmhemisphere = self.parent.projtypepage.utmhemisphere
+ ellipse = self.parent.ellipsepage.ellipse
+ ellipsedesc = self.parent.ellipsepage.ellipsedesc
+ datum = self.parent.datumpage.datum
+ datumdesc = self.parent.datumpage.datumdesc
+ ellipsoid = self.parent.datumpage.ellipsoid
+ datumparams = self.parent.datumpage.datumparams
+ transform = self.parent.datumpage.transform
+ transregion = self.parent.datumpage.transregion
+ transparams = self.parent.datumpage.transparams
+
+ self.ldatabase.SetLabel(str(database))
+ self.llocation.SetLabel(str(location))
+ label = ''
+ if coordsys == 'epsg':
+ label = 'EPSG code %s (%s)' % (self.parent.epsgpage.epsgcode,self.parent.epsgpage.epsgdesc)
+ self.lprojection.SetLabel(label)
+ elif coordsys == 'file':
+ label = 'matches file %s' % self.parent.filepage.georeffile
+ self.lprojection.SetLabel(label)
+ elif coordsys == 'proj':
+ label = ('%s, %s%s' % (projdesc, datumdesc, ellipsedesc))
+ self.lprojection.SetLabel(label)
+ elif coordsys == 'xy':
+ label = ('XY coordinate system. Not projected')
+ self.lprojection.SetLabel(label)
+ elif coordsys == 'custom':
+ label = ('%s' % self.parent.custompage.customstring)
+ self.lprojection.SetLabel(label)
+
+class RegionDef(wx.Frame):
+ """
+ Page for setting default region extents and resolution
+ """
+
+ def __init__(self,parent,id=wx.ID_ANY, title="Set default region values", location=None):
+ wx.Frame.__init__(self, parent, id, title, size=(650,300))
+
+ self.parent = parent
+ self.location = location
+
+ # inputs
+ self.ttop = self.MakeTextCtrl("1", size=(150, -1))
+ self.tbottom = self.MakeTextCtrl("0", size=(150, -1))
+ self.tleft = self.MakeTextCtrl("0", size=(150, -1))
+ self.tright = self.MakeTextCtrl("1", size=(150, -1))
+ self.tres = self.MakeTextCtrl("1", size=(150, -1))
+
+ self.north = 1.0
+ self.south = 0.0
+ self.east = 1.0
+ self.west = 0.0
+ self.res = 1.0
+
+ # labels
+ self.lmessage = wx.StaticText(self,-1, "", size=(300,50))
+
+ # buttons
+ self.bset = self.MakeButton("Set coordinates", size=(150,-1))
+ self.bcancel = self.MakeButton("Cancel", size=(150,-1))
+
+ #Set current working environment to PERMANENT mapset in selected location in order to set default region (WIND)
+ envval = {}
+ cmdlist = ['g.gisenv']
+ p = gcmd.Command(cmdlist)
+ if p.returncode == 0:
+ output = p.module_stdout.read().strip("'").split(';\n')
+ for line in output:
+ line = line.strip()
+ if '=' in line: key,val = line.split('=')
+ envval[key] = val
+ self.currlocation = envval['LOCATION_NAME'].strip("';")
+ self.currmapset = envval['MAPSET'].strip("';")
+ if self.currlocation == self.location and self.currmapset == 'PERMANENT':
+ pass
+ else:
+ cmdlist = ['g.mapset', 'location=%s' % self.location, 'mapset=PERMANENT']
+ gcmd.Command(cmdlist)
+ else:
+ wx.MessageBox('A valid location must be selected')
+ return
+
+ #Get current region settings
+ region = {}
+ cmdlist = ['g.region', '-gp']
+ p = gcmd.Command(cmdlist)
+ if p.returncode == 0:
+ output = p.module_stdout.read().split('\n')
+ for line in output:
+ line = line.strip()
+ if '=' in line: key,val = line.split('=')
+ region[key] = float(val)
+ else:
+ wx.MessageBox('Invalid region')
+ return
+
+ self.north = region['n']
+ self.south = region['s']
+ self.east = region['e']
+ self.west = region['w']
+ self.res = region['ewres']
+
+ # Insert current region settings into text controls
+ self.ttop.SetValue(str(self.north))
+ self.tbottom.SetValue(str(self.south))
+ self.tleft.SetValue(str(self.west))
+ self.tright.SetValue(str(self.east))
+ self.tres.SetValue(str(self.res))
+
+ # layout
+ self.sizer = rcs.RowColSizer()
+
+ self.sizer.Add(self.MakeLLabel("Region extents and resolution:"), 3,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 10, row=0,col=0, colspan=2)
+
+ self.sizer.Add(self.MakeRLabel("North"), 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 0, row=1,col=2)
+ self.sizer.Add(self.ttop, 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=2,col=2)
+
+ self.sizer.Add(self.MakeRLabel("West"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 0, row=3,col=0)
+ self.sizer.Add(self.tleft, 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=3,col=1)
+
+ self.sizer.Add(self.tright, 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=3,col=3)
+ self.sizer.Add(self.MakeRLabel("East"), 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 0, row=3,col=4)
+
+ self.sizer.Add(self.tbottom, 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=4,col=2)
+ self.sizer.Add(self.MakeRLabel("South"), 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 0, row=5,col=2)
+
+ self.sizer.Add(self.MakeRLabel("Resolution"), 0,
+ wx.ALIGN_RIGHT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=6,col=1)
+ self.sizer.Add(self.tres, 0,
+ wx.ALIGN_CENTER_HORIZONTAL |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=6,col=2)
+
+ self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6)
+
+ self.sizer.Add(self.bset, 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=8, col=3 )
+
+ self.sizer.Add(self.bcancel, 0,
+ wx.ALIGN_LEFT |
+ wx.ALIGN_CENTER_VERTICAL |
+ wx.ALL, 5, row=8, col=1 )
+
+
+ self.SetSizer(self.sizer)
+ self.SetAutoLayout(True)
+ self.Layout()
+
+ self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset)
+ self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel)
+ self.Bind(wx.EVT_TEXT, self.OnNorth, self.ttop)
+ self.Bind(wx.EVT_TEXT, self.OnSouth, self.tbottom)
+ self.Bind(wx.EVT_TEXT, self.OnEast, self.tright)
+ self.Bind(wx.EVT_TEXT, self.OnWest, self.tleft)
+ self.Bind(wx.EVT_TEXT, self.OnRes, self.tres)
+
+ def MakeRLabel(self, text=""):
+ """Make right-aligned label"""
+ try:
+ if text[-1] != " ":
+ text += " "
+ except:
+ pass
+ return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT)
+
+ def MakeLLabel(self, text=""):
+ """Make left-aligned label"""
+ try:
+ if text[-1] != " ":
+ text += " "
+ except:
+ pass
+ return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT)
+
+ def MakeTextCtrl(self,text='', size=(100,-1)):
+ """Generic text control"""
+ return wx.TextCtrl(self,-1, text, size=size)
+
+ def MakeButton(self,text, size=(75,25)):
+ """Generic button"""
+ return wx.Button(self, -1, text,
+ style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL,
+ size=size)
+
+ def OnNorth(self,event):
+ self.north = event.GetString()
+
+ def OnSouth(self, event):
+ self.south = event.GetString()
+
+ def OnEast(self,event):
+ self.east = event.GetString()
+
+ def OnWest(self,event):
+ self.west = event.GetString()
+
+ def OnRes(self,event):
+ self.res = event.GetString()
+
+ def OnSetButton(self,event=None):
+ cmdlist = ['g.region', '-sgpa', 'n=%s' % self.north, 's=%s' % self.south, \
+ 'e=%s' % self.east, 'w=%s' % self.west, 'res=%s' % self.res]
+ p = gcmd.Command(cmdlist)
+ if p.returncode == 0:
+ output = p.module_stdout.read()
+ wx.MessageBox('New default region:\n%s' % output)
+ else:
+ wx.MessageBox('Setting default region failed\n%s %s' % \
+ (p.module_stderr.read(),p.module_stdout.read()))
+ self.Destroy()
+
+ def OnCancel(self, event):
+ self.Destroy()
+
+class GWizard:
+ """
+ Start wizard here and finish wizard here
+ """
+
+ def __init__(self, parent, grassdatabase):
+ wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","wizard.png"), wx.BITMAP_TYPE_PNG)
+ wizbmp.Rescale(250,600)
+ wizbmp = wizbmp.ConvertToBitmap()
+
+ global coordsys
+ self.parent = parent
+ # get georeferencing information from tables in $GISBASE/etc
+
+ # make projections dictionary
+ f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r")
+ self.projections = {}
+ for line in f.readlines():
+ line = line.expandtabs(1)
+ line = line.strip()
+ if not line:
+ continue
+ if line == '' or line[0] == "#":
+ continue
+ proj,projdesc = line.split(":", 1)
+ proj = proj.strip()
+ projdesc = projdesc.strip()
+ self.projections[proj] = projdesc
+ f.close()
+
+ f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r")
+ self.datums = {}
+ paramslist = []
+ for line in f.readlines():
+ line = line.expandtabs(1)
+ line = line.strip()
+ if not line:
+ continue
+ if line == '' or line[0] == "#":
+ continue
+ datum,info = line.split(" ", 1)
+ info = info.strip()
+ datumdesc,params = info.split(" ",1)
+ datumdesc = datumdesc.strip('"')
+ paramlist = params.split()
+ ellipsoid = paramlist.pop(0)
+ self.datums[datum] = (datumdesc,ellipsoid,paramlist)
+ f.close()
+
+ # make datum transforms dictionary
+ f = open(os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table"),"r")
+ self.transforms = {}
+ j = 1
+ for line in f.readlines():
+ transcode = 'T'+str(j)
+ line = line.expandtabs(1)
+ line = line.strip()
+ if not line:
+ continue
+ if line == '' or line[0] == "#":
+ continue
+ datum,rest = line.split(" ", 1)
+ rest = rest.strip('" ')
+ params,rest = rest.split('"', 1)
+ params = params.strip()
+ rest = rest.strip('" ')
+ try:
+ region,info = rest.split('"', 1)
+ info = info.strip('" ')
+ info = region+': '+info
+ except:
+ info = rest
+ self.transforms[transcode] = (datum,info,params)
+ j+=1
+ f.close()
+
+ # make ellipsiods dictionary
+ f = open(os.path.join(os.getenv("GISBASE"), "etc","ellipse.table"),"r")
+ self.ellipsoids = {}
+ for line in f.readlines():
+ line = line.expandtabs(1)
+ line = line.strip()
+ if not line:
+ continue
+ if line == '' or line[0] == "#":
+ continue
+ ellipse,rest = line.split(" ", 1)
+ rest = rest.strip('" ')
+ desc,params = rest.split('"', 1)
+ desc = desc.strip('" ')
+ paramslist = params.split()
+ self.ellipsoids[ellipse] = (desc,paramslist)
+ f.close()
+
+ # define wizard pages
+ self.wizard = wiz.Wizard(parent, -1, "Define new Location",
+ bitmap=wizbmp)
+ self.startpage = DatabasePage(self.wizard, self, grassdatabase)
+ self.csystemspage = CoordinateSystemPage(self.wizard, self)
+ self.projpage = ProjectionsPage(self.wizard, self)
+ self.projtypepage = ProjTypePage(self.wizard,self)
+ self.epsgpage = EPSGPage(self.wizard, self)
+ self.filepage = GeoreferencedFilePage(self.wizard, self)
+ self.datumpage = DatumPage(self.wizard, self)
+ self.ellipsepage = EllipsePage(self.wizard, self)
+ self.custompage = CustomPage(self.wizard, self)
+ self.sumpage = SummaryPage(self.wizard, self)
+
+
+ # Set the initial order of the pages
+ # it should follow the epsg line
+ self.startpage.SetNext(self.csystemspage)
+
+ self.csystemspage.SetPrev(self.startpage)
+ self.csystemspage.SetNext(self.sumpage)
+
+ self.projpage.SetPrev(self.csystemspage)
+ self.projpage.SetNext(self.projtypepage)
+
+ self.projtypepage.SetPrev(self.projpage)
+ self.projtypepage.SetNext(self.datumpage)
+
+ self.datumpage.SetPrev(self.projtypepage)
+ self.datumpage.SetNext(self.sumpage)
+
+ self.ellipsepage.SetPrev(self.projtypepage)
+ self.ellipsepage.SetNext(self.sumpage)
+
+ self.epsgpage.SetPrev(self.csystemspage)
+ self.epsgpage.SetNext(self.sumpage)
+
+ self.filepage.SetPrev(self.csystemspage)
+ self.filepage.SetNext(self.sumpage)
+
+ self.custompage.SetPrev(self.csystemspage)
+ self.custompage.SetNext(self.sumpage)
+
+ self.sumpage.SetPrev(self.csystemspage)
+
+ self.wizard.FitToPage(self.datumpage)
+
+ self.location = None #New location created
+
+ success = False
+
+ if self.wizard.RunWizard(self.startpage):
+ success = self.onWizFinished()
+ if success == True:
+ self.location = self.startpage.location
+ dlg = wx.MessageDialog(self.wizard,
+ "Do you want to set the default region extents and resolution now?",
+ "New location '%s' created"% self.location,
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_YES:
+ dlg.Destroy()
+ defineRegion = RegionDef(None, location=self.location)
+ defineRegion.Show()
+ else:
+ dlg.Destroy()
+
+ else:
+ wx.MessageBox("Unable to create new location.")
+ else:
+ wx.MessageBox("Location wizard canceled. New location not created.")
+
+# self.wizard.Destroy()
+
+ def onWizFinished(self):
+ database = self.startpage.grassdatabase
+ location = self.startpage.location
+ global coordsys
+ success = False
+
+# wx.MessageBox("finished database: %s, location: %s, coordsys: %s" % (database, location, coordsys))
+ if os.path.isdir(os.path.join(database,location)):
+ dlg = wx.MessageDialog(self, "Could not create new location: %s already exists"
+ % os.path.join(database,location),"Could not create location",
+ wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ if coordsys == "xy":
+ success = self.XYCreate()
+ elif coordsys == "latlong":
+ rows = int(round((float(north)-float(south))/float(resolution)))
+ cols = int(round((float(east)-float(west))/float(resolution)))
+ cells = int(rows*cols)
+ success = self.LatlongCreate()
+ elif coordsys == "proj":
+ success = self.Proj4Create()
+ elif coordsys == 'custom':
+ success = self.CustomCreate()
+ elif coordsys == "epsg":
+ success = self.EPSGCreate()
+ elif coordsys == "file":
+ success = self.FileCreate()
+
+ return success
+
+ def XYCreate(self):
+ """
+ Create an XY location
+ """
+ database = self.startpage.grassdatabase
+ location = self.startpage.location
+
+ dlg = wx.MessageDialog(self.wizard, "New XY location '%s' will be created (not projected or georeferenced)"
+ % location,
+ "Create new XY location?",
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return False
+ else:
+ dlg.Destroy()
+
+ #Make location folder and PERMANT mapset
+ os.mkdir(os.path.join(database,location))
+ os.mkdir(os.path.join(database,location,'PERMANENT'))
+
+ #Make DEFAULT_WIND and WIND files
+ regioninfo = ['proj: 0',
+ 'zone: 0',
+ 'north: 1',
+ 'south: 0',
+ 'east: 1',
+ 'west: 0',
+ 'cols: 1',
+ 'rows: 1',
+ 'e-w resol: 1',
+ 'n-s resol: 1',
+ 'top: 1',
+ 'bottom: 0',
+ 'cols3: 1',
+ 'rows3: 1',
+ 'depths: 1',
+ 'e-w resol3: 1',
+ 'n-s resol3: 1',
+ 't-b resol: 1']
+
+ try:
+ defwind = open(os.path.join(database,location,"PERMANENT","DEFAULT_WIND"),'w')
+ for param in regioninfo:
+ defwind.write(param+'\n')
+ defwind.close()
+ shutil.copy(os.path.join(database,location,"PERMANENT","DEFAULT_WIND"),\
+ os.path.join(database,location,"PERMANENT","WIND"))
+
+ #Make MYNAME file
+ myname = open(os.path.join(database,location,"PERMANENT","MYNAME"),'w')
+ myname.write('')
+ myname.close()
+ return True
+ except:
+ return False
+
+ def Proj4Create(self):
+ """
+ Create a new location for selected projection
+ """
+
+ location = self.startpage.location
+ proj = self.projpage.proj
+ projdesc = self.projpage.projdesc
+
+ utmzone = self.projtypepage.utmzone
+ utmhemisphere = self.projtypepage.utmhemisphere
+
+ datum = self.datumpage.datum
+ if self.datumpage.datumdesc:
+ datumdesc = self.datumpage.datumdesc+' - '+self.datumpage.ellipsoid
+ else: datumdesc = ''
+ datumparams = self.datumpage.datumparams
+ transparams = self.datumpage.transparams
+
+ ellipse = self.ellipsepage.ellipse
+ ellipsedesc = self.ellipsepage.ellipsedesc
+ ellipseparams = self.ellipsepage.ellipseparams
+
+ # Creating PROJ.4 string
+ if proj == 'll':
+ proj = 'longlat'
+
+ if proj == 'utm' and utmhemisphere == 'south':
+ proj4string = '+proj=%s +zone=%s +south' % (proj, utmzone)
+ elif proj == 'utm':
+ proj4string = '+proj=%s +zone=%s' % (proj, utmzone)
+ else:
+ proj4string = '+proj=%s ' % (proj)
+
+ proj4params = ''
+ # set ellipsoid parameters
+ for item in ellipseparams:
+ if item[:4] == 'f=1/':
+ item = '+rf='+item[4:]
+ else:
+ item = '+'+item
+ proj4params = '%s %s' % (proj4params, item)
+ # set datum and transform parameters if relevant
+ if datumparams:
+ for item in datumparams:
+ proj4params = '%s +%s' % (proj4params,item)
+ if transparams:
+ proj4params = '%s +no_defs +%s' % (proj4params,transparams)
+ else:
+ proj4params = '%s +no_defs' % proj4params
+ else:
+ proj4params = '%s +no_defs' % proj4params
+
+ proj4string = '%s %s' % (proj4string, proj4params)
+
+ msgtext = "New location '%s' will be created georeferenced to" % location
+ georeftext = '%s: %s%s' % (projdesc,datumdesc,ellipsedesc)
+ p4text = '(PROJ.4 string: %s)' % proj4string
+
+ dlg = wx.MessageDialog(self.wizard, msgtext+' '+georeftext+' '+p4text,
+ "Create new location?",
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return False
+ else:
+ dlg.Destroy()
+
+ # Creating location from PROJ.4 string passed to g.proj
+ try:
+ cmdlist = ['g.proj', '-c', 'proj4=%s' % proj4string, 'location=%s' % location]
+ p = gcmd.Command(cmdlist)
+ if p.module.returncode == 0:
+ return True
+ else:
+ return False
+
+ except StandardError, e:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ def CustomCreate(self):
+ proj4string = self.custompage.customstring
+ location = self.startpage.location
+
+ dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created using PROJ.4 string: %s"
+ % (location,proj4string),
+ "Create new location?",
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return False
+ else:
+ dlg.Destroy()
+
+ try:
+ cmdlist = ['g.proj','-c','proj4=%s' % proj4string,'location=%s' % location]
+ p = gcmd.Command(cmdlist)
+ if p.module.returncode == 0:
+ return True
+ else:
+ return False
+
+ except StandardError, e:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+
+ def EPSGCreate(self):
+ """
+ Create a new location from an EPSG code.
+ """
+ epsgcode = self.epsgpage.epsgcode
+ epsgdesc = self.epsgpage.epsgdesc
+ location = self.startpage.location
+ cmdlist = []
+
+ if not epsgcode:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: EPSG Code value missing",
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to EPSG code %s: %s"
+ % (location, epsgcode, epsgdesc),
+ "Create new location from EPSG code?",
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return False
+ else:
+ dlg.Destroy()
+
+ # creating location
+ try:
+ cmdlist = ['g.proj','epsg=%s' % epsgcode,'datumtrans=-1']
+ p = gcmd.Command(cmdlist)
+ dtoptions = p.module_stdout.read()
+ if dtoptions != None:
+ dtrans = ''
+ # open a dialog to select datum transform number
+ dlg = wx.TextEntryDialog(self.wizard, dtoptions,
+ caption='Select the number of a datum transformation to use',
+ defaultValue='1',
+ style=wx.TE_WORDWRAP|wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX|
+ wx.RESIZE_BORDER|wx.VSCROLL|
+ wx.OK|wx.CANCEL)
+
+ if dlg.ShowModal() == wx.ID_CANCEL:
+ dlg.Destroy()
+ return False
+ else:
+ dtrans = dlg.GetValue()
+ if dtrans != '':
+ dlg.Destroy()
+ else:
+ wx.MessageBox('You must select a datum transform')
+ return False
+
+ cmdlist = ['g.proj','-c','epsg=%s' % epsgcode,'location=%s' % location,'datumtrans=%s' % dtrans]
+ else:
+ cmdlist = ['g.proj','-c','epsg=%s' % epsgcode,'location=%s' % location,'datumtrans=1']
+
+ p = gcmd.Command(cmdlist)
+ if p.module.returncode == 0:
+ return True
+ else:
+ return False
+
+ except StandardError, e:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ def FileCreate(self):
+ """
+ Create a new location from a georeferenced file
+ """
+ georeffile = self.filepage.georeffile
+ location = self.startpage.location
+
+ cmdlist = []
+
+ dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to file '%s'"
+ % (location, georeffile), "Create new location from georeferenced file?",
+ wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
+ if dlg.ShowModal() == wx.ID_NO:
+ dlg.Destroy()
+ return False
+ else:
+ dlg.Destroy()
+
+ if not os.path.isfile(georeffile):
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: could not find file %s" % georeffile,
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ if not georeffile:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: georeferenced file not set",
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+ # creating location
+ try:
+ cmdlist = ['g.proj','-c','georef=%s' % georeffile,'location=%s' % location]
+ p = gcmd.Command(cmdlist)
+ if p.module.returncode == 0:
+ return True
+ else:
+ return False
+
+ except StandardError, e:
+ dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
+ "Could not create location", wx.OK|wx.ICON_INFORMATION)
+ dlg.ShowModal()
+ dlg.Destroy()
+ return False
+
+if __name__ == "__main__":
+ gWizard = GWizard(None, "")
+ GRASSStartUp = GWizard.StartUp(0)
+ GRASSStartUp.MainLoop()
+ #app.MainLoop()
Copied: trunk/grassaddons/gui/gui_modules/states.txt (from rev 1148, trunk/grassaddons/gui/states.txt)
===================================================================
--- trunk/grassaddons/gui/gui_modules/states.txt (rev 0)
+++ trunk/grassaddons/gui/gui_modules/states.txt 2007-10-20 09:51:46 UTC (rev 1149)
@@ -0,0 +1,185 @@
+Afghanistan; 59.9,28.66 75.65,39.11
+Africa; -20.2,-37.6 53.4,35.75
+Albania; 19.36,39.42 21.39,42.71
+Algeria; -9.47,17.94 13.19,38.14
+Angola; 11.31,-18.68 24.97,-3.84
+Antarctic; -180,-90 180,-66
+Antarctica; -180,-90 180,-62.83
+Arctic; -180,66 180,90
+Argentina; -74.97,-56.71 -51.76,-20.25
+Armenia; 43.53,38.68 47.07,41.48
+Asia; 40,-10 180,83.5
+Australia; 111.22,-45.73 155.72,-8.88
+Austria; 9.27,45.99 17.93,49.38
+Azerbaijan; 44.58,38.04 50.96,42.2
+Bangladesh; 87.95,20.75 93.07,26.62
+Belgium; 2.54,49.31 6.69,51.69
+Belize; -89.18,15.78 -87.78,18.64
+Benin; 0.74,5.97 4.34,12.66
+Bhutan; 88.8,26.54 92.37,28.46
+Bolivia; -70.05,-23.63 -56.72,-9.13
+Bosnia and Herzegovina; 15.76,42.38 20.02,45.45
+Botswana; 19.57,-27.41 29.94,-17.32
+Brazil; -75.64,-35.81 -32.74,7.12
+Brunei; 114.22,3.96 115.42,5.09
+Bulgaria; 22.19,40.86 29.02,44.59
+Burkina Faso; -5.72,9.19 2.98,15.54
+Burma; 91.41,9.22 102.13,29.34
+Burundi; 28.98,-4.85 31.17,-2.35
+Byelarus; 22.91,50.82 33.38,56.65
+Cambodia; 102.28,10.07 107.98,14.86
+Cameroon; 8.22,1.06 16.85,13.65
+Canada; -145.27,37.3 -48.11,87.61
+Caribbean; -91.4,27.36 -55.4,6.48
+Central African Republic; 13.96,1.5 28.11,11.67
+Central America; -94.1,21.8 -75.8,6.61
+Chad; 12.88,6.67 24.97,24.19
+Chile; -77.16,-56.79 -64.9,-15.72
+China; 70.83,15.06 137.97,56.58
+Colombia; -79.69,-5 -66.15,13.28
+Congo; 10.93,-5.41 19.19,3.98
+Costa Rica; -85.83,7.9 -82.18,11.38
+Croatia; 13.47,42.09 19.92,46.84
+Cuba; -85.03,19.36 -73.44,23.68
+Cyprus; 32.23,34.44 34.78,35.78
+Czech Republic; 12.13,48.23 19.38,51.42
+Denmark; 8.02,54.68 12.89,58
+Djibouti; 41.89,10.78 43.77,12.81
+Dominican Republic; -71.87,17.54 -67.99,20.12
+East Pacific Ocean; -180,64.8 -72.7,-75.6
+Ecuador; -81.08,-5.35 -74.68,1.72
+Egypt; 24.29,21.29 37.61,32.14
+El Salvador; -90.05,13.07 -87.41,14.6
+Equatorial Guinea; 8.39,0.76 11.59,3.82
+Eritrea; 36.31,12 43.58,18.41
+Estonia; 23.3,57.29 28.59,59.75
+Ethiopia; 32.49,2.63 48.85,15.56
+Europe; -25.1,71.3 35,34.9
+Finland; 20.46,59.3 32.14,70.44
+France; -5.29,40.65 10.4,51.82
+French Guiana; -54.37,1.84 -51.23,5.89
+Gabon; 8.71,-4.23 15.01,2.6
+Gambia; -16.71,13.02 -13.66,13.96
+Germany; 5.68,46.86 15.68,55.41
+Ghana; -3.31,4.39 1.7,11.47
+Greece; 19.99,34.62 27.19,42.01
+Greenland; -75.34,56.78 -9.36,86.6
+Guatemala; -92.24,13.59 -87.87,18.06
+Guinea; -15.19,6.77 -6.87,13.02
+Guinea-Bissau; -16.51,10.97 -13.34,12.8
+Guyana; -61.41,0.81 -56.12,8.79
+Haiti; -74.38,17.88 -71.34,20.1
+Honduras; -89.47,12.75 -82.92,16.31
+Hungary; 16.12,45.44 23.57,48.95
+Iceland; -24.55,62.81 -12.79,67.01
+India; 66.79,6.58 99.01,36.96
+Indian Ocean; 22.3,-55.4 119.5,25.2
+Indonesia; 93.11,-12.65 143.45,7.88
+Iran; 43.31,24.08 64.42,40.73
+Iraq; 38.47,28.5 49.25,37.84
+Ireland; -10.52,51.23 -5.62,55.49
+Israel; 34.17,29.25 36.09,33.31
+Italy; 6.11,36.15 19.33,47.71
+Ivory Coast; -8.64,4.03 -2.01,10.96
+Jamaica; -78.22,17.72 -76,18.63
+Japan; 128.74,30.1 146.46,46.26
+Jordan; 34.97,28.87 39.75,33.44
+Kazakhstan; 44.73,38.62 89.65,57.49
+Kenya; 33,-5.3 42.44,5.07
+Democratic People's Republic of Korea; 124.02,43.29 37.55,130.95
+Republic of Korea; 125.95,38.76 33.06,129.88
+Kuwait; 46.62,28.34 48.74,30
+Kyrgyzstan; 69.01,38.7 81.03,43.77
+Laos; 99.77,13.47 108.1,22.98
+Latvia; 20.76,55.32 28.76,58.44
+Lebanon; 35.09,32.84 36.79,34.63
+Lesotho; 27.16,-30.89 29.76,-28.59
+Liberia; -11.47,4.16 -6.95,8.66
+Libya; 8.79,18.7 26.1,33.95
+Lithuania; 20.86,53.6 27.25,56.73
+Luxembourg; 5.9,49.42 6.77,50.21
+Macedonia; 20.62,40.62 23.27,42.48
+Madagascar; 42.83,-26.31 51.38,-11.58
+Malawi; 32.55,-17.51 36.46,-9.26
+Malaysia; 99.4,-0.2 120.19,7.86
+Mali; -12.77,9.25 5.27,25.83
+Mauritania; -17.47,14.21 -4.04,27.81
+Mexico; -118.48,13.05 -85.18,34.17
+Middle East; 25,10.7 59.7,36.1
+Moldova; 26.64,45.31 30.47,48.64
+Mongolia; 86.47,40 121.62,53.65
+Montenegro; 18.56,41.77 20.67,43.64
+Morocco; -13.52,26.96 -0.28,36.48
+Mozambique; 29.67,-27.82 41.89,-9.63
+Namibia; 11.32,-29.61 25.86,-16.31
+Nepal; 79.9,26 88.84,30.88
+Netherlands; 3.54,50.56 7.62,53.59
+New Hampshire; -72.68,42.57 -70.58,45.43
+New Jersey; -75.69,38.8 -73.78,41.47
+New Mexico; -109.35,31.04 -102.7,37.3
+New Zealand; 166.05,-47.31 179.41,-33.89
+Nicaragua; -87.7,10.55 -82.87,15.24
+Niger; -0.39,10.95 16.95,24.28
+Nigeria; 2.33,3.72 15.34,14.4
+North America; -168.5,18 -50.4,85.7
+North Atlantic Ocean; -82,0 12,80
+Northern Temperate; -180,23 180,60
+Norway; 3.88,56.69 32.56,81.95
+Oman; 51.53,16.19 60.52,26.73
+Pakistan; 60.18,22.94 78.66,37.86
+Panama; -83.06,6.9 -76.63,9.95
+Papua New Guinea; 140.37,-11.3 153.05,-2.2
+Paraguay; -62.83,-27.85 -53.6,-18.87
+Peru; -82.13,-19.35 -67.52,0.79
+Philippines; 116.68,4.85 127.23,19.22
+Poland; 13.77,48.57 24.85,55.24
+Portugal; -9.6,36.75 -5.65,42.36
+Qatar; 50.97,24.33 51.89,26.17
+Romania; 20.05,43.29 30.38,48.76
+Russia; 25,23.21 180,71
+Rwanda; 28.9,-3.01 31.2,-1.03
+Saudi Arabia; 33.9,14.01 57.3,33.22
+Senegal; -17.53,12.02 -10.89,17.14
+Serbia; 18.8,41.66 23.35,46.39
+Sierra Leone; -13.16,6.71 -10.02,10.09
+Slovakia; 16.84,47.61 23.06,49.93
+Slovenia; 13.39,45.28 16.87,47.06
+Somalia; 40.53,-2.55 52.14,12.66
+South Africa; 13.68,-35.9 33.98,-21.27
+South America; -84.9,-57.6 -32.4,13.7
+South Atlantic Ocean; -67,-55.4 23,0
+Southern Ocean; -180,-77 180,-32
+Southern Temperate; -180,-60 180,-23
+Spain; -9.69,35.4 3.98,44.38
+Sri Lanka; 79.69,5.76 82.26,9.89
+Sudan; 21.06,2.6 39.77,22.86
+Suriname; -58.01,1.53 -53.42,6.23
+Swaziland; 30.93,-27.52 32.45,-25.72
+Sweden; 10.56,54.63 24.84,69.68
+Switzerland; 5.92,45.66 10.84,48.02
+Syria; 35.36,31.84 43.11,37.69
+Taiwan; 119.99,21.78 122.14,25.31
+Tajikistan; 67.34,36.34 75.59,41.46
+Tanzania United Republic of; 0,-0.54 28.96,41.23
+Thailand; 96.83,4.8 106.42,21.22
+Togo; -0.09,5.85 2.21,11.33
+Trinidad; -61.88,10.01 -60.86,10.89
+Tropics; -180,-23 180,23
+Tunisia; 7.38,29.87 12.03,37.65
+Turkey; 25.29,34.91 45.94,43
+Turkmenistan; 52.05,34.56 67.66,43.46
+Uganda; 29.45,-1.82 35.52,4.32
+Ukraine; 21.4,43.61 41.24,53.31
+United Arab Emirates; 51.06,21.82 56.87,26.25
+United Kingdom; -8.41,49.49 2.39,59.07
+United States; -180,13.71 -61.48,76.63
+Uruguay; -58.46,-35.26 -52.77,-29.97
+Uzbekistan; 55.44,36.08 74.31,46.46
+Venezuela; -73.81,-0.11 -58.91,12.92
+Vietnam; 101.43,7.75 110.25,24.05
+Virginia; -84.1,36.12 -74.82,39.88
+Western Sahara; -17.23,20.87 -8.01,28
+Yemen; 42.45,12.12 53.74,19.51
+Zaire; 11.45,-14.4 32.4,6.28
+Zambia; 21.55,-18.7 34.45,-7.69
+Zimbabwe; 25.11,-22.93 33.65,15.22
Deleted: trunk/grassaddons/gui/location_wizard.py
===================================================================
--- trunk/grassaddons/gui/location_wizard.py 2007-10-19 22:28:09 UTC (rev 1148)
+++ trunk/grassaddons/gui/location_wizard.py 2007-10-20 09:51:46 UTC (rev 1149)
@@ -1,1863 +0,0 @@
-"""
-MODULE: location_wizard.py
-
-CLASSES:
- * TitledPage
- * DatabasePage
- * CoordinateSystemPage
- * ProjectionsPage
- * ProjTypePage
- * DatumPage
- * EllipsePage
- * GeoreferencedFilePage
- * EPSGPage
- * CustomPage
- * SummaryPage
- * RegionDef
- * GWizard
-
-PURPOSE: Create a new GRASS location. User can choose from multiple methods
-
-AUTHORS: The GRASS Development Team
- Michael Barton
- Jachym Cepicky
-
-COPYRIGHT: (C) 2006-2007 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.
-"""
-import os
-import shutil
-import re
-import string
-import sys
-
-import wx
-import wx.lib.mixins.listctrl as listmix
-import wx.lib.rcsizer as rcs
-import wx.wizard as wiz
-
-import gui_modules
-import gui_modules.gcmd as gcmd
-try:
- import subprocess
-except:
- from compat import subprocess
-
-
-gmpath = gui_modules.__path__[0]
-sys.path.append(gmpath)
-
-
-global coordsys
-global north
-global south
-global east
-global west
-global resolution
-global wizerror
-
-coordsys = ''
-north = ''
-south = ''
-east = ''
-west = ''
-resolution = ''
-
-class TitledPage(wiz.WizardPageSimple):
- """
- Class to make wizard pages. Generic methods to make
- labels, text entries, and buttons.
- """
- def __init__(self, parent, title):
- wiz.WizardPageSimple.__init__(self, parent)
-
- self.title = wx.StaticText(self,-1,title)
- self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD))
-
- self.sizer = rcs.RowColSizer()
- tmpsizer = wx.BoxSizer(wx.VERTICAL)
-
- tmpsizer.Add(self.title, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
- tmpsizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0)
- tmpsizer.Add(self.sizer, wx.EXPAND)
-
- self.SetSizer(tmpsizer)
- self.SetAutoLayout(True)
-
- def MakeRLabel(self, text=""):
- """Make right-aligned label"""
- try:
- if text[-1] != " ":
- text += " "
- except:
- pass
- return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT)
-
- def MakeLLabel(self, text=""):
- """Make left-aligned label"""
- try:
- if text[-1] != " ":
- text += " "
- except:
- pass
- return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT)
-
- def MakeTextCtrl(self,text='', size=(100,-1)):
- """Generic text control"""
- return wx.TextCtrl(self,-1, text, size=size)
-
- def MakeButton(self,text, size=(75,25)):
- """Generic button"""
- return wx.Button(self, -1, text,
- style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL,
- size=size)
-
-
-class DatabasePage(TitledPage):
- """
- Wizard page for setting GIS data directory and location name
- """
- def __init__(self, wizard, parent, grassdatabase):
- TitledPage.__init__(self, wizard, "Define GRASS database and new Location Name")
-
- self.grassdatabase = grassdatabase
- self.location = ''
-
- # buttons
- self.bbrowse = self.MakeButton("Browse...")
-
- # text controls
- self.tgisdbase = self.MakeTextCtrl(grassdatabase, size=(300, -1))
- self.tlocation = self.MakeTextCtrl("newLocation", size=(300, -1))
-
- # layout
- self.sizer.Add(self.MakeRLabel("GIS Data Directory:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=1, col=2)
- self.sizer.Add(self.tgisdbase,0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=1, col=3)
- self.sizer.Add(self.bbrowse, 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=1, col=4)
- #
- self.sizer.Add(self.MakeRLabel("Project Location"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=2, col=2)
- self.sizer.Add(self.tlocation,0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=2, col=3)
- self.sizer.Add(self.MakeRLabel("(projection/coordinate system)"), 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5,
- row=2, col=4)
-
- # bindings
- self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged)
-
- def OnBrowse(self, event):
- dlg = wx.DirDialog(self, "Choose GRASS data directory:", os.getcwd(),wx.DD_DEFAULT_STYLE)
- if dlg.ShowModal() == wx.ID_OK:
- self.grassdatabase = dlg.GetPath()
- self.tgisdbase.SetValue(self.grassdatabase)
- dlg.Destroy()
-
- def onPageChanging(self,event=None):
- if os.path.isdir(os.path.join(self.tgisdbase.GetValue(),self.tlocation.GetValue())):
- dlg = wx.MessageDialog(self, "Could not create new location: <%s> directory exists "\
- % str(self.tlocation.GetValue()),"Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- event.Veto()
- return
-
- if not self.tlocation.GetValue():
- dlg = wx.MessageDialog(self, "Could not create new location: location not set "\
- ,"Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- event.Veto()
- return
-
- self.location = self.tlocation.GetValue()
- self.grassdatabase = self.tgisdbase.GetValue()
-
- def OnPageChanged(self,event=None):
- self.grassdatabase = self.tgisdbase.GetValue()
- self.location = self.tlocation.GetValue()
-
-
-class CoordinateSystemPage(TitledPage):
- """
- Wizard page for choosing method for location creation
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Choose method for creating a new location")
-
- self.parent = parent
- global coordsys
-
- # toggles
- self.radio1 = wx.RadioButton( self, -1, " Select coordinate system " , style = wx.RB_GROUP)
- self.radio2 = wx.RadioButton( self, -1, " Select EPSG code for coordinate system " )
- self.radio3 = wx.RadioButton( self, -1, " Use coordinate system of selected georeferenced file " )
- self.radio4 = wx.RadioButton( self, -1, " Create custom PROJ.4 parameters string for coordinate system " )
- self.radio5 = wx.RadioButton( self, -1, " Create arbitrary non-earth coordinate system (XY)" )
-
- # layout
- self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2)
- self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2)
- self.sizer.Add(self.radio3, 0, wx.ALIGN_LEFT, row=3, col=2)
- self.sizer.Add(self.radio4, 0, wx.ALIGN_LEFT, row=4, col=2)
- self.sizer.Add(self.radio5, 0, wx.ALIGN_LEFT, row=5, col=2)
-
- # bindings
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId())
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId())
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio3.GetId())
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio4.GetId())
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio5.GetId())
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-
- def OnPageChange(self,event=None):
- global coordsys
- if event.GetDirection() and not coordsys:
- wx.MessageBox('You must select a coordinate system')
- event.Veto()
-
- def SetVal(self,event):
- global coordsys
- if event.GetId() == self.radio1.GetId():
- coordsys = "proj"
- self.SetNext(self.parent.projpage)
- self.parent.sumpage.SetPrev(self.parent.datumpage)
- elif event.GetId() == self.radio2.GetId():
- coordsys = "epsg"
- self.SetNext(self.parent.epsgpage)
- self.parent.sumpage.SetPrev(self.parent.epsgpage)
- elif event.GetId() == self.radio3.GetId():
- coordsys = "file"
- self.SetNext(self.parent.filepage)
- self.parent.sumpage.SetPrev(self.parent.filepage)
- elif event.GetId() == self.radio4.GetId():
- coordsys = "custom"
- self.SetNext(self.parent.custompage)
- self.parent.sumpage.SetPrev(self.parent.custompage)
- elif event.GetId() == self.radio5.GetId():
- coordsys = "xy"
- self.SetNext(self.parent.sumpage)
- set.parent.sumpage.SetPrev(self.parent.csystemspage)
-
-class ProjectionsPage(TitledPage):
- """
- Wizard page for selecting projection (select coordinate system option)
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Choose projection")
-
- self.parent = parent
- self.proj = ''
- self.projdesc = ''
-
- # text input
- self.tproj = self.MakeTextCtrl("", size=(200,-1))
-
- # search box
- self.searchb = wx.SearchCtrl(self, size=(200,-1),
- style=wx.TE_PROCESS_ENTER)
-
- self.projlist = wx.ListCtrl(self, id=wx.ID_ANY,
- size=(650,275),
- style=wx.LC_REPORT |
- wx.LC_HRULES |
- wx.EXPAND)
- self.projlist.InsertColumn(0, 'Code')
- self.projlist.InsertColumn(1, 'Description')
- self.projlist.SetColumnWidth(0, 100)
- self.projlist.SetColumnWidth(1, 500)
-
- # layout
- self.sizer.Add(self.MakeRLabel("Projection code:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=2)
- self.sizer.Add(self.tproj, 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=3)
-
- self.sizer.Add(self.MakeRLabel("Search in projection description"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=2)
- self.sizer.Add(self.searchb, 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=3)
-
- self.sizer.Add(self.projlist,
- wx.EXPAND |
- wx.ALIGN_LEFT |
- wx.ALL, 5, row=3, col=1, colspan=4)
-
- # events
- self.Bind(wx.EVT_TEXT, self.OnText, self.tproj)
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.projlist)
- self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-
- self._onBrowseProj(None, None)
-
- def OnPageChange(self,event):
- if event.GetDirection() and self.proj not in self.parent.projections:
- wx.MessageBox('You must select a valid projection in order to continue')
- event.Veto()
- if self.proj == 'utm':
- self.parent.projtypepage.text_utm.SetEditable(True)
- self.parent.projtypepage.hemischoices = ['north','south']
- else:
- self.parent.projtypepage.text_utm.SetValue('')
- self.parent.projtypepage.text_utm.SetEditable(False)
- self.parent.projtypepage.hemischoices = []
-
- def OnText(self, event):
- self.proj = event.GetString()
- if self.proj in self.parent.projections:
- self.projdesc = self.parent.projections[self.proj]
-
- def OnDoSearch(self,event):
- str = self.searchb.GetValue()
- listItem = self.projlist.GetColumn(1)
-
- for i in range(self.projlist.GetItemCount()):
- listItem = self.projlist.GetItem(i,1)
- if listItem.GetText().find(str) > -1:
- self.proj = self.projlist.GetItem(i, 0).GetText()
- self.tproj.SetValue(self.proj)
- break
-
- self._onBrowseProj(None,str)
-
- def OnItemSelected(self,event):
- index = event.m_itemIndex
- item = event.GetItem()
-
- self.proj = item.GetText()
- self.projdesc = self.projlist.GetItem(index, 1).GetText()
- self.tproj.SetValue(self.proj)
-
- def _onBrowseProj(self,event,search=None):
- try:
- projlist = self.parent.projections.items()
- projlist.sort()
- self.projlist.DeleteAllItems()
- for proj,desc in projlist:
- entry = self.projlist.GetItemCount()
- if search and (proj.lower().find(search.lower()) > -1 or \
- desc.lower().find(search.lower()) > -1) or \
- not search:
- index = self.projlist.InsertStringItem(entry,proj)
- self.projlist.SetStringItem(index,1,desc)
-
- self.projlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- self.projlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.projlist.SendSizeEvent()
-
- except StandardError, e:
- dlg = wx.MessageDialog(self, "Could not read projections list: %s " % e,
- "Could not read projections", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-class ProjTypePage(TitledPage):
- """
- Wizard page for selecting method of setting coordinate system parameters
- (select coordinate system option)
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters")
- global coordsys
-
- self.utmzone = ''
- self.utmhemisphere = ''
- self.hemischoices = ["north","south"]
- self.parent = parent
-
- self.radio1 = wx.RadioButton( self, -1, " Select datum with associated ellipsoid", style = wx.RB_GROUP )
- self.radio2 = wx.RadioButton( self, -1, " Select ellipsoid" )
- self.title_utm = self.MakeLLabel("Set zone for UTM projection")
- self.text_utm = self.MakeTextCtrl(size=(100,-1))
- self.label_utm = self.MakeRLabel("Zone: ")
- self.hemisphere = wx.Choice(self, -1, (100, 50), choices = self.hemischoices)
- self.label_hemisphere = self.MakeRLabel("Hemisphere for zone: ")
-
- # layout
- self.sizer.Add(self.radio1, 0, wx.ALIGN_LEFT, row=1, col=2)
- self.sizer.Add(self.radio2, 0, wx.ALIGN_LEFT, row=2, col=2)
- self.sizer.Add(self.title_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=4,col=2)
- self.sizer.Add(self.label_utm, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1)
- self.sizer.Add(self.text_utm, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2)
- self.sizer.Add(self.label_hemisphere, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=6,col=1)
- self.sizer.Add(self.hemisphere, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=6,col=2)
-
- self.title_utm.Hide()
- self.text_utm.Hide()
- self.label_utm.Hide()
- self.hemisphere.Hide()
- self.label_hemisphere.Hide()
-
- # bindings
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio1.GetId())
- self.Bind(wx.EVT_RADIOBUTTON, self.SetVal, id=self.radio2.GetId())
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
-
- def OnPageChange(self,event=None):
- if event.GetDirection() and self.parent.projpage.proj == 'utm' and self.utmzone == '':
- wx.MessageBox('You must set a zone for a UTM projection')
- event.Veto()
- self.title_utm.Hide()
- self.text_utm.Hide()
- self.label_utm.Hide()
- self.hemisphere.Hide()
- self.label_hemisphere.Hide()
-
- def OnEnterPage(self,event):
- if self.parent.projpage.proj == 'utm':
- self.title_utm.Show()
- self.text_utm.Show()
- self.label_utm.Show()
- self.hemisphere.Show()
- self.label_hemisphere.Show()
-
- self.Bind(wx.EVT_CHOICE, self.OnHemisphere, self.hemisphere)
- self.Bind(wx.EVT_TEXT, self.GetUTM, self.text_utm)
-
- def SetVal(self, event):
- global coordsys
- if event.GetId() == self.radio1.GetId():
- self.SetNext(self.parent.datumpage)
- self.parent.sumpage.SetPrev(self.parent.datumpage)
- elif event.GetId() == self.radio2.GetId():
- self.SetNext(self.parent.ellipsepage)
- self.parent.sumpage.SetPrev(self.parent.ellipsepage)
-
- def GetUTM(self, event):
- self.utmzone = event.GetString()
-
- def OnHemisphere(self, event):
- self.utmhemisphere = event.GetString()
-
-
-class DatumPage(TitledPage):
- """
- Wizard page for selecting datum (with associated ellipsoid)
- and datum transformation parameters (select coordinate system option)
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Specify geodetic datum")
-
- self.parent = parent
- self.datum = ''
- self.datumdesc = ''
- self.ellipsoid = ''
- self.datumparams = ''
- self.transform = ''
- self.transregion = ''
- self.transparams = ''
- self.hastransform = False
- self.proj4params = ''
-
- # text input
- self.tdatum = self.MakeTextCtrl("", size=(200,-1))
- self.ttrans = self.MakeTextCtrl("", size=(200,-1))
-
- # search box
- self.searchb = wx.SearchCtrl(self, size=(200,-1),
- style=wx.TE_PROCESS_ENTER)
-
- # button
-# self.bupdate = self.MakeButton("Update trans. parms.",
-# size=(-1,-1))
-
- # create list control for datum/elipsoid list
- self.datumlist = wx.ListCtrl(self, id=wx.ID_ANY,
- size=(650,150),
- style=wx.LC_REPORT|
- wx.LC_HRULES|
- wx.EXPAND)
- self.datumlist.InsertColumn(0, 'Code')
- self.datumlist.InsertColumn(1, 'Description')
- self.datumlist.InsertColumn(2, 'Ellipsoid')
- self.datumlist.SetColumnWidth(0, 100)
- self.datumlist.SetColumnWidth(1, 250)
- self.datumlist.SetColumnWidth(2, 100)
-
- # create list control for datum transformation parameters list
- self.transformlist = wx.ListCtrl(self, id=wx.ID_ANY,
- size=(650,125),
- style=wx.LC_REPORT |
- wx.LC_HRULES |
- wx.EXPAND)
- self.transformlist.InsertColumn(0, 'Code')
- self.transformlist.InsertColumn(1, 'Datum')
- self.transformlist.InsertColumn(2, 'Description')
- self.transformlist.SetColumnWidth(0, 50)
- self.transformlist.SetColumnWidth(1, 125)
- self.transformlist.SetColumnWidth(2, 250)
-
- # layout
- self.sizer.Add(self.MakeRLabel("Datum code:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=1)
- self.sizer.Add(self.tdatum, 0 ,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=2)
-# self.sizer.Add(self.bupdate, 0 ,
-# wx.ALIGN_LEFT |
-# wx.ALIGN_CENTER_VERTICAL |
-# wx.ALL, 5, row=1, col=3)
- self.sizer.Add(self.MakeRLabel("Search in description:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=2)
- self.sizer.Add(self.searchb, 0 ,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=2)
-
- self.sizer.Add(self.datumlist,
- wx.EXPAND |
- wx.ALIGN_LEFT |
- wx.ALL, 5, row=3, col=1, colspan=4)
-
- self.sizer.Add(self.MakeRLabel("Transformation parameters:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=5)
- self.sizer.Add(self.ttrans, 0 ,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=5, col=2)
-
- self.sizer.Add(self.transformlist,
- wx.EXPAND |
- wx.ALIGN_LEFT |
- wx.ALL, 5, row=6, col=1, colspan=4)
-
- # events
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnDatumSelected, self.datumlist)
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnTransformSelected, self.transformlist)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-# self.bupdate.Bind(wx.EVT_BUTTON, self._onBrowseParams)
- self.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
- self.Bind(wx.EVT_TEXT, self.OnDText, self.tdatum)
-
- self._onBrowseDatums(None,None)
-
- def OnPageChange(self,event):
- self.proj4params = ''
- if event.GetDirection() and self.datum not in self.parent.datums:
- wx.MessageBox('You must select a valid datum in order to continue')
- event.Veto()
-# if self.hastransform == True and self.transform == '':
-# wx.MessageBox('You must select a datum transform')
-# event.Veto()
- self.GetNext().SetPrev(self)
- self.parent.ellipsepage.ellipseparams = self.parent.ellipsoids[self.ellipsoid][1]
- self.GetNext().SetPrev(self)
-
- def OnDText(self, event):
- self.datum = event.GetString()
- if self.datum in self.parent.datums:
- self.datumdesc = self.parent.datums[self.datum][0]
- self.ellipsoid = self.parent.datums[self.datum][1]
- self.datumparams = self.parent.datums[self.datum][2]
-
- self._onBrowseParams(None,self.datum)
-
- def OnTText(self, event):
- self.transform = event.GetString()
- if self.transform in self.parent.transforms:
- self.transdatum = self.parent.transforms[self.transform][0]
- self.transregion = self.parent.transforms[self.transform][1]
- self.transparams = self.parent.transforms[self.transform][2]
-
- def OnDoSearch(self,event):
- str = self.searchb.GetValue()
- listItem = self.datumlist.GetColumn(1)
-
- for i in range(self.datumlist.GetItemCount()):
- listItem = self.datumlist.GetItem(i,1)
- if listItem.GetText().find(str) > -1:
- datum = self.datumlist.GetItem(i, 0)
- self.tdatum.SetValue(datum.GetText())
- break
-
- self._onBrowseDatums(None,str)
-
- def OnTransformSelected(self,event):
- index = event.m_itemIndex
- item = event.GetItem()
-
- self.transform = item.GetText()
- self.transdatum = self.parent.transforms[self.transform][0]
- self.transregion = self.parent.transforms[self.transform][1]
- self.transparams = self.parent.transforms[self.transform][2]
-
- self.ttrans.SetValue(str(self.transform))
-
- def OnDatumSelected(self,event):
- index = event.m_itemIndex
- item = event.GetItem()
-
- self.datum = item.GetText()
- self.datumdesc = self.parent.datums[self.datum][0]
- self.ellipsoid = self.parent.datums[self.datum][1]
- self.datumparams = self.parent.datums[self.datum][2]
-
- self.tdatum.SetValue(self.datum)
- self._onBrowseParams(None, self.datum)
- event.Skip()
-
- def _onBrowseParams(self, event=None, search=None):
- search = self.datum.strip()
- try:
- self.transform = ''
- self.transformlist.DeleteAllItems()
- for item in self.parent.transforms:
- transdatum = self.parent.transforms[item][0]
- transregion = self.parent.transforms[item][1]
- entry = self.transformlist.GetItemCount()
- if (transdatum.lower() == search.lower()):
- index = self.transformlist.InsertStringItem(entry,item)
- self.transformlist.SetStringItem(index,1,transdatum)
- self.transformlist.SetStringItem(index,2,transregion)
- self.hastransform = True
-
- self.transformlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- self.transformlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.transformlist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
- self.transformlist.SendSizeEvent()
-
- except IOError, e:
- self.transformlist.DeleteAllItems()
- dlg = wx.MessageDialog(self, "Could not read datum params: %s " % e,
- "Could not read file", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
- def _onBrowseDatums(self,event,search=None):
- try:
- self.datum = ''
- self.datumlist.DeleteAllItems()
-
- datumlist = self.parent.datums.items()
- datumlist.sort()
- for datum,info in datumlist:
- datumdesc = info[0]
- ellipse = info[1]
- entry = self.datumlist.GetItemCount()
- if search and (datum.lower().find(search.lower()) > -1 or\
- datumdesc.lower().find(search.lower()) > -1 or\
- ellipse.lower().find(search.lower()) > -1) or\
- not search:
- index = self.datumlist.InsertStringItem(entry,datum)
- self.datumlist.SetStringItem(index,1,datumdesc)
- self.datumlist.SetStringItem(index,2,ellipse)
-
- self.datumlist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- self.datumlist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.datumlist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
- self.datumlist.SendSizeEvent()
-
- except IOError, e:
- dlg = wx.MessageDialog(self, "Could not read datums: %s " % e,
- "Could not read datums list", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-class EllipsePage(TitledPage):
- """
- Wizard page for selecting ellipsoid (select coordinate system option)
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Specify ellipsoid")
-
- self.parent = parent
- self.ellipse = ''
- self.ellipsedesc = ''
- self.ellipseparams = ''
- self.proj4params = ''
-
- # text input
- self.tellipse = self.MakeTextCtrl("", size=(200,-1))
-
- # search box
- self.searchb = wx.SearchCtrl(self, size=(200,-1),
- style=wx.TE_PROCESS_ENTER)
-
- # create list control for ellipse list
- self.ellipselist = wx.ListCtrl(self, id=wx.ID_ANY,
- size=(650,250),
- style=wx.LC_REPORT|
- wx.LC_HRULES|
- wx.EXPAND)
- self.ellipselist.InsertColumn(0, 'Code')
- self.ellipselist.InsertColumn(1, 'Description')
- self.ellipselist.SetColumnWidth(0, 100)
- self.ellipselist.SetColumnWidth(1, 250)
-
- # layout
- self.sizer.Add(self.MakeRLabel("Ellipse code:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=1)
- self.sizer.Add(self.tellipse, 0 ,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=2)
- self.sizer.Add(self.MakeRLabel("Search in description:"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=1)
- self.sizer.Add(self.searchb, 0 ,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=2)
-
- self.sizer.Add(self.ellipselist, 0 ,
- wx.EXPAND |
- wx.ALIGN_LEFT |
- wx.ALL, 5, row=3, col=1, colspan=3)
-
- # events
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEllipseSelected, self.ellipselist)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
- self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
- self.Bind(wx.EVT_TEXT, self.OnText, self.tellipse)
-
- self._onBrowseEllipse(None,None)
-
- def OnPageChange(self,event):
- self.proj4params = ''
- if event.GetDirection() and self.ellipse not in self.parent.ellipsoids:
- wx.MessageBox('You must select a valid ellipsoid in order to continue')
- event.Veto()
- self.GetNext().SetPrev(self)
- self.parent.datumpage.datumparams = ''
- self.parent.datumpage.transparams = ''
- self.GetNext().SetPrev(self)
-
- def OnText(self, event):
- self.ellipse = event.GetString()
- if self.ellipse in self.parent.ellipsoids:
- self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0]
- self.ellipseparams = self.parent.ellipsoids[self.ellipse][1]
-
- def OnDoSearch(self,event):
- str = self.searchb.GetValue()
- listItem = self.ellipselist.GetColumn(1)
-
- for i in range(self.ellipselist.GetItemCount()):
- item = self.ellipselist.GetItem(i,0)
- itemdesc = self.ellipselist.GetItem(i,1)
- if itemdesc.GetText().find(str) > -1:
- self.ellipse = item.GetText()
- self.tellipse.SetValue(self.ellipse)
- self.ellipselist.EnsureVisible(long(self.ellipselist.GetItem(i)))
- break
-
- self._onBrowseEllipse(None,str)
-
- def OnEllipseSelected(self,event):
- index = event.m_itemIndex
- item = event.GetItem()
-
- self.ellipse = item.GetText()
- self.ellipsedesc = self.parent.ellipsoids[self.ellipse][0]
- self.ellipseparams = self.parent.ellipsoids[self.ellipse][1]
-
- self.tellipse.SetValue(self.ellipse)
- self._onBrowseEllipse(None)
-
- def _onBrowseEllipse(self,event,search=None):
- try:
- ellipselist = self.parent.ellipsoids.items()
- ellipselist.sort()
- self.ellipselist.DeleteAllItems()
- for ellipsoid,info in ellipselist:
- desc = info[0]
- entry = self.ellipselist.GetItemCount()
- if search and (ellipsoid.lower().find(search.lower()) > -1 or \
- desc.lower().find(search.lower()) > -1) or \
- not search:
- index = self.ellipselist.InsertStringItem(entry,ellipsoid)
- self.ellipselist.SetStringItem(index,1,desc)
-
- self.ellipselist.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- self.ellipselist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.ellipselist.SendSizeEvent()
- except IOError, e:
- dlg = wx.MessageDialog(self, "Could not read ellipse information: %s " % e,
- "Problem parsing ellipse list", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-class GeoreferencedFilePage(TitledPage):
- """
- Wizard page for selecting georeferenced file to use
- for setting coordinate system parameters
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Select georeferenced file")
-
- self.georeffile = ''
-
- # create controls
- self.lfile= wx.StaticText(self, -1, "Georeferenced file: ",
- style=wx.ALIGN_RIGHT)
- self.tfile = wx.TextCtrl(self,-1, "", size=(300,-1))
- self.bbrowse = wx.Button(self, -1, "Browse...")
-
- # do layout
- self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT |
- wx.ALIGN_CENTRE_VERTICAL |
- wx.ALL, 5, row=1, col=2)
- self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT |
- wx.ALIGN_CENTRE_VERTICAL |
- wx.ALL, 5, row=1, col=3)
- self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT |
- wx.ALL, 5, row=1, col=4)
-
- self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
- self.Bind(wx.EVT_TEXT, self.OnText, self.tfile)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-
- def OnPageChange(self, event):
- if event.GetDirection() and self.georeffile == '':
- wx.MessageBox('You must select a georeferenced file in order to continue')
- event.Veto()
- self.GetNext().SetPrev(self)
-
- def OnText(self, event):
- self.georeffile = event.GetString()
-
- def OnBrowse(self, event):
-
- dlg = wx.FileDialog(self, "Choose a georeferenced file:", os.getcwd(), "", "*.*", wx.OPEN)
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- self.tfile.SetValue(path)
- dlg.Destroy()
-
- def OnCreate(self, event):
- pass
-
-
-class EPSGPage(TitledPage):
- """
- Wizard page for selecting EPSG code for
- setting coordinate system parameters
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Choose EPSG Code")
- self.parent = parent
- self.epsgcode = ''
- self.epsgdesc = ''
-
-
- # labels
- self.lfile= wx.StaticText(self, -1, "Path to the EPSG-codes file: ",
- style=wx.ALIGN_RIGHT)
- self.lcode= wx.StaticText(self, -1, "EPSG code: ",
- style=wx.ALIGN_RIGHT)
- self.lsearch= wx.StaticText(self, -1, "Search in code description: ",
- style=wx.ALIGN_RIGHT)
-
- # text input
- epsgdir = os.path.join(os.environ["GRASS_PROJSHARE"], 'epsg')
- self.tfile = wx.TextCtrl(self,-1, epsgdir, size=(200,-1))
- self.tcode = wx.TextCtrl(self,-1, "", size=(200,-1))
-
- # buttons
- self.bbrowse = wx.Button(self, -1, "Browse...")
- self.bbcodes = wx.Button(self, -1, "Browse Codes...")
-
- # search box
- self.searchb = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER)
-
- self.epsglist = wx.ListCtrl(self, id=wx.ID_ANY,
- size=(650,275),
- style=wx.LC_REPORT|
- wx.LC_HRULES|
- wx.EXPAND)
- self.epsglist.InsertColumn(0, 'Code', wx.LIST_FORMAT_CENTRE)
- self.epsglist.InsertColumn(1, 'Description', wx.LIST_FORMAT_LEFT)
- self.epsglist.InsertColumn(2, 'Parameters', wx.LIST_FORMAT_LEFT)
- self.epsglist.SetColumnWidth(0, 50)
- self.epsglist.SetColumnWidth(1, 300)
- self.epsglist.SetColumnWidth(2, 325)
-
- # layout
- self.sizer.Add(self.lfile, 0, wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=1)
- self.sizer.Add(self.tfile, 0, wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=2)
- self.sizer.Add(self.bbrowse, 0, wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=1, col=3)
-
- self.sizer.Add(self.lcode, 0, wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=2)
- self.sizer.Add(self.tcode, 0, wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2, col=2)
-
- self.sizer.Add(self.lsearch, 0, wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, col=1, row=3)
- self.sizer.Add(self.searchb, 0, wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=3, col=2)
- self.sizer.Add(self.bbcodes, 0 , wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=3, col=3)
-
- self.sizer.Add(self.epsglist, wx.ALIGN_LEFT|wx.EXPAND, 0, row=4, col=1, colspan=5)
-
- # events
- self.Bind(wx.EVT_BUTTON, self.OnBrowse, self.bbrowse)
- self.Bind(wx.EVT_BUTTON, self.OnBrowseCodes, self.bbcodes)
- self.Bind(wx.EVT_TEXT, self.OnText, self.tcode)
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.epsglist)
- self.searchb.Bind(wx.EVT_TEXT_ENTER, self.OnDoSearch, self.searchb)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-
- def OnPageChange(self, event):
- if event.GetDirection() and not self.epsgcode:
- wx.MessageBox('You must select an EPSG code')
- event.Veto()
- self.GetNext().SetPrev(self)
-
- def OnText(self, event):
- self.epsgcode = event.GetString()
-
- def OnDoSearch(self,event):
- str = self.searchb.GetValue()
- listItem = self.epsglist.GetColumn(1)
-
- for i in range(self.epsglist.GetItemCount()):
- listItem = self.epsglist.GetItem(i,1)
- if listItem.GetText().find(str) > -1:
- self.epsgcode = self.epsglist.GetItem(i, 0)
- self.tcode.SetValue(self.epsgcode.GetText())
- break
-
- self.OnBrowseCodes(None,str)
-
- def OnBrowse(self, event):
-
- dlg = wx.FileDialog(self, "Choose EPSG codes file:",
- "/", "", "*.*", wx.OPEN)
- if dlg.ShowModal() == wx.ID_OK:
- path = dlg.GetPath()
- self.tfile.SetValue(path)
- dlg.Destroy()
-
- def OnItemSelected(self,event):
- index = event.m_itemIndex
- item = event.GetItem()
-
- self.epsgcode = item.GetText()
- self.epsgdesc = self.epsglist.GetItem(index, 1).GetText()
- self.tcode.SetValue(str(self.epsgcode))
-
- def OnBrowseCodes(self,event,search=None):
- try:
- self.epsglist.DeleteAllItems()
- f = open(self.tfile.GetValue(),"r")
- i=1
- j = 0
- descr = None
- code = None
- params = ""
- #self.epsglist.ClearAll()
- for line in f.readlines():
- line = line.strip()
- if line.find("#") == 0:
- descr = line[1:].strip()
- elif line.find("<") == 0:
- code = line.split(" ")[0]
- for par in line.split(" ")[1:]:
- params += par + " "
- code = code[1:-1]
- if code == None: code = 'no code'
- if descr == None: descr = 'no description'
- if params == None: params = 'no parameters'
- if i%2 == 0:
- if search and descr.lower().find(search.lower()) > -1 or\
- not search:
- index = self.epsglist.InsertStringItem(j, code)
- self.epsglist.SetStringItem(index, 1, descr)
- self.epsglist.SetStringItem(index, 2, params)
- j += 1
- # reset
- descr = None; code = None; params = ""
-# if i%2 == 0:
-# self.epsglist.SetItemBackgroundColour(i, "grey")
- i += 1
- f.close()
- self.epsglist.SetColumnWidth(1, wx.LIST_AUTOSIZE)
- self.epsglist.SetColumnWidth(2, wx.LIST_AUTOSIZE)
- self.SendSizeEvent()
- except StandardError, e:
- dlg = wx.MessageDialog(self, "Could not read EPGS codes: %s " % e,
- "Could not read file", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
-
-
-class CustomPage(TitledPage):
- """
- Wizard page for entering custom PROJ.4 string
- for setting coordinate system parameters
- """
-
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Choose method of specifying georeferencing parameters")
- global coordsys
- self.customstring = ''
- self.parent = parent
-
- self.text_proj4string = self.MakeTextCtrl(size=(400,100))
- self.label_proj4string = self.MakeRLabel("Enter PROJ.4 parameters string: ")
- self.sizer.Add(self.label_proj4string, 0, wx.ALIGN_RIGHT|wx.ALL, 5, row=5,col=1)
- self.sizer.Add(self.text_proj4string, 0, wx.ALIGN_LEFT|wx.ALL, 5, row=5,col=2)
-
- self.Bind(wx.EVT_TEXT, self.GetProjstring, self.text_proj4string)
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.OnPageChange)
-
- def OnPageChange(self, event):
- if event.GetDirection() and not self.customstring:
- wx.MessageBox('You must enter a PROJ.4 string')
- event.Veto()
- self.GetNext().SetPrev(self)
-
- def GetProjstring(self, event):
- self.customstring = event.GetString()
-
-
-class SummaryPage(TitledPage):
- """
- Shows summary result of choosing coordinate system parameters
- prior to creating location
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, "Summary")
-
- self.parent = parent
-
- # labels
- self.ldatabase = self.MakeLLabel("")
- self.llocation = self.MakeLLabel("")
- self.lprojection = self.MakeLLabel("")
-
- self.lprojection.Wrap(500)
-
- self.sizer.Add(self.MakeRLabel("GRASS database:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=1, col=0)
- self.sizer.Add(self.ldatabase, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=1, col=1)
- self.sizer.Add(self.MakeRLabel("Location name:"), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=2, col=0)
- self.sizer.Add(self.llocation, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=2, col=1)
- self.sizer.Add(wx.StaticLine(self, -1), 0, wx.ALIGN_RIGHT|wx.EXPAND|wx.ALL, 0, row=3, col=0, colspan=2)
- self.sizer.Add((10,10), 1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5, row=4, col=0)
- self.sizer.Add(self.MakeRLabel("Projection: "), 1, flag=wx.ALIGN_RIGHT|wx.ALL, border=5, row=5, col=0)
- self.sizer.Add(self.lprojection, 1, flag=wx.ALIGN_LEFT|wx.ALL, border=5, row=5, col=1)
- self.sizer.Add((10,20), 1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, border=5, row=6, col=0)
- self.sizer.Add(self.MakeLLabel("You can set the default extents and resolution after creating new location"), \
- 1, flag=wx.ALIGN_CENTRE|wx.ALL, border=5, row=7, col=0, colspan=2)
- self.sizer.Add(self.MakeLLabel("or you can set them during a working session."), \
- 1, flag=wx.ALIGN_CENTRE|wx.ALL, border=5, row=8, col=0, colspan=2)
-
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChange)
-
- def OnPageChange(self,event):
- """
- Insert values into text controls for summary of location creation options
- """
-
- database = self.parent.startpage.grassdatabase
- location = self.parent.startpage.location
-
- global coordsys
- if not coordsys:
- coordsys = 0
-
- projection = self.parent.projpage.proj
- projdesc = self.parent.projpage.projdesc
- utmzone = self.parent.projtypepage.utmzone
- utmhemisphere = self.parent.projtypepage.utmhemisphere
- ellipse = self.parent.ellipsepage.ellipse
- ellipsedesc = self.parent.ellipsepage.ellipsedesc
- datum = self.parent.datumpage.datum
- datumdesc = self.parent.datumpage.datumdesc
- ellipsoid = self.parent.datumpage.ellipsoid
- datumparams = self.parent.datumpage.datumparams
- transform = self.parent.datumpage.transform
- transregion = self.parent.datumpage.transregion
- transparams = self.parent.datumpage.transparams
-
- self.ldatabase.SetLabel(str(database))
- self.llocation.SetLabel(str(location))
- label = ''
- if coordsys == 'epsg':
- label = 'EPSG code %s (%s)' % (self.parent.epsgpage.epsgcode,self.parent.epsgpage.epsgdesc)
- self.lprojection.SetLabel(label)
- elif coordsys == 'file':
- label = 'matches file %s' % self.parent.filepage.georeffile
- self.lprojection.SetLabel(label)
- elif coordsys == 'proj':
- label = ('%s, %s%s' % (projdesc, datumdesc, ellipsedesc))
- self.lprojection.SetLabel(label)
- elif coordsys == 'xy':
- label = ('XY coordinate system. Not projected')
- self.lprojection.SetLabel(label)
- elif coordsys == 'custom':
- label = ('%s' % self.parent.custompage.customstring)
- self.lprojection.SetLabel(label)
-
-class RegionDef(wx.Frame):
- """
- Page for setting default region extents and resolution
- """
-
- def __init__(self,parent,id=wx.ID_ANY, title="Set default region values", location=None):
- wx.Frame.__init__(self, parent, id, title, size=(650,300))
-
- self.parent = parent
- self.location = location
-
- # inputs
- self.ttop = self.MakeTextCtrl("1", size=(150, -1))
- self.tbottom = self.MakeTextCtrl("0", size=(150, -1))
- self.tleft = self.MakeTextCtrl("0", size=(150, -1))
- self.tright = self.MakeTextCtrl("1", size=(150, -1))
- self.tres = self.MakeTextCtrl("1", size=(150, -1))
-
- self.north = 1.0
- self.south = 0.0
- self.east = 1.0
- self.west = 0.0
- self.res = 1.0
-
- # labels
- self.lmessage = wx.StaticText(self,-1, "", size=(300,50))
-
- # buttons
- self.bset = self.MakeButton("Set coordinates", size=(150,-1))
- self.bcancel = self.MakeButton("Cancel", size=(150,-1))
-
- #Set current working environment to PERMANENT mapset in selected location in order to set default region (WIND)
- envval = {}
- cmdlist = ['g.gisenv']
- p = gcmd.Command(cmdlist)
- if p.returncode == 0:
- output = p.module_stdout.read().strip("'").split(';\n')
- for line in output:
- line = line.strip()
- if '=' in line: key,val = line.split('=')
- envval[key] = val
- self.currlocation = envval['LOCATION_NAME'].strip("';")
- self.currmapset = envval['MAPSET'].strip("';")
- if self.currlocation == self.location and self.currmapset == 'PERMANENT':
- pass
- else:
- cmdlist = ['g.mapset', 'location=%s' % self.location, 'mapset=PERMANENT']
- gcmd.Command(cmdlist)
- else:
- wx.MessageBox('A valid location must be selected')
- return
-
- #Get current region settings
- region = {}
- cmdlist = ['g.region', '-gp']
- p = gcmd.Command(cmdlist)
- if p.returncode == 0:
- output = p.module_stdout.read().split('\n')
- for line in output:
- line = line.strip()
- if '=' in line: key,val = line.split('=')
- region[key] = float(val)
- else:
- wx.MessageBox('Invalid region')
- return
-
- self.north = region['n']
- self.south = region['s']
- self.east = region['e']
- self.west = region['w']
- self.res = region['ewres']
-
- # Insert current region settings into text controls
- self.ttop.SetValue(str(self.north))
- self.tbottom.SetValue(str(self.south))
- self.tleft.SetValue(str(self.west))
- self.tright.SetValue(str(self.east))
- self.tres.SetValue(str(self.res))
-
- # layout
- self.sizer = rcs.RowColSizer()
-
- self.sizer.Add(self.MakeLLabel("Region extents and resolution:"), 3,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 10, row=0,col=0, colspan=2)
-
- self.sizer.Add(self.MakeRLabel("North"), 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 0, row=1,col=2)
- self.sizer.Add(self.ttop, 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=2,col=2)
-
- self.sizer.Add(self.MakeRLabel("West"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 0, row=3,col=0)
- self.sizer.Add(self.tleft, 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=3,col=1)
-
- self.sizer.Add(self.tright, 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=3,col=3)
- self.sizer.Add(self.MakeRLabel("East"), 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 0, row=3,col=4)
-
- self.sizer.Add(self.tbottom, 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=4,col=2)
- self.sizer.Add(self.MakeRLabel("South"), 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 0, row=5,col=2)
-
- self.sizer.Add(self.MakeRLabel("Resolution"), 0,
- wx.ALIGN_RIGHT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=6,col=1)
- self.sizer.Add(self.tres, 0,
- wx.ALIGN_CENTER_HORIZONTAL |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=6,col=2)
-
- self.sizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND|wx.ALL, 0, row=7, col=0, colspan=6)
-
- self.sizer.Add(self.bset, 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=8, col=3 )
-
- self.sizer.Add(self.bcancel, 0,
- wx.ALIGN_LEFT |
- wx.ALIGN_CENTER_VERTICAL |
- wx.ALL, 5, row=8, col=1 )
-
-
- self.SetSizer(self.sizer)
- self.SetAutoLayout(True)
- self.Layout()
-
- self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset)
- self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel)
- self.Bind(wx.EVT_TEXT, self.OnNorth, self.ttop)
- self.Bind(wx.EVT_TEXT, self.OnSouth, self.tbottom)
- self.Bind(wx.EVT_TEXT, self.OnEast, self.tright)
- self.Bind(wx.EVT_TEXT, self.OnWest, self.tleft)
- self.Bind(wx.EVT_TEXT, self.OnRes, self.tres)
-
- def MakeRLabel(self, text=""):
- """Make right-aligned label"""
- try:
- if text[-1] != " ":
- text += " "
- except:
- pass
- return wx.StaticText(self, -1, text, style=wx.ALIGN_RIGHT)
-
- def MakeLLabel(self, text=""):
- """Make left-aligned label"""
- try:
- if text[-1] != " ":
- text += " "
- except:
- pass
- return wx.StaticText(self, -1, text, style=wx.ALIGN_LEFT)
-
- def MakeTextCtrl(self,text='', size=(100,-1)):
- """Generic text control"""
- return wx.TextCtrl(self,-1, text, size=size)
-
- def MakeButton(self,text, size=(75,25)):
- """Generic button"""
- return wx.Button(self, -1, text,
- style=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL,
- size=size)
-
- def OnNorth(self,event):
- self.north = event.GetString()
-
- def OnSouth(self, event):
- self.south = event.GetString()
-
- def OnEast(self,event):
- self.east = event.GetString()
-
- def OnWest(self,event):
- self.west = event.GetString()
-
- def OnRes(self,event):
- self.res = event.GetString()
-
- def OnSetButton(self,event=None):
- cmdlist = ['g.region', '-sgpa', 'n=%s' % self.north, 's=%s' % self.south, \
- 'e=%s' % self.east, 'w=%s' % self.west, 'res=%s' % self.res]
- p = gcmd.Command(cmdlist)
- if p.returncode == 0:
- output = p.module_stdout.read()
- wx.MessageBox('New default region:\n%s' % output)
- else:
- wx.MessageBox('Setting default region failed\n%s %s' % \
- (p.module_stderr.read(),p.module_stdout.read()))
- self.Destroy()
-
- def OnCancel(self, event):
- self.Destroy()
-
-class GWizard:
- """
- Start wizard here and finish wizard here
- """
-
- def __init__(self, parent, grassdatabase):
- wizbmp = wx.Image(os.path.join(os.getenv("GISBASE"),"etc","wx","images","wizard.png"), wx.BITMAP_TYPE_PNG)
- wizbmp.Rescale(250,600)
- wizbmp = wizbmp.ConvertToBitmap()
-
- global coordsys
- self.parent = parent
- # get georeferencing information from tables in $GISBASE/etc
-
- # make projections dictionary
- f = open(os.path.join(os.getenv("GISBASE"), "etc","projections"),"r")
- self.projections = {}
- for line in f.readlines():
- line = line.expandtabs(1)
- line = line.strip()
- if not line:
- continue
- if line == '' or line[0] == "#":
- continue
- proj,projdesc = line.split(":", 1)
- proj = proj.strip()
- projdesc = projdesc.strip()
- self.projections[proj] = projdesc
- f.close()
-
- f = open(os.path.join(os.getenv("GISBASE"), "etc","datum.table"),"r")
- self.datums = {}
- paramslist = []
- for line in f.readlines():
- line = line.expandtabs(1)
- line = line.strip()
- if not line:
- continue
- if line == '' or line[0] == "#":
- continue
- datum,info = line.split(" ", 1)
- info = info.strip()
- datumdesc,params = info.split(" ",1)
- datumdesc = datumdesc.strip('"')
- paramlist = params.split()
- ellipsoid = paramlist.pop(0)
- self.datums[datum] = (datumdesc,ellipsoid,paramlist)
- f.close()
-
- # make datum transforms dictionary
- f = open(os.path.join(os.getenv("GISBASE"), "etc","datumtransform.table"),"r")
- self.transforms = {}
- j = 1
- for line in f.readlines():
- transcode = 'T'+str(j)
- line = line.expandtabs(1)
- line = line.strip()
- if not line:
- continue
- if line == '' or line[0] == "#":
- continue
- datum,rest = line.split(" ", 1)
- rest = rest.strip('" ')
- params,rest = rest.split('"', 1)
- params = params.strip()
- rest = rest.strip('" ')
- try:
- region,info = rest.split('"', 1)
- info = info.strip('" ')
- info = region+': '+info
- except:
- info = rest
- self.transforms[transcode] = (datum,info,params)
- j+=1
- f.close()
-
- # make ellipsiods dictionary
- f = open(os.path.join(os.getenv("GISBASE"), "etc","ellipse.table"),"r")
- self.ellipsoids = {}
- for line in f.readlines():
- line = line.expandtabs(1)
- line = line.strip()
- if not line:
- continue
- if line == '' or line[0] == "#":
- continue
- ellipse,rest = line.split(" ", 1)
- rest = rest.strip('" ')
- desc,params = rest.split('"', 1)
- desc = desc.strip('" ')
- paramslist = params.split()
- self.ellipsoids[ellipse] = (desc,paramslist)
- f.close()
-
- # define wizard pages
- self.wizard = wiz.Wizard(parent, -1, "Define new Location",
- bitmap=wizbmp)
- self.startpage = DatabasePage(self.wizard, self, grassdatabase)
- self.csystemspage = CoordinateSystemPage(self.wizard, self)
- self.projpage = ProjectionsPage(self.wizard, self)
- self.projtypepage = ProjTypePage(self.wizard,self)
- self.epsgpage = EPSGPage(self.wizard, self)
- self.filepage = GeoreferencedFilePage(self.wizard, self)
- self.datumpage = DatumPage(self.wizard, self)
- self.ellipsepage = EllipsePage(self.wizard, self)
- self.custompage = CustomPage(self.wizard, self)
- self.sumpage = SummaryPage(self.wizard, self)
-
-
- # Set the initial order of the pages
- # it should follow the epsg line
- self.startpage.SetNext(self.csystemspage)
-
- self.csystemspage.SetPrev(self.startpage)
- self.csystemspage.SetNext(self.sumpage)
-
- self.projpage.SetPrev(self.csystemspage)
- self.projpage.SetNext(self.projtypepage)
-
- self.projtypepage.SetPrev(self.projpage)
- self.projtypepage.SetNext(self.datumpage)
-
- self.datumpage.SetPrev(self.projtypepage)
- self.datumpage.SetNext(self.sumpage)
-
- self.ellipsepage.SetPrev(self.projtypepage)
- self.ellipsepage.SetNext(self.sumpage)
-
- self.epsgpage.SetPrev(self.csystemspage)
- self.epsgpage.SetNext(self.sumpage)
-
- self.filepage.SetPrev(self.csystemspage)
- self.filepage.SetNext(self.sumpage)
-
- self.custompage.SetPrev(self.csystemspage)
- self.custompage.SetNext(self.sumpage)
-
- self.sumpage.SetPrev(self.csystemspage)
-
- self.wizard.FitToPage(self.datumpage)
-
- self.location = None #New location created
-
- success = False
-
- if self.wizard.RunWizard(self.startpage):
- success = self.onWizFinished()
- if success == True:
- self.location = self.startpage.location
- dlg = wx.MessageDialog(self.wizard,
- "Do you want to set the default region extents and resolution now?",
- "New location '%s' created"% self.location,
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_YES:
- dlg.Destroy()
- defineRegion = RegionDef(None, location=self.location)
- defineRegion.Show()
- else:
- dlg.Destroy()
-
- else:
- wx.MessageBox("Unable to create new location.")
- else:
- wx.MessageBox("Location wizard canceled. New location not created.")
-
-# self.wizard.Destroy()
-
- def onWizFinished(self):
- database = self.startpage.grassdatabase
- location = self.startpage.location
- global coordsys
- success = False
-
-# wx.MessageBox("finished database: %s, location: %s, coordsys: %s" % (database, location, coordsys))
- if os.path.isdir(os.path.join(database,location)):
- dlg = wx.MessageDialog(self, "Could not create new location: %s already exists"
- % os.path.join(database,location),"Could not create location",
- wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- if coordsys == "xy":
- success = self.XYCreate()
- elif coordsys == "latlong":
- rows = int(round((float(north)-float(south))/float(resolution)))
- cols = int(round((float(east)-float(west))/float(resolution)))
- cells = int(rows*cols)
- success = self.LatlongCreate()
- elif coordsys == "proj":
- success = self.Proj4Create()
- elif coordsys == 'custom':
- success = self.CustomCreate()
- elif coordsys == "epsg":
- success = self.EPSGCreate()
- elif coordsys == "file":
- success = self.FileCreate()
-
- return success
-
- def XYCreate(self):
- """
- Create an XY location
- """
- database = self.startpage.grassdatabase
- location = self.startpage.location
-
- dlg = wx.MessageDialog(self.wizard, "New XY location '%s' will be created (not projected or georeferenced)"
- % location,
- "Create new XY location?",
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- return False
- else:
- dlg.Destroy()
-
- #Make location folder and PERMANT mapset
- os.mkdir(os.path.join(database,location))
- os.mkdir(os.path.join(database,location,'PERMANENT'))
-
- #Make DEFAULT_WIND and WIND files
- regioninfo = ['proj: 0',
- 'zone: 0',
- 'north: 1',
- 'south: 0',
- 'east: 1',
- 'west: 0',
- 'cols: 1',
- 'rows: 1',
- 'e-w resol: 1',
- 'n-s resol: 1',
- 'top: 1',
- 'bottom: 0',
- 'cols3: 1',
- 'rows3: 1',
- 'depths: 1',
- 'e-w resol3: 1',
- 'n-s resol3: 1',
- 't-b resol: 1']
-
- try:
- defwind = open(os.path.join(database,location,"PERMANENT","DEFAULT_WIND"),'w')
- for param in regioninfo:
- defwind.write(param+'\n')
- defwind.close()
- shutil.copy(os.path.join(database,location,"PERMANENT","DEFAULT_WIND"),\
- os.path.join(database,location,"PERMANENT","WIND"))
-
- #Make MYNAME file
- myname = open(os.path.join(database,location,"PERMANENT","MYNAME"),'w')
- myname.write('')
- myname.close()
- return True
- except:
- return False
-
- def Proj4Create(self):
- """
- Create a new location for selected projection
- """
-
- location = self.startpage.location
- proj = self.projpage.proj
- projdesc = self.projpage.projdesc
-
- utmzone = self.projtypepage.utmzone
- utmhemisphere = self.projtypepage.utmhemisphere
-
- datum = self.datumpage.datum
- if self.datumpage.datumdesc:
- datumdesc = self.datumpage.datumdesc+' - '+self.datumpage.ellipsoid
- else: datumdesc = ''
- datumparams = self.datumpage.datumparams
- transparams = self.datumpage.transparams
-
- ellipse = self.ellipsepage.ellipse
- ellipsedesc = self.ellipsepage.ellipsedesc
- ellipseparams = self.ellipsepage.ellipseparams
-
- # Creating PROJ.4 string
- if proj == 'll':
- proj = 'longlat'
-
- if proj == 'utm' and utmhemisphere == 'south':
- proj4string = '+proj=%s +zone=%s +south' % (proj, utmzone)
- elif proj == 'utm':
- proj4string = '+proj=%s +zone=%s' % (proj, utmzone)
- else:
- proj4string = '+proj=%s ' % (proj)
-
- proj4params = ''
- # set ellipsoid parameters
- for item in ellipseparams:
- if item[:4] == 'f=1/':
- item = '+rf='+item[4:]
- else:
- item = '+'+item
- proj4params = '%s %s' % (proj4params, item)
- # set datum and transform parameters if relevant
- if datumparams:
- for item in datumparams:
- proj4params = '%s +%s' % (proj4params,item)
- if transparams:
- proj4params = '%s +no_defs +%s' % (proj4params,transparams)
- else:
- proj4params = '%s +no_defs' % proj4params
- else:
- proj4params = '%s +no_defs' % proj4params
-
- proj4string = '%s %s' % (proj4string, proj4params)
-
- msgtext = "New location '%s' will be created georeferenced to" % location
- georeftext = '%s: %s%s' % (projdesc,datumdesc,ellipsedesc)
- p4text = '(PROJ.4 string: %s)' % proj4string
-
- dlg = wx.MessageDialog(self.wizard, msgtext+' '+georeftext+' '+p4text,
- "Create new location?",
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- return False
- else:
- dlg.Destroy()
-
- # Creating location from PROJ.4 string passed to g.proj
- try:
- cmdlist = ['g.proj', '-c', 'proj4=%s' % proj4string, 'location=%s' % location]
- p = gcmd.Command(cmdlist)
- if p.module.returncode == 0:
- return True
- else:
- return False
-
- except StandardError, e:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- def CustomCreate(self):
- proj4string = self.custompage.customstring
- location = self.startpage.location
-
- dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created using PROJ.4 string: %s"
- % (location,proj4string),
- "Create new location?",
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- return False
- else:
- dlg.Destroy()
-
- try:
- cmdlist = ['g.proj','-c','proj4=%s' % proj4string,'location=%s' % location]
- p = gcmd.Command(cmdlist)
- if p.module.returncode == 0:
- return True
- else:
- return False
-
- except StandardError, e:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
-
- def EPSGCreate(self):
- """
- Create a new location from an EPSG code.
- """
- epsgcode = self.epsgpage.epsgcode
- epsgdesc = self.epsgpage.epsgdesc
- location = self.startpage.location
- cmdlist = []
-
- if not epsgcode:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: EPSG Code value missing",
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to EPSG code %s: %s"
- % (location, epsgcode, epsgdesc),
- "Create new location from EPSG code?",
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- return False
- else:
- dlg.Destroy()
-
- # creating location
- try:
- cmdlist = ['g.proj','epsg=%s' % epsgcode,'datumtrans=-1']
- p = gcmd.Command(cmdlist)
- dtoptions = p.module_stdout.read()
- if dtoptions != None:
- dtrans = ''
- # open a dialog to select datum transform number
- dlg = wx.TextEntryDialog(self.wizard, dtoptions,
- caption='Select the number of a datum transformation to use',
- defaultValue='1',
- style=wx.TE_WORDWRAP|wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX|
- wx.RESIZE_BORDER|wx.VSCROLL|
- wx.OK|wx.CANCEL)
-
- if dlg.ShowModal() == wx.ID_CANCEL:
- dlg.Destroy()
- return False
- else:
- dtrans = dlg.GetValue()
- if dtrans != '':
- dlg.Destroy()
- else:
- wx.MessageBox('You must select a datum transform')
- return False
-
- cmdlist = ['g.proj','-c','epsg=%s' % epsgcode,'location=%s' % location,'datumtrans=%s' % dtrans]
- else:
- cmdlist = ['g.proj','-c','epsg=%s' % epsgcode,'location=%s' % location,'datumtrans=1']
-
- p = gcmd.Command(cmdlist)
- if p.module.returncode == 0:
- return True
- else:
- return False
-
- except StandardError, e:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- def FileCreate(self):
- """
- Create a new location from a georeferenced file
- """
- georeffile = self.filepage.georeffile
- location = self.startpage.location
-
- cmdlist = []
-
- dlg = wx.MessageDialog(self.wizard, "New location '%s' will be created georeferenced to file '%s'"
- % (location, georeffile), "Create new location from georeferenced file?",
- wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- return False
- else:
- dlg.Destroy()
-
- if not os.path.isfile(georeffile):
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: could not find file %s" % georeffile,
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- if not georeffile:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: georeferenced file not set",
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- # creating location
- try:
- cmdlist = ['g.proj','-c','georef=%s' % georeffile,'location=%s' % location]
- p = gcmd.Command(cmdlist)
- if p.module.returncode == 0:
- return True
- else:
- return False
-
- except StandardError, e:
- dlg = wx.MessageDialog(self.wizard, "Could not create new location: %s " % str(e),
- "Could not create location", wx.OK|wx.ICON_INFORMATION)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
-if __name__ == "__main__":
- gWizard = GWizard(None, "")
- GRASSStartUp = GWizard.StartUp(0)
- GRASSStartUp.MainLoop()
- #app.MainLoop()
Deleted: trunk/grassaddons/gui/states.txt
===================================================================
--- trunk/grassaddons/gui/states.txt 2007-10-19 22:28:09 UTC (rev 1148)
+++ trunk/grassaddons/gui/states.txt 2007-10-20 09:51:46 UTC (rev 1149)
@@ -1,185 +0,0 @@
-Afghanistan; 59.9,28.66 75.65,39.11
-Africa; -20.2,-37.6 53.4,35.75
-Albania; 19.36,39.42 21.39,42.71
-Algeria; -9.47,17.94 13.19,38.14
-Angola; 11.31,-18.68 24.97,-3.84
-Antarctic; -180,-90 180,-66
-Antarctica; -180,-90 180,-62.83
-Arctic; -180,66 180,90
-Argentina; -74.97,-56.71 -51.76,-20.25
-Armenia; 43.53,38.68 47.07,41.48
-Asia; 40,-10 180,83.5
-Australia; 111.22,-45.73 155.72,-8.88
-Austria; 9.27,45.99 17.93,49.38
-Azerbaijan; 44.58,38.04 50.96,42.2
-Bangladesh; 87.95,20.75 93.07,26.62
-Belgium; 2.54,49.31 6.69,51.69
-Belize; -89.18,15.78 -87.78,18.64
-Benin; 0.74,5.97 4.34,12.66
-Bhutan; 88.8,26.54 92.37,28.46
-Bolivia; -70.05,-23.63 -56.72,-9.13
-Bosnia and Herzegovina; 15.76,42.38 20.02,45.45
-Botswana; 19.57,-27.41 29.94,-17.32
-Brazil; -75.64,-35.81 -32.74,7.12
-Brunei; 114.22,3.96 115.42,5.09
-Bulgaria; 22.19,40.86 29.02,44.59
-Burkina Faso; -5.72,9.19 2.98,15.54
-Burma; 91.41,9.22 102.13,29.34
-Burundi; 28.98,-4.85 31.17,-2.35
-Byelarus; 22.91,50.82 33.38,56.65
-Cambodia; 102.28,10.07 107.98,14.86
-Cameroon; 8.22,1.06 16.85,13.65
-Canada; -145.27,37.3 -48.11,87.61
-Caribbean; -91.4,27.36 -55.4,6.48
-Central African Republic; 13.96,1.5 28.11,11.67
-Central America; -94.1,21.8 -75.8,6.61
-Chad; 12.88,6.67 24.97,24.19
-Chile; -77.16,-56.79 -64.9,-15.72
-China; 70.83,15.06 137.97,56.58
-Colombia; -79.69,-5 -66.15,13.28
-Congo; 10.93,-5.41 19.19,3.98
-Costa Rica; -85.83,7.9 -82.18,11.38
-Croatia; 13.47,42.09 19.92,46.84
-Cuba; -85.03,19.36 -73.44,23.68
-Cyprus; 32.23,34.44 34.78,35.78
-Czech Republic; 12.13,48.23 19.38,51.42
-Denmark; 8.02,54.68 12.89,58
-Djibouti; 41.89,10.78 43.77,12.81
-Dominican Republic; -71.87,17.54 -67.99,20.12
-East Pacific Ocean; -180,64.8 -72.7,-75.6
-Ecuador; -81.08,-5.35 -74.68,1.72
-Egypt; 24.29,21.29 37.61,32.14
-El Salvador; -90.05,13.07 -87.41,14.6
-Equatorial Guinea; 8.39,0.76 11.59,3.82
-Eritrea; 36.31,12 43.58,18.41
-Estonia; 23.3,57.29 28.59,59.75
-Ethiopia; 32.49,2.63 48.85,15.56
-Europe; -25.1,71.3 35,34.9
-Finland; 20.46,59.3 32.14,70.44
-France; -5.29,40.65 10.4,51.82
-French Guiana; -54.37,1.84 -51.23,5.89
-Gabon; 8.71,-4.23 15.01,2.6
-Gambia; -16.71,13.02 -13.66,13.96
-Germany; 5.68,46.86 15.68,55.41
-Ghana; -3.31,4.39 1.7,11.47
-Greece; 19.99,34.62 27.19,42.01
-Greenland; -75.34,56.78 -9.36,86.6
-Guatemala; -92.24,13.59 -87.87,18.06
-Guinea; -15.19,6.77 -6.87,13.02
-Guinea-Bissau; -16.51,10.97 -13.34,12.8
-Guyana; -61.41,0.81 -56.12,8.79
-Haiti; -74.38,17.88 -71.34,20.1
-Honduras; -89.47,12.75 -82.92,16.31
-Hungary; 16.12,45.44 23.57,48.95
-Iceland; -24.55,62.81 -12.79,67.01
-India; 66.79,6.58 99.01,36.96
-Indian Ocean; 22.3,-55.4 119.5,25.2
-Indonesia; 93.11,-12.65 143.45,7.88
-Iran; 43.31,24.08 64.42,40.73
-Iraq; 38.47,28.5 49.25,37.84
-Ireland; -10.52,51.23 -5.62,55.49
-Israel; 34.17,29.25 36.09,33.31
-Italy; 6.11,36.15 19.33,47.71
-Ivory Coast; -8.64,4.03 -2.01,10.96
-Jamaica; -78.22,17.72 -76,18.63
-Japan; 128.74,30.1 146.46,46.26
-Jordan; 34.97,28.87 39.75,33.44
-Kazakhstan; 44.73,38.62 89.65,57.49
-Kenya; 33,-5.3 42.44,5.07
-Democratic People's Republic of Korea; 124.02,43.29 37.55,130.95
-Republic of Korea; 125.95,38.76 33.06,129.88
-Kuwait; 46.62,28.34 48.74,30
-Kyrgyzstan; 69.01,38.7 81.03,43.77
-Laos; 99.77,13.47 108.1,22.98
-Latvia; 20.76,55.32 28.76,58.44
-Lebanon; 35.09,32.84 36.79,34.63
-Lesotho; 27.16,-30.89 29.76,-28.59
-Liberia; -11.47,4.16 -6.95,8.66
-Libya; 8.79,18.7 26.1,33.95
-Lithuania; 20.86,53.6 27.25,56.73
-Luxembourg; 5.9,49.42 6.77,50.21
-Macedonia; 20.62,40.62 23.27,42.48
-Madagascar; 42.83,-26.31 51.38,-11.58
-Malawi; 32.55,-17.51 36.46,-9.26
-Malaysia; 99.4,-0.2 120.19,7.86
-Mali; -12.77,9.25 5.27,25.83
-Mauritania; -17.47,14.21 -4.04,27.81
-Mexico; -118.48,13.05 -85.18,34.17
-Middle East; 25,10.7 59.7,36.1
-Moldova; 26.64,45.31 30.47,48.64
-Mongolia; 86.47,40 121.62,53.65
-Montenegro; 18.56,41.77 20.67,43.64
-Morocco; -13.52,26.96 -0.28,36.48
-Mozambique; 29.67,-27.82 41.89,-9.63
-Namibia; 11.32,-29.61 25.86,-16.31
-Nepal; 79.9,26 88.84,30.88
-Netherlands; 3.54,50.56 7.62,53.59
-New Hampshire; -72.68,42.57 -70.58,45.43
-New Jersey; -75.69,38.8 -73.78,41.47
-New Mexico; -109.35,31.04 -102.7,37.3
-New Zealand; 166.05,-47.31 179.41,-33.89
-Nicaragua; -87.7,10.55 -82.87,15.24
-Niger; -0.39,10.95 16.95,24.28
-Nigeria; 2.33,3.72 15.34,14.4
-North America; -168.5,18 -50.4,85.7
-North Atlantic Ocean; -82,0 12,80
-Northern Temperate; -180,23 180,60
-Norway; 3.88,56.69 32.56,81.95
-Oman; 51.53,16.19 60.52,26.73
-Pakistan; 60.18,22.94 78.66,37.86
-Panama; -83.06,6.9 -76.63,9.95
-Papua New Guinea; 140.37,-11.3 153.05,-2.2
-Paraguay; -62.83,-27.85 -53.6,-18.87
-Peru; -82.13,-19.35 -67.52,0.79
-Philippines; 116.68,4.85 127.23,19.22
-Poland; 13.77,48.57 24.85,55.24
-Portugal; -9.6,36.75 -5.65,42.36
-Qatar; 50.97,24.33 51.89,26.17
-Romania; 20.05,43.29 30.38,48.76
-Russia; 25,23.21 180,71
-Rwanda; 28.9,-3.01 31.2,-1.03
-Saudi Arabia; 33.9,14.01 57.3,33.22
-Senegal; -17.53,12.02 -10.89,17.14
-Serbia; 18.8,41.66 23.35,46.39
-Sierra Leone; -13.16,6.71 -10.02,10.09
-Slovakia; 16.84,47.61 23.06,49.93
-Slovenia; 13.39,45.28 16.87,47.06
-Somalia; 40.53,-2.55 52.14,12.66
-South Africa; 13.68,-35.9 33.98,-21.27
-South America; -84.9,-57.6 -32.4,13.7
-South Atlantic Ocean; -67,-55.4 23,0
-Southern Ocean; -180,-77 180,-32
-Southern Temperate; -180,-60 180,-23
-Spain; -9.69,35.4 3.98,44.38
-Sri Lanka; 79.69,5.76 82.26,9.89
-Sudan; 21.06,2.6 39.77,22.86
-Suriname; -58.01,1.53 -53.42,6.23
-Swaziland; 30.93,-27.52 32.45,-25.72
-Sweden; 10.56,54.63 24.84,69.68
-Switzerland; 5.92,45.66 10.84,48.02
-Syria; 35.36,31.84 43.11,37.69
-Taiwan; 119.99,21.78 122.14,25.31
-Tajikistan; 67.34,36.34 75.59,41.46
-Tanzania United Republic of; 0,-0.54 28.96,41.23
-Thailand; 96.83,4.8 106.42,21.22
-Togo; -0.09,5.85 2.21,11.33
-Trinidad; -61.88,10.01 -60.86,10.89
-Tropics; -180,-23 180,23
-Tunisia; 7.38,29.87 12.03,37.65
-Turkey; 25.29,34.91 45.94,43
-Turkmenistan; 52.05,34.56 67.66,43.46
-Uganda; 29.45,-1.82 35.52,4.32
-Ukraine; 21.4,43.61 41.24,53.31
-United Arab Emirates; 51.06,21.82 56.87,26.25
-United Kingdom; -8.41,49.49 2.39,59.07
-United States; -180,13.71 -61.48,76.63
-Uruguay; -58.46,-35.26 -52.77,-29.97
-Uzbekistan; 55.44,36.08 74.31,46.46
-Venezuela; -73.81,-0.11 -58.91,12.92
-Vietnam; 101.43,7.75 110.25,24.05
-Virginia; -84.1,36.12 -74.82,39.88
-Western Sahara; -17.23,20.87 -8.01,28
-Yemen; 42.45,12.12 53.74,19.51
-Zaire; 11.45,-14.4 32.4,6.28
-Zambia; 21.55,-18.7 34.45,-7.69
-Zimbabwe; 25.11,-22.93 33.65,15.22
From landa at grass.itc.it Sat Oct 20 12:58:27 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:47 2007
Subject: [grass-addons] r1150 - in trunk/grassaddons/gui: . gui_modules icons
Message-ID: <200710201058.l9KAwR2v026871@grass.itc.it>
Author: landa
Date: 2007-10-20 12:58:23 +0200 (Sat, 20 Oct 2007)
New Revision: 1150
Modified:
trunk/grassaddons/gui/README
trunk/grassaddons/gui/gui_modules/grassenv.py
trunk/grassaddons/gui/icons/icon.py
Log:
GRASS_ICONPATH must be given as GRASS variable.
Modified: trunk/grassaddons/gui/README
===================================================================
--- trunk/grassaddons/gui/README 2007-10-20 09:51:46 UTC (rev 1149)
+++ trunk/grassaddons/gui/README 2007-10-20 10:58:23 UTC (rev 1150)
@@ -125,10 +125,10 @@
* default (based on TCL/TK GUI prototype)
* Silk
-To enable 'Silk' icon theme set environment variable:
+To enable 'Silk' icon theme set GRASS variable:
-$ export GRASS_ICONPATH=$GISBASE/etc/wx/icons/silk
+$ g.gisenv set=GRASS_ICONPATH=$GISBASE/etc/wx/icons/silk
To re-enable default icons (TCL/TK theme)
-$ unset GRASS_ICONPATH
+$ g.gisenv set=GRASS_ICONPATH=
Modified: trunk/grassaddons/gui/gui_modules/grassenv.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-20 09:51:46 UTC (rev 1149)
+++ trunk/grassaddons/gui/gui_modules/grassenv.py 2007-10-20 10:58:23 UTC (rev 1150)
@@ -17,16 +17,29 @@
import os
import sys
-gmpath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
-sys.path.append(gmpath)
-import gcmd
+try:
+ import subprocess
+except:
+ CompatPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "compat")
+ sys.path.append(CompatPath)
+ import subprocess
+
+# gmpath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
+# sys.path.append(gmpath)
+# import gcmd
def GetGRASSVariable(var):
"""Return GRASS variable or '' if variable is not defined"""
- gisEnv = gcmd.Command(['g.gisenv'])
+ # gisEnv = gcmd.Command(['g.gisenv'])
- for item in gisEnv.ReadStdOutput():
+ gisEnv = subprocess.Popen(['g.gisenv'],
+ stdin=None,
+ stdout=subprocess.PIPE,
+ stderr=None,
+ close_fds=True)
+
+ for item in gisEnv.stdout.readlines():
if var in item:
return item.split('=')[1].replace("'",'').replace(';','').strip()
- return ''
+ return None
Modified: trunk/grassaddons/gui/icons/icon.py
===================================================================
--- trunk/grassaddons/gui/icons/icon.py 2007-10-20 09:51:46 UTC (rev 1149)
+++ trunk/grassaddons/gui/icons/icon.py 2007-10-20 10:58:23 UTC (rev 1150)
@@ -22,9 +22,16 @@
import wx
+gmPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
+sys.path.append(gmPath)
+import grassenv
+
+iconpath = grassenv.GetGRASSVariable('GRASS_ICONPATH')
+if not iconpath:
+ iconpath = os.getenv("GRASS_ICONPATH")
+
iconpath_default = os.path.join(os.getenv("GISBASE"), "etc", "gui", "icons")
iconpath_vdigit = os.path.join(os.getenv("GISBASE"), "etc", "v.digit")
-iconpath = os.getenv("GRASS_ICONPATH")
icons_default = {
# map display
From landa at grass.itc.it Sun Oct 21 00:16:51 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:47 2007
Subject: [grass-addons] r1151 - in trunk/grassaddons/gui: . gui_modules
Message-ID: <200710202216.l9KMGpcR032474@grass.itc.it>
Author: landa
Date: 2007-10-21 00:16:46 +0200 (Sun, 21 Oct 2007)
New Revision: 1151
Modified:
trunk/grassaddons/gui/gui_modules/debug.py
trunk/grassaddons/gui/gui_modules/gcmd.py
trunk/grassaddons/gui/gui_modules/toolbars.py
trunk/grassaddons/gui/gui_modules/wxgui_utils.py
trunk/grassaddons/gui/wxgui.py
Log:
Styled command output introduced (not fully functional, need to be fixed!)
Various minor fixes...
Modified: trunk/grassaddons/gui/gui_modules/debug.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/debug.py 2007-10-20 10:58:23 UTC (rev 1150)
+++ trunk/grassaddons/gui/gui_modules/debug.py 2007-10-20 22:16:46 UTC (rev 1151)
@@ -59,7 +59,7 @@
def msg (self, level, message):
self._update_level()
if self.debuglevel > 0 and level > 0 and level <= self.debuglevel:
- print "GUI D%d/%d: %s" % (level, level, message)
+ print >> sys.stderr, "GUI D%d/%d: %s" % (level, level, message)
# Debug instance
Debug = DebugMsg()
Modified: trunk/grassaddons/gui/gui_modules/gcmd.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-20 10:58:23 UTC (rev 1150)
+++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-20 22:16:46 UTC (rev 1151)
@@ -31,9 +31,11 @@
sys.path.append(CompatPath)
import subprocess
-# debugging ...
+# debugging & log window
GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules")
sys.path.append(GuiModulePath)
+
+import wxgui_utils
from debug import Debug as Debug
class EndOfCommand(Exception):
@@ -53,6 +55,7 @@
verbose - verbose mode [0; 3]
wait - wait for childer execution
dlgMsg - type of error message (None, gui, txt) [only if wait=True]
+ log - log window or None
Usage:
cmd = Command(cmd=['d.rast', 'elevation.dem'], verbose=True, wait=True)
@@ -66,7 +69,8 @@
"""
def __init__ (self, cmd, stdin=None,
- verbose=0, wait=True, dlgMsg='gui'):
+ verbose=0, wait=True, dlgMsg='gui',
+ stdout=None, stderr=None):
#
# input
#
@@ -81,7 +85,11 @@
self.cmd.append('--q')
elif verbose == 3 and '--v' not in self.cmd:
self.cmd.append('--v')
-
+ else:
+ verbosity = os.getenv("GRASS_VERBOSE")
+ os.environ["GRASS_VERBOSE"] = str(verbose)
+ if verbosity:
+ os.environ["GRASS_VERBOSE"] = verbosity
#
# GRASS module
#
@@ -97,7 +105,6 @@
#
message_format = os.getenv("GRASS_MESSAGE_FORMAT")
os.environ["GRASS_MESSAGE_FORMAT"] = "gui"
- # os.environ["GRASS_MESSAGE_FORMAT"] = "txt"
#
# run command ...
@@ -110,11 +117,25 @@
else: # Popen class (default)
Debug.msg(4, "Command.__init__(): [Popen] cmd='%s'" % ' '.join(cmd))
+ if stdout is None:
+ out = subprocess.PIPE
+ elif stdout == sys.stdout:
+ out = None
+ else:
+ out = stdout
+
+ if stderr is None:
+ err = subprocess.PIPE
+ elif stderr == sys.stderr:
+ err = None
+ else:
+ err = stderr
+
self.module = subprocess.Popen(self.cmd,
stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- close_fds=True)
+ stdout=out,
+ stderr=err,
+ close_fds=False)
# set up streams
self.module_stdin = self.module.stdin
self.module_stderr = self.module.stderr
@@ -124,20 +145,16 @@
self.module_stdin.write(stdin)
self.module_stdin.close()
- if message_format:
- os.environ["GRASS_MESSAGE_FORMAT"] = message_format
- else:
- os.unsetenv("GRASS_MESSAGE_FORMAT")
-
- # list of messages (<- stderr)
- # -> [(type, content)] type = (error, warning, message)
- self.module_msg = self.__ProcessStdErr() # -> self.module_msg
-
if self.module:
if wait:
self.module.wait()
+
+ if stderr is None:
+ # list of messages (<- stderr)
+ # -> [(type, content)] type = (error, warning, message)
+ self.module_msg = self.__ProcessStdErr() # -> self.module_msg
+
self.returncode = self.module.returncode
-
# failed?
if self.dlgMsg and self.returncode != 0:
if self.dlgMsg == 'gui': # GUI dialog
@@ -162,6 +179,11 @@
Debug.msg (3, "Command(): cmd='%s', wait=%d, returncode=?" % \
(' '.join(self.cmd), wait))
+ if message_format:
+ os.environ["GRASS_MESSAGE_FORMAT"] = message_format
+ else:
+ os.unsetenv("GRASS_MESSAGE_FORMAT")
+
def __ProcessStdErr(self):
"""
Read messages/warnings/errors from stderr
@@ -198,6 +220,10 @@
Note: Remove '\n' from output (TODO: '\r\n' ??)
"""
lineList = []
+
+ if stream is None:
+ return lineList
+
while True:
line = stream.readline()
if not line:
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-20 10:58:23 UTC (rev 1150)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-20 22:16:46 UTC (rev 1151)
@@ -595,8 +595,9 @@
self.combo.SetValue ('Select vector map')
# re-active layer
- # TODO: if status doesn't change in layer tree...
- self.mapcontent.ChangeLayerActive(layerSelected, True)
+ item = self.parent.tree.FindItemByData('maplayer', layerSelected)
+ if item and self.parent.tree.IsItemChecked(item):
+ self.mapcontent.ChangeLayerActive(layerSelected, True)
self.parent.digit.SetMapName(None)
Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-20 10:58:23 UTC (rev 1150)
+++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-10-20 22:16:46 UTC (rev 1151)
@@ -6,6 +6,9 @@
* Layer
* LayerTree
* GMConsole
+ * GMStdout
+ * GMStrerr
+ * GMStc
PURPOSE: Utility classes for GRASS wxPython GUI. Main functions include tree control
for GIS map layer management, command console, and command parsing.
@@ -22,11 +25,15 @@
"""
-import os,sys
+import os
+import sys
+import string
+import tempfile
+
import wx
import wx.lib.customtreectrl as CT
import wx.combo
-import string
+import wx.stc
gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","gui_modules" )
sys.path.append(gmpath)
@@ -346,7 +353,6 @@
Note: lcmd is given as a list
"""
self.first = True
- checked = False
params = {} # no initial options parameters
# deselect active item
@@ -360,7 +366,6 @@
ctrl = wx.TextCtrl(self, id=wx.ID_ANY, value='',
pos=wx.DefaultPosition, size=(250,25),
style=wx.TE_MULTILINE|wx.TE_WORDWRAP)
- checked = True
ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
ctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
elif ltype == 'group':
@@ -368,7 +373,6 @@
ctrl = None
grouptext = 'Layer group:' + str(self.groupnode)
self.groupnode += 1
- checked = True
else:
# all other items (raster, vector, ...)
ctrl = wx.SpinCtrl(self, id=wx.ID_ANY, value="", pos=(30, 50),
@@ -398,8 +402,11 @@
# layer is initially unchecked as inactive (beside 'command')
# use predefined value if given
- if lchecked:
+ if lchecked is not None:
checked = lchecked
+ else:
+ checked = True
+
self.CheckItem(layer, checked=checked)
# select new item
@@ -903,7 +910,7 @@
self.GetPyData(layer)[0]['propwin'] = propwin
# check layer as active
- self.CheckItem(layer, checked=True)
+ # self.CheckItem(layer, checked=True)
# change parameters for item in layers list in render.Map
self.ChangeLayer(layer)
@@ -976,8 +983,28 @@
def OnCloseWindow(self, event):
pass
- # self.Map.Clean()
+ # self.Map.Clean()
+ def FindItemByData(self, key, value):
+ """Find item based on key and value (see PyData[0])"""
+ item = self.GetFirstChild(self.root)[0]
+ return self.__FindSubItemByData(item, key, value)
+
+ def __FindSubItemByData(self, item, key, value):
+ """Support method for FindItemByValue"""
+ while item and item.IsOk():
+ itemValue = self.GetPyData(item)[0][key]
+ if value == itemValue:
+ return item
+ if self.GetPyData(item)[0]['type'] == 'group':
+ subItem = self.GetFirstChild(item)[0]
+ found = self.__FindSubItemByData(subItem, key, value)
+ if found:
+ return found
+ item = self.GetNextSibling(item)
+
+ return None
+
class GMConsole(wx.Panel):
"""
Create and manage output console for commands entered on the
@@ -998,10 +1025,15 @@
self.gcmdlst = [] # list of commands in bin and scripts
# text control for command output
- self.cmd_output = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="",
- style=wx.TE_MULTILINE| wx.TE_READONLY)
- self.cmd_output.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
+ # self.cmd_output = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="",
+ # style=wx.TE_MULTILINE| wx.TE_READONLY)
+ # self.cmd_output.SetFont(wx.Font(10, wx.FONTFAMILY_MODERN, wx.NORMAL, wx.NORMAL, 0, ''))
+ self.cmd_output = GMStc(parent=self, id=wx.ID_ANY)
+ # redirect
+ # sys.stdout = GMStdout(self.cmd_output)
+ # sys.stderr = GMStderr(self.cmd_output)
+
# buttons
self.console_clear = wx.Button(parent=self, id=wx.ID_CLEAR)
self.console_save = wx.Button(parent=self, id=wx.ID_SAVE)
@@ -1081,7 +1113,7 @@
if cmdlist[0] in gcmdlst:
# send GRASS command without arguments to GUI command interface
# except display commands (they are handled differently)
- if cmdlist[0][0:2] == "d.":
+ if cmdlist[0][0:2] == "d.": # display GRASS commands
try:
layertype = {'d.rast' : 'raster',
'd.rgb' : 'rgb',
@@ -1098,46 +1130,27 @@
'd.rhumbline' : 'rhumb',
'd.labels' : 'labels'}[cmdlist[0]]
except KeyError:
- print _('Command type not yet implemented')
+ wx.MessageBox(message=_("Command '%s' not yet implemented") % cmdlist[0])
return False
# add layer
self.parent.curr_page.maptree.AddLayer(ltype=layertype,
lcmd=cmdlist)
- else:
- if len(cmdlist) > 1:
- menuform.GUI().ParseCommand(cmdlist, parentframe=self, show=False)
- else:
- menuform.GUI().ParseCommand(cmdlist, parentframe=self, show=True)
-
- else:
- # Send any other command to the shell. Send output to
- # console output window.
-
- if self.parent.notebook.GetSelection() != 1:
- # select 'Command output' tab
- self.parent.notebook.SetSelection(1)
-
- self.cmd_output.write("$ " + ' '.join(cmdlist) + "\n")
-
- if cmdlist[0] not in gcmdlst:
- # if command is not a GRASS command, treat it like a shell command
- generalCmd = subprocess.Popen(cmdlist,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- close_fds=True)
+ else: # other GRASS commands
+ if self.parent.notebook.GetSelection() != 1:
+ # select 'Command output' tab
+ self.parent.notebook.SetSelection(1)
- for outline in runCmd.stdout:
- self.cmd_output.write(outline)
- else:
# activate compuational region (set with g.region) for all non-display commands.
tmpreg = os.getenv("GRASS_REGION")
os.unsetenv("GRASS_REGION")
# process GRASS command with argument
- grassCmd = gcmd.Command(cmdlist, verbose=3)
-
+ self.cmd_output.AddText('$ %s' % ' '.join(cmdlist))
+ grassCmd = gcmd.Command(cmdlist, verbose=3,
+ stdout=GMStdout(self.cmd_output),
+ stderr=GMStderr(self.cmd_output))
# deactivate computational region and return to display settings
if tmpreg:
@@ -1149,9 +1162,25 @@
# if oline.find("GRASS_INFO_PERCENT")>-1:
# self.console_progressbar.SetValue(int(oline.split()[1]))
- for line in grassCmd.ReadStdOutput():
- self.cmd_output.write(line + '\n')
-
+ else:
+ # Send any other command to the shell. Send output to
+ # console output window.
+
+ if self.parent.notebook.GetSelection() != 1:
+ # select 'Command output' tab
+ self.parent.notebook.SetSelection(1)
+
+ print "$ " + ' '.join(cmdlist)
+
+ # if command is not a GRASS command, treat it like a shell command
+ generalCmd = subprocess.Popen(cmdlist,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ close_fds=True)
+
+ for outline in generalCmd.stdout:
+ print outline
+
return True
def ClearHistory(self, event):
@@ -1183,3 +1212,119 @@
output.close()
dlg.Destroy()
+
+class GMStdout:
+ """GMConsole standard output
+
+ Based on FrameOutErr.py
+
+ Name: FrameOutErr.py
+ Purpose: Redirecting stdout / stderr
+ Author: Jean-Michel Fauth, Switzerland
+ Copyright: (c) 2005-2007 Jean-Michel Fauth
+ Licence: GPL
+ """
+ def __init__(self, gmstc):
+ self.gmstc = gmstc
+ self.buffer = tempfile.TemporaryFile(mode="w")
+
+ def write(self, s):
+ # if not self.gmstc.GetParent().IsShown():
+ # self.mystc.GetParent().Show()
+
+ s = s.replace('\n', os.linesep)
+ p1 = self.gmstc.GetCurrentPos() # get caret position
+ self.gmstc.AddText(s)
+ self.gmstc.EnsureCaretVisible()
+ p2 = self.gmstc.GetCurrentPos()
+ self.gmstc.StartStyling(p1, 0xff)
+ self.gmstc.SetStyling(p2 - p1 + 1, self.gmstc.StyleOutput)
+
+ def fileno(self):
+ return self.buffer.fileno()
+
+ def __del__(self):
+ self.buffer.flush()
+ self.buffer.seek(0,0)
+ for line in self.buffer.readlines():
+ self.write(line)
+
+class GMStderr:
+ """GMConsole standard error output
+
+ Based on FrameOutErr.py
+
+ Name: FrameOutErr.py
+ Purpose: Redirecting stdout / stderr
+ Author: Jean-Michel Fauth, Switzerland
+ Copyright: (c) 2005-2007 Jean-Michel Fauth
+ Licence: GPL
+ """
+ def __init__(self, gmstc):
+ self.gmstc = gmstc
+ self.buffer = tempfile.TemporaryFile(mode="w")
+
+ def write(self, s):
+ # if self.gmstc.GetParent().IsShown() == False:
+ # self.gmstc.GetParent().Show()
+
+ s = s.replace('\n', os.linesep)
+ p1 = self.gmstc.GetCurrentPos()
+ self.gmstc.AddText(s)
+ self.gmstc.EnsureCaretVisible()
+ p2 = self.gmstc.GetCurrentPos()
+ self.gmstc.SetStyling(p2 - p1 + 1, self.gmstc.StyleError)
+
+ def fileno(self):
+ return self.buffer.fileno()
+
+ def __del__(self):
+ self.buffer.flush()
+ self.buffer.seek(0,0)
+ for line in self.buffer.readlines():
+ self.write(line)
+
+class GMStc(wx.stc.StyledTextCtrl):
+ """Styled GMConsole
+
+ Based on FrameOutErr.py
+
+ Name: FrameOutErr.py
+ Purpose: Redirecting stdout / stderr
+ Author: Jean-Michel Fauth, Switzerland
+ Copyright: (c) 2005-2007 Jean-Michel Fauth
+ Licence: GPL
+ """
+ def __init__(self, parent, id):
+ wx.stc.StyledTextCtrl.__init__(self, parent, id)
+ self.parent = parent
+
+ # styles
+ self.StyleDefault = 0
+ self.StyleDefaultSpec = "face:Courier New,size:10,fore:#000000,back:#FFFFFF"
+ self.StyleOutput = 1
+ self.StyleOutputSpec = "face:Courier New,size:10,fore:#0000FF,back:#FFFFFF"
+ self.StyleError = 2
+ self.StyleErrorSpec = "face:Courier New,size:10,fore:#7F0000,back:#FFFFFF"
+
+ # default and clear => init
+ self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, self.StyleDefaultSpec)
+ self.StyleClearAll()
+ self.StyleSetSpec(self.StyleOutput, self.StyleOutputSpec)
+ self.StyleSetSpec(self.StyleError, self.StyleErrorSpec)
+
+ # margin widths
+ self.SetMarginWidth(0, 0)
+ self.SetMarginWidth(1, 0)
+ self.SetMarginWidth(2, 0)
+
+ # miscellaneous, a few parameters
+ self.SetMarginLeft(2)
+ self.SetViewWhiteSpace(True)
+ self.SetTabWidth(4)
+ self.SetUseTabs(False)
+ #~ self.SetEOLMode(wx.stc.STC_EOL_CRLF)
+ #~ self.SetViewEOL(True)
+ self.UsePopUp(True)
+ self.SetSelBackground(True, "#FFFF00")
+ self.SetUseHorizontalScrollBar(True)
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-20 10:58:23 UTC (rev 1150)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-20 22:16:46 UTC (rev 1151)
@@ -450,7 +450,7 @@
filename = ''
if dlg.ShowModal() == wx.ID_OK:
- filename = dlg.GetFilename()
+ filename = dlg.GetPath()
if filename == '':
return
@@ -537,7 +537,7 @@
filename = ''
if dlg.ShowModal() == wx.ID_OK:
- filename = dlg.GetFilename()
+ filename = dlg.GetPath()
if filename == '':
return False
From neteler at grass.itc.it Sun Oct 21 10:39:00 2007
From: neteler at grass.itc.it (neteler@grass.itc.it)
Date: Thu Oct 25 01:43:47 2007
Subject: [grass-addons] r1152 - in trunk/grassaddons: . i.points.auto
i.points.auto/orig
Message-ID: <200710210839.l9L8d0LK031452@grass.itc.it>
Author: neteler
Date: 2007-10-21 10:38:25 +0200 (Sun, 21 Oct 2007)
New Revision: 1152
Added:
trunk/grassaddons/i.points.auto/
trunk/grassaddons/i.points.auto/Makefile
trunk/grassaddons/i.points.auto/TODO
trunk/grassaddons/i.points.auto/analyze.c
trunk/grassaddons/i.points.auto/ask.c
trunk/grassaddons/i.points.auto/ask_mag.c
trunk/grassaddons/i.points.auto/call.c
trunk/grassaddons/i.points.auto/cell.c
trunk/grassaddons/i.points.auto/cellhd.c
trunk/grassaddons/i.points.auto/colors.c
trunk/grassaddons/i.points.auto/conv.c
trunk/grassaddons/i.points.auto/curses.c
trunk/grassaddons/i.points.auto/debug.c
trunk/grassaddons/i.points.auto/defs.h
trunk/grassaddons/i.points.auto/description.html
trunk/grassaddons/i.points.auto/digit.c
trunk/grassaddons/i.points.auto/dot.c
trunk/grassaddons/i.points.auto/drawcell.c
trunk/grassaddons/i.points.auto/driver.c
trunk/grassaddons/i.points.auto/equ.c
trunk/grassaddons/i.points.auto/find.c
trunk/grassaddons/i.points.auto/find_points.c
trunk/grassaddons/i.points.auto/find_points_semi.c
trunk/grassaddons/i.points.auto/georef.c
trunk/grassaddons/i.points.auto/globals.h
trunk/grassaddons/i.points.auto/graphics.c
trunk/grassaddons/i.points.auto/group.c
trunk/grassaddons/i.points.auto/input.c
trunk/grassaddons/i.points.auto/line.c
trunk/grassaddons/i.points.auto/local_proto.h
trunk/grassaddons/i.points.auto/main.c
trunk/grassaddons/i.points.auto/mark.c
trunk/grassaddons/i.points.auto/mouse.c
trunk/grassaddons/i.points.auto/orig/
trunk/grassaddons/i.points.auto/orig/find_points_semi.c.org
trunk/grassaddons/i.points.auto/orig/globals.h.org
trunk/grassaddons/i.points.auto/overlap_area.c
trunk/grassaddons/i.points.auto/points.c
trunk/grassaddons/i.points.auto/target.c
trunk/grassaddons/i.points.auto/title.c
trunk/grassaddons/i.points.auto/view.c
trunk/grassaddons/i.points.auto/where.c
trunk/grassaddons/i.points.auto/zoom.c
trunk/grassaddons/i.points.auto/zoom_box.c
trunk/grassaddons/i.points.auto/zoom_pnt.c
Log:
new module for semi-automated image registration based on FFT correlation
Added: trunk/grassaddons/i.points.auto/Makefile
===================================================================
--- trunk/grassaddons/i.points.auto/Makefile (rev 0)
+++ trunk/grassaddons/i.points.auto/Makefile 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = i.points.auto
+
+LIBES = $(IMAGERYLIB) $(GMATHLIB) $(D_LIB) $(DISPLAYLIB) $(RASTERLIB) $(GISLIB) $(VASKLIB) $(CURSES) $(FFTWLIB)
+DEPENDENCIES= $(IMAGERYDEP) $(GMATHDEP) $(D_DEP) $(DISPLAYDEP) $(RASTERDEP) $(GISDEP) $(VASKDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Property changes on: trunk/grassaddons/i.points.auto/Makefile
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/TODO
===================================================================
--- trunk/grassaddons/i.points.auto/TODO (rev 0)
+++ trunk/grassaddons/i.points.auto/TODO 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,5 @@
+Compile with
+ make MODULE_TOPDIR=$HOME/grass63/
+
+This code is basically an improved i.points (from 2004).
+Further changes in i.points haven's been ported here yet.
Added: trunk/grassaddons/i.points.auto/analyze.c
===================================================================
--- trunk/grassaddons/i.points.auto/analyze.c (rev 0)
+++ trunk/grassaddons/i.points.auto/analyze.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,935 @@
+#include
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+#define NLINES 18
+struct box
+{
+ int top, bottom, left,right;
+};
+
+static int uparrow ( struct box *,int);
+static int downarrow ( struct box *,int) ;
+static int pick(int,int);
+static int done(void);
+static int cancel_which(void);
+static int inbox (struct box *,int,int);
+static int dotext (char *,int,int,int,int,int,int);
+static int compute_transformation(void);
+static int to_file(void);
+static int askfile(void);
+static int to_printer(void);
+static int do_report ( FILE *);
+static int printcentered(FILE *,char *,int);
+static int show_point(int,int);
+static int offsetx, offsety;
+static int n_old;
+static int which;
+static struct box more, less, report,box_lines, box_points;
+static int height, size, edge, nlines;
+static int curp, first_point;
+static double rms,l_rms;
+static double *xres, *yres, *gnd, *tres, *ures, *lgnd;
+static int pager;
+static int xmax, ymax, gmax;
+static int tmax, umax, lgmax;
+static char buf[300];
+int new_control_line (Lines *ln,double t1,double u1,double t2,double u2,int status);
+Lines lines; /* contiene t ed u delle rette inserite */
+int use_points=1;
+int top, bottom, left, right, width, middle, nums;
+int count =0, first_line=0;
+#define FMT0(buf,n) \
+ sprintf (buf, "%3d ", n)
+#define FMT1(buf,xres,yres,gnd) \
+ sprintf (buf, "%5.1f %5.1f %6.1f ", xres,yres,gnd)
+#define LHEAD1 " error "
+#define LHEAD2 " # col row target"
+#define LLINEHEAD2 " # dt du target"
+
+#define FMT2(buf,e1,n1,e2,n2) \
+ sprintf (buf, "%9.1f %9.1f %9.1f %9.1f ", e1,n1,e2,n2)
+#define RHEAD1 " image target"
+#define RHEAD2 " east north east north"
+#define RLINEHEAD2 " t1 u1 t2 u2 "
+
+#define BACKGROUND WHITE
+
+int
+analyze (void)
+{
+
+ double t_temp1,u_temp1, t_temp2, u_temp2;
+
+ static int use = 1;
+
+ static Objects objects[]=
+ {
+ MENU(" DONE ", done, &use),
+ MENU(" PRINT ", to_printer, &use),
+ MENU(" FILE ", to_file, &use),
+ INFO(" Double click on point to be included/excluded ", &use),
+ OTHER(pick,&use),
+ {0}
+ };
+
+ int color;
+ int tsize;
+ int cury;
+ int len;
+ int line;
+ int i;
+/* to give user a response of some sort */
+ if (group.points.count ==0)
+ return 0;
+
+
+ Menu_msg ("Preparing analysis ...");
+
+/*
+ * build a popup window at center of the screen.
+ * 35% the height and wide enough to hold the report
+ *
+ */
+
+ /* height of 1 line, based on NLINES taking up 35% vertical space */
+ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP))/NLINES + 1;
+ use_points=1;
+/* size of text, 80% of line height */
+ tsize = .8 * height;
+ size = tsize-2; /* fudge for computing pixels width of text */
+
+/* indent for the text */
+ edge = .1 * height + 1;
+
+/* determine the length, in chars, of printed line */
+ FMT0 (buf,0);
+ nums = strlen(buf) * size;
+ FMT1 (buf, 0.0, 0.0, 0.0);
+ len = strlen(buf);
+ middle = len * size;
+ FMT2 (buf, 0.0, 0.0, 0.0, 0.0);
+ len += strlen(buf) ;
+
+/* width is for max chars plus sidecar for more/less */
+ R_standard_color (WHITE);
+ width = len * size + nums + 2*height;
+ if ((SCREEN_RIGHT - SCREEN_LEFT) < width)
+ width = SCREEN_RIGHT - SCREEN_LEFT;
+
+
+/* define the window */
+
+ //bottom = VIEW_MENU->top-1;
+ //top = bottom - height*NLINES;
+
+ bottom = height*NLINES;
+ top = 0;
+
+
+ left = SCREEN_LEFT;
+ right = left + width;
+ middle += left + nums;
+ nums += left;
+
+/* save what is under this area, so it can be restored */
+ R_panel_save (tempfile1, top, bottom, left, right);
+
+
+/* fill it with white */
+ R_standard_color (WHITE);
+ R_box_abs (left, top, right, bottom);
+
+ right -= 2*height; /* reduce it to exclude sidecar */
+
+/* print messages in message area */
+ R_text_size (tsize, tsize);
+
+
+/* setup the more/less boxes in the sidecar */
+ R_standard_color (BLUE);
+ less.top = top;
+ less.bottom = top + 2*height;
+ less.left = right;
+ less.right = right + 2*height;
+ Outline_box (less.top, less.bottom, less.left, less.right);
+
+ more.top = bottom - 2*height;
+ more.bottom = bottom;
+ more.left = right;
+ more.right = right + 2*height;
+ Outline_box (more.top, more.bottom, more.left, more.right);
+
+/*
+ * top two lines are for column labels
+ * last two line is for overall rms error.
+ */
+ nlines = NLINES - 4;
+ first_point = 0;
+
+/* allocate predicted values */
+ xres = (double *) G_calloc (group.points.count, sizeof (double));
+ yres = (double *) G_calloc (group.points.count, sizeof (double));
+ gnd = (double *) G_calloc (group.points.count, sizeof (double));
+
+
+ i=0;
+ while(group.points.status[i]!=1 && i < group.points.count)
+ i++;
+ if(i >=group.points.count && group.points.status[i]!=1)
+ i=0;
+offsetx = group.points.e2[i] - group.points.e1[i];
+offsety = group.points.n2[i] - group.points.n1[i];
+
+
+lines.count=0;
+ for (i=0; i < group.points.count; i++)
+ {
+ if (group.points.status[i] == 2 || group.points.status[i] == -2)
+ {
+ points_to_line (group.points.e1[i], group.points.n1[i],group.points.e1[i+1], group.points.n1[i+1],&t_temp1,&u_temp1);
+ points_to_line (group.points.e2[i]- offsetx, group.points.n2[i]-offsety,group.points.e2[i+1]-offsetx, group.points.n2[i+1]-offsety,&t_temp2,&u_temp2);
+
+ sprintf (buf, "t2[0] e u2[0].... %f %f \n",10000*t_temp2,10000*u_temp2 );
+ Curses_write_window (INFO_WINDOW, 3+ i, 2, buf);
+
+
+ new_control_line ( &lines,10000*t_temp1,10000*u_temp1,10000*t_temp2,10000*u_temp2,group.points.status[i]);
+ }
+ }
+
+ tres = (double *) G_calloc (lines.count, sizeof (double));
+ ures = (double *) G_calloc (lines.count, sizeof (double));
+ lgnd = (double *) G_calloc (lines.count, sizeof (double));
+
+ /* compute transformation for the first time */
+ compute_transformation();
+
+
+ /* put head on the report */
+
+ box_points.top=top;
+ box_points.bottom=top+height-1;
+ box_points.left= left;
+ box_points.right=(right-left)/2;
+ dotext (" ANALYZE -> POINTS",top, top+height, left, (right-left)/2, 0, RED);
+ Outline_box (box_points.top, box_points.bottom, box_points.left, box_points.right);
+
+ box_lines.top=top;
+ box_lines.bottom=top+height-1;
+ box_lines.left= ((right- left)/2)+1;
+ box_lines.right=right;
+ dotext (" ANALYZE -> LINES",top, top+height, ((right-left)/2)+1, right, 0, BLACK);
+ Outline_box (box_lines.top, box_lines.bottom, box_lines.left, box_lines.right);
+
+ cury=top;
+ cury = top+height;
+ dotext (LHEAD1, cury, cury+height, left, middle, 0, BLACK);
+ dotext (RHEAD1, cury, cury+height, middle, right-1, 0, BLACK);
+ cury += height;
+ dotext (LHEAD2, cury, cury+height, left, middle, 0, BLACK);
+ dotext (RHEAD2, cury, cury+height, middle, right-1, 0, BLACK);
+
+ cury += height;
+ R_move_abs (left, cury-1);
+ R_cont_abs (right, cury-1);
+
+/* isolate the sidecar */
+ R_standard_color (BLACK);
+ R_move_abs (right, top);
+ R_cont_abs (right, bottom);
+
+/* define report box */
+ report.top = cury;
+ report.left = left;
+ report.right = right;
+ count = 0;
+ first_line = 0;
+
+/* lets do it */
+ pager = 1;
+ while(1)
+ {
+ R_text_size (tsize, tsize);
+ line = 0;
+ curp = first_point;
+ cury = top + 3*height;
+ count=0;
+ while(1)
+ {
+ if (line >= nlines || curp >= group.points.count)
+ break;
+ if(group.equation_stat > 0 && group.points.status[curp]==1)
+ {
+ if(use_points)
+ {
+ color = BLUE;
+ FMT1(buf, xres[curp], yres[curp], gnd[curp]);
+ if (curp == xmax || curp == ymax || curp == gmax)
+ color = RED;
+ dotext (buf, cury, cury+height, nums, middle, 0, color);
+ line++;
+ cury += height;
+ }
+ }
+ else if(group.points.status[curp] ==2)
+ {
+ /* if(group.points.status[curp+1]!=3)
+ break;*/
+ if(!use_points)
+ {
+ color = BLUE;
+ if (count+first_line == tmax || count+first_line == umax || count+first_line == lgmax)
+ color = RED;
+ sprintf (buf, "%5.1f %5.1f %5.1f ", tres[count+ first_line],ures[count+first_line],lgnd[count+first_line]);
+ dotext (buf, cury, cury+height, nums, middle, 0, color);
+ line++;
+ cury += height;
+ }
+
+ curp++;
+ }
+ else if (group.points.status[curp] > 0)
+ {
+ FMT0 (buf, curp+1-count);
+ dotext (buf, cury, cury+height, left, nums, 0, BLACK);
+ FMT2(buf,
+ group.points.e1[curp],
+ group.points.n1[curp],
+ group.points.e2[curp],
+ group.points.n2[curp]);
+ dotext (buf, cury, cury+height, middle, right-1, 0, BLACK);
+ dotext ("?", cury, cury+height, nums, middle, 1, BLACK);
+ line++;
+ cury += height;
+ }
+
+ else if (group.points.status[curp] == -2 )
+ {
+ if(group.points.status[curp+1]!=-3)
+ break;
+ if (!use_points)
+ {
+ dotext ("not used", cury, cury+height, nums, middle, 1, BLUE);
+ line++;
+ cury += height;
+ }
+ curp++;
+ }
+ else if (use_points)
+ {
+ dotext ("not used", cury, cury+height, nums, middle, 1, BLACK);
+ line++;
+ cury += height;
+ }
+ if (pager)
+ {
+ if(use_points &&( group.points.status[curp]==1 || group.points.status[curp]==0))
+ {
+
+ FMT0 (buf, curp+1-2*(first_line+count));
+ dotext (buf, cury-height, cury, left, nums, 0, BLACK);
+ FMT2(buf,
+ group.points.e1[curp],
+ group.points.n1[curp],
+ group.points.e2[curp],
+ group.points.n2[curp]);
+ dotext (buf, cury-height, cury, middle, right-1, 0, BLACK);
+ }
+ if(!use_points &&( group.points.status[curp]>1 || group.points.status[curp]<-1))
+ {
+ FMT0 (buf, first_line + count);
+ dotext (buf, cury-height, cury, left, nums, 0, BLACK);
+ sprintf (buf, "%9.1f %9.1f %9.1f %9.1f ",
+ lines.t1[first_line+count],
+ lines.u1[first_line+count],
+ lines.t2[first_line+count],
+ lines.u2[first_line+count]);
+ dotext (buf, cury-height, cury, middle, right-1, 0, BLACK);
+
+ }
+ }
+ if( group.points.status[curp]>1 || group.points.status[curp]<-1)
+ count++;
+ curp++;
+ }
+ report.bottom = cury;
+ if(use_points)
+ {
+ downarrow (&more, ((group.points.count-curp)-2*(lines.count-(count+first_line)))>0 ? BLACK : BACKGROUND);
+ uparrow (&less, first_point > 0 ? BLACK : BACKGROUND);
+ }
+ if(!use_points)
+ {
+ downarrow (&more, (lines.count-(count+first_line))>0 ? BLACK : BACKGROUND);
+ uparrow (&less, first_point > 0 ? BLACK : BACKGROUND);
+ }
+
+ R_standard_color (BACKGROUND);
+ R_box_abs (left, cury, right-1, bottom);
+ if(use_points) {
+ if (group.equation_stat < 0)
+ {
+ color = RED;
+ strcpy (buf, "Poorly placed control points");
+ }
+ else if (group.equation_stat == 0)
+ {
+ color = RED;
+ strcpy (buf, "No active control points");
+ }
+ else
+ {
+ color = BLACK;
+ sprintf (buf, "Overall rms error: %.2f", rms);
+ }
+ }
+ else
+ {
+ if (lines.line_stat < 0)
+ {
+ color = RED;
+ strcpy (buf, "Poorly placed control points");
+ }
+ else if (lines.line_stat == 0)
+ {
+ color = RED;
+ strcpy (buf, "No active control points");
+ }
+ else
+ {
+ color = BLACK;
+ sprintf (buf, "Overall rms error: %.2f", l_rms);
+ }
+ }
+ dotext (buf, bottom-height, bottom, left, right-1, 0, color);
+ R_standard_color (BLACK);
+ R_move_abs (left, bottom-height);
+ R_cont_abs (right-1, bottom-height);
+
+ pager = 0;
+ which = -1;
+ if(Input_pointer(objects) < 0)
+ break;
+
+
+
+ }
+
+ /* all done. restore what was under the window */
+ right += 2*height; /* move it back over the sidecar */
+ R_standard_color (BACKGROUND);
+ R_box_abs (left, top, right, bottom);
+ R_panel_restore (tempfile1);
+ R_panel_delete (tempfile1);
+ R_flush();
+
+ free (xres); free (yres); free (gnd);
+ I_put_control_points (group.name, &group.points);
+ display_points(1);
+ return 0; /* return but don't QUIT */
+}
+
+
+static int uparrow (struct box *box, int color)
+{
+ R_standard_color (BLACK);
+ Uparrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge);
+
+ return 0;
+}
+
+static int downarrow(struct box *box, int color)
+{
+ R_standard_color (BLACK);
+ Downarrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge);
+
+ return 0;
+}
+
+static int pick(int x,int y)
+{
+ int n;
+ int cur;
+ int i;
+
+ cur = which;
+ cancel_which();
+ if (inbox(&more,x,y))
+ {
+ if (use_points && ((group.points.count-curp)-2*(lines.count-(count+first_line)))<=0)
+ return 0;
+ if(!use_points && (lines.count-(count+first_line))<=0)
+ return 0;
+ first_point = curp;
+ first_line +=count;
+ pager = 1;
+ return 1;
+ }
+ if (inbox(&box_points,x,y))
+ {
+ R_text_size (.8*height, .8*height);
+ use_points=1;
+ dotext (" ANALYZE -> POINTS",top, top+height, left, (right-left)/2, 0, RED);
+ dotext (" ANALYZE -> LINES",top, top+height,((right-left)/2)+1, right, 0, BLACK);
+ Outline_box (box_points.top, box_points.bottom, box_points.left, box_points.right);
+ Outline_box (box_lines.top, box_lines.bottom, box_lines.left, box_lines.right);
+ dotext (LHEAD2, top+2*height, top+3*height, left, middle, 0, BLACK);
+ dotext (RHEAD2, top+2*height, top+3*height, middle, right-1, 0, BLACK);
+ first_point = 0;
+ first_line = 0;
+ pager = 1;
+ return 1;
+ }
+ if (inbox(&box_lines,x,y))
+ {
+ R_text_size (.8*height, .8*height);
+ use_points=0;
+ dotext (" ANALYZE -> LINES",top, top+height, ((right-left)/2)+1, right, 0, RED);
+ dotext (" ANALYZE -> POINTS",top, top+height, left, (right-left)/2, 0, BLACK);
+ Outline_box (box_points.top, box_points.bottom, box_points.left, box_points.right);
+ Outline_box (box_lines.top, box_lines.bottom, box_lines.left, box_lines.right);
+ dotext (LLINEHEAD2, top+2*height, top+3*height, left, middle, 0, BLACK);
+ dotext (RLINEHEAD2, top+2*height, top+3*height, middle, right-1, 0, BLACK);
+ first_point = 0;
+ first_line = 0;
+ pager = 1;
+ return 1;
+ }
+ if (inbox(&less,x,y))
+ {
+ if (first_point == 0)
+ return 0;
+ first_point = 0;
+ first_line = 0;
+ pager = 1;
+ return 1;
+ }
+ if (!inbox (&report,x,y))
+ {
+ return 0;
+ }
+
+ n_old = n = (y - report.top)/height;
+ i=0;
+ if(use_points){
+ for (i; i<=n; i++)
+ if (group.points.status[first_point + i]==2||group.points.status[first_point + i]==-2) n+=2;
+ }
+ else { while (n>=0) {
+ if (group.points.status[first_point + i]==2||group.points.status[first_point + i]==-2) {
+ n--;
+ i++;
+ }
+ i++;
+ }
+ n=i-2;
+ }
+ if (n == cur) /* second click! */
+ {
+ if (group.points.status[first_point +n]==2||group.points.status[first_point +n]==-2) {
+ group.points.status[first_point+n] = -group.points.status[first_point+n];
+ group.points.status[first_point+(n+1)] = -group.points.status[first_point+(n+1)];
+ lines.status[first_line + n_old] = - lines.status[first_line + n_old];
+ }
+
+ else
+ group.points.status[first_point+n] = !group.points.status[first_point+n];
+ compute_transformation();
+ show_point (first_point+n, 1);
+
+
+ return 1;
+ }
+ which = n;
+ show_point (first_point+n, 0);
+ R_standard_color (RED);
+ Outline_box (report.top + n*height, report.top +(n+1)*height,
+ report.left, report.right-1);
+ return 0; /* ignore first click */
+
+}
+
+static int done (void)
+{
+ cancel_which();
+ return -1;
+}
+
+static int cancel_which (void)
+{
+ if (which >= 0)
+ {
+ R_standard_color (BACKGROUND);
+ Outline_box (report.top + which*height, report.top +(which+1)*height,
+ report.left, report.right-1);
+ show_point (first_point+which, 1);
+ }
+ which = -1;
+
+ return 0;
+}
+
+static int inbox (struct box *box,int x,int y)
+{
+ return (x>box->left && x right && y>box->top && ybottom);
+}
+
+static int dotext (char *text,
+ int top,int bottom,int left,int right,int centered,int color)
+{
+ R_standard_color (BACKGROUND);
+ R_box_abs (left, top, right, bottom);
+ R_standard_color (color);
+ R_move_abs (left+1+edge, bottom-1-edge);
+ if (centered)
+ R_move_rel ((right-left-strlen(text)*size)/2,0);
+ R_set_window (top, bottom, left, right); /* for text clipping */
+ R_text (text);
+ R_set_window (SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT);
+
+ return 0;
+}
+
+static int compute_transformation (void)
+{
+ int n, count;
+ double d,d1,d2,sum;
+ double e1, e2, n1, n2;
+ double t1, t2, u1, u2;
+ double xval, yval, gval;
+ double tval, uval, lgval;
+
+ xmax = ymax = gmax = 0;
+ xval = yval = gval = 0.0;
+
+ Compute_equation(); /*trova gli A,B,C che legano punti dell'image a punti del ltarget */
+ lines.line_stat = compute_georef_equations_lp(&lines);
+
+ if (group.equation_stat <= 0 && lines.line_stat<=0) return 1;
+
+/* compute the row,col error plus ground error
+ * keep track of largest and second largest error
+ */
+ sum = 0.0;
+ rms = 0.0;
+ count = 0;
+ for (n = 0; n < group.points.count && group.equation_stat>0; n++)
+ {
+ if (group.points.status[n] !=1) continue;
+ count++;
+ georef (group.points.e2[n], group.points.n2[n], &e1, &n1, group.E21, group.N21);
+ georef (group.points.e1[n], group.points.n1[n], &e2, &n2, group.E12, group.N12);
+
+ if((d = xres[n] = e1-group.points.e1[n]) < 0)
+ d = -d;
+ if (d > xval)
+ {
+ xmax = n;
+ xval = d;
+ }
+
+ if ((d = yres[n] = n1-group.points.n1[n]) < 0)
+ d = -d;
+ if (d > yval)
+ {
+ ymax = n;
+ yval = d;
+ }
+
+/* compute ground error (ie along diagonal) */
+ d1 = e2 - group.points.e2[n];
+ d2 = n2 - group.points.n2[n];
+ d = d1*d1 + d2*d2;
+ sum += d; /* add it to rms sum, before taking sqrt */
+ d = sqrt(d);
+ gnd[n] = d;
+ if (d > gval) /* is this one the max? */
+ {
+ gmax = n;
+ gval = d;
+ }
+
+ }
+/* compute overall rms error */
+ if (count)
+ rms = sqrt (sum/count);
+
+ count =0;
+ tmax = umax = lgmax = 0;
+ tval = uval = lgval = 0.0;
+ sum = 0.0;
+ l_rms = 0.0;
+ for (n = 0; n < lines.count && lines.line_stat>0 ; n++)
+ {
+ if (lines.status[n] !=2) continue;
+ count++;
+ georef (lines.t2[n], lines.u2[n], &t1, &u1, lines.E21, lines.N21);
+ georef (lines.t1[n], lines.u1[n], &t2, &u2, lines.E12, lines.N12);
+ if((d = tres[n] = t1- lines.t1[n]) < 0)
+ d = -d;
+ if (d > tval)
+ {
+ tmax = n;
+ tval = d;
+ }
+
+ if ((d = ures[n] = u1- lines.u1[n]) < 0)
+ d = -d;
+ if (d > uval)
+ {
+ umax = n;
+ uval = d;
+ }
+
+/* compute ground error (ie along diagonal) */
+ d1 = t2 - lines.t2[n];
+ d2 = u2 - lines.u2[n];
+ d = d1*d1 + d2*d2;
+ sum += d; /* add it to rms sum, before taking sqrt */
+ d = sqrt(d);
+ lgnd[n] = d;
+ if (d > lgval) /* is this one the max? */
+ {
+ lgmax = n;
+ lgval = d;
+ }
+
+ }
+ if (count)
+ l_rms = sqrt (sum/count);
+
+
+
+ return 0;
+}
+
+static int to_file (void)
+{
+ FILE *fd;
+ char msg[1024];
+
+ cancel_which();
+ if (Input_other (askfile, "Keyboard") < 0)
+ {
+ return 0;
+ }
+
+ fd = fopen (buf, "w");
+ if (fd == NULL)
+ {
+ sprintf (msg, "** Unable to create file %s\n", buf);
+ Beep();
+ Curses_write_window (PROMPT_WINDOW, 2, 1, msg);
+ }
+ else
+ {
+ do_report (fd);
+ fclose (fd);
+ sprintf (msg, "Report saved in file %s\n", buf);
+ Curses_write_window (PROMPT_WINDOW, 2, 1, msg);
+ }
+ return 0;
+}
+
+static int askfile (void)
+{
+ char file[100];
+
+ while (1)
+ {
+ Curses_prompt_gets ("Enter file to hold report: ", file);
+ G_strip (file);
+ if (*file == 0) return -1;
+ if (G_index (file, '/'))
+ strcpy (buf, file);
+ else
+ sprintf (buf, "%s/%s", G_home(), file);
+ if (access (buf, 0) != 0)
+ return 1;
+ sprintf (buf, "** %s already exists. choose another file", file);
+ Beep();
+ Curses_write_window (PROMPT_WINDOW, 2, 1, buf);
+ }
+
+ return 0;
+}
+
+static int to_printer (void)
+{
+ FILE *fd;
+ cancel_which();
+ Menu_msg ("sending report to printer ...");
+
+ fd = popen ("lpr", "w");
+ do_report (fd);
+ pclose (fd);
+ return 0;
+}
+
+static int do_report ( FILE *fd)
+{
+ char buf[100];
+ int n;
+ int width;
+
+ fprintf (fd, "LOCATION: %-20s GROUP: %-20s MAPSET: %s\n\n",
+ G_location(), group.name, G_mapset());
+ fprintf (fd, "%15sAnalysis of control point registration\n\n", "");
+ fprintf (fd, "%s %s\n", LHEAD1, RHEAD1);
+ fprintf (fd, "%s %s\n", LHEAD2, RHEAD2);
+
+ FMT1 (buf,0.0,0.0,0.0);
+ width = strlen (buf);
+
+ for (n = 0; n < group.points.count; n++)
+ {
+ FMT0(buf,n+1);
+ fprintf (fd, "%s", buf);
+ if(group.equation_stat > 0 && group.points.status[n] > 0)
+ {
+ FMT1(buf, xres[n], yres[n], gnd[n]);
+ fprintf (fd, "%s", buf);
+ }
+ else if (group.points.status[n] > 0)
+ printcentered (fd, "?", width);
+ else
+ printcentered (fd, "not used", width);
+ FMT2(buf,
+ group.points.e1[n],
+ group.points.n1[n],
+ group.points.e2[n],
+ group.points.n2[n]);
+ fprintf (fd, " %s\n", buf);
+ }
+ fprintf (fd, "\n");
+ if (group.equation_stat < 0)
+ fprintf (fd, "Poorly place control points\n");
+ else if (group.equation_stat == 0)
+ fprintf (fd, "No active control points\n");
+ else
+ fprintf (fd, "Overall rms error: %.2f\n", rms);
+
+ return 0;
+}
+
+static int printcentered (FILE *fd, char *buf,int width)
+{
+ int len;
+ int n;
+ int i;
+
+ len = strlen (buf);
+ n = (width -len)/2;
+
+ for (i = 0; i < n; i++)
+ fprintf (fd, " ");
+ fprintf (fd, "%s", buf);
+ i += len;
+ while (i++ < width)
+ fprintf (fd, " ");
+
+ return 0;
+}
+
+static int show_point(int n,int true_color)
+{
+ int x_temp[2], y_temp[2];
+ int row,col;
+
+ if (!true_color)
+ R_standard_color (ORANGE);
+ else if(group.points.status[n]>0)
+ R_standard_color (GREEN);
+ else
+ R_standard_color (RED);
+
+
+ /* Display red_points in VIEW_MAP1_ZOOM */
+
+ if (group.points.status[n]==0 || group.points.status[n] == 1 )
+ display_one_point (VIEW_MAP1_ZOOM, group.points.e1[n], group.points.n1[n]);
+ else
+ {
+ display_one_point (VIEW_MAP1_ZOOM, group.points.e1[n], group.points.n1[n]);
+ display_one_point (VIEW_MAP1_ZOOM, group.points.e1[n+1], group.points.n1[n+1]);
+ row = northing_to_row (&VIEW_MAP1_ZOOM->cell.head, group.points.n1[n]) + .5;
+ col = easting_to_col (&VIEW_MAP1_ZOOM->cell.head, group.points.e1[n]) + .5;
+ y_temp[0] = row_to_view (VIEW_MAP1_ZOOM, row);
+ x_temp[0] = col_to_view (VIEW_MAP1_ZOOM, col);
+
+ row = northing_to_row (&VIEW_MAP1_ZOOM->cell.head, group.points.n1[n+1]) + .5;
+ col = easting_to_col (&VIEW_MAP1_ZOOM->cell.head,group.points.e1[n+1]) + .5;
+ y_temp[1] = row_to_view (VIEW_MAP1_ZOOM, row);
+ x_temp[1] = col_to_view (VIEW_MAP1_ZOOM, col);
+
+ R_polyline_abs (x_temp,y_temp,2);
+ R_flush();
+
+ }
+
+
+ /* Display red_points in VIEW_MAP2_ZOOM */
+ if (group.points.status[n]==0 || group.points.status[n] == 1 )
+ display_one_point (VIEW_MAP2_ZOOM, group.points.e2[n], group.points.n2[n]);
+ else
+ {
+ display_one_point (VIEW_MAP2_ZOOM, group.points.e2[n], group.points.n2[n]);
+ display_one_point (VIEW_MAP2_ZOOM, group.points.e2[n+1], group.points.n2[n+1]);
+ row = northing_to_row (&VIEW_MAP2_ZOOM->cell.head, group.points.n2[n]) + .5;
+ col = easting_to_col (&VIEW_MAP2_ZOOM->cell.head, group.points.e2[n]) + .5;
+ y_temp[0] = row_to_view (VIEW_MAP2_ZOOM, row);
+ x_temp[0] = col_to_view (VIEW_MAP2_ZOOM, col);
+
+ row = northing_to_row (&VIEW_MAP2_ZOOM->cell.head, group.points.n2[n+1]) + .5;
+ col = easting_to_col (&VIEW_MAP2_ZOOM->cell.head,group.points.e2[n+1]) + .5;
+ y_temp[1] = row_to_view (VIEW_MAP2_ZOOM, row);
+ x_temp[1] = col_to_view (VIEW_MAP2_ZOOM, col);
+
+ R_polyline_abs (x_temp,y_temp,2);
+ R_flush();
+
+ }
+
+
+
+ return 0;
+}
+
+
+int points_to_line (double e1, double n1, double e2, double n2, double *t, double *u)
+{
+ double a,b,c;
+ a=-(n2 - n1);
+ b= (e2 - e1);
+ c= (n2*e1 - n1*e2);
+ *t= a/c;
+ *u=b/c;
+ }
+
+int new_control_line ( Lines *ln,
+ double t1,double u1,double t2,double u2,int status)
+{
+ int i;
+ unsigned int size;
+
+ i = (ln->count)++ ;
+ size = ln->count * sizeof(double) ;
+ ln->t1 = (double *) G_realloc (ln->t1, size);
+ ln->t2 = (double *) G_realloc (ln->t2, size);
+ ln->u1 = (double *) G_realloc (ln->u1, size);
+ ln->u2 = (double *) G_realloc (ln->u2, size);
+ size = ln->count * sizeof(int) ;
+ ln->status = (int *) G_realloc (ln->status, size);
+
+ ln->t1[i] = t1;
+ ln->t2[i] = t2;
+ ln->u1[i] = u1;
+ ln->u2[i] = u2;
+ ln->status[i] = status;
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/analyze.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/ask.c
===================================================================
--- trunk/grassaddons/i.points.auto/ask.c (rev 0)
+++ trunk/grassaddons/i.points.auto/ask.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,676 @@
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+#define NLINES 18
+
+struct box
+{
+ int top, bottom, left,right;
+};
+
+static int pick(int,int,int);
+static int downarrow(struct box *,int);
+static int uparrow(struct box *,int);
+static int dobox(struct box *,char *,int,int,int,int,int);
+static int dotext(char *,int ,int ,int ,int ,int );
+static int inbox(struct box *,int ,int );
+static int cancel_which();
+
+static int text_size;
+static int which;
+static struct box cancel, more, less;
+static int height, size, edge, count;
+static int page,npages;
+static struct
+{
+ char name[GNAME_MAX], mapset[GMAPSET_MAX];
+ struct box box;
+} list[NLINES*2];
+
+int
+ask_gis_files (char *type, char *file, char *xname, char *xmapset, int position)
+{
+ static int use = 1;
+ int pick();
+ static Objects objects[]=
+ {
+ OTHER(pick,&use),
+ {0}
+ };
+
+ char msg[100];
+ FILE *fd;
+ int width;
+ int len1, len2, len;
+ long offset;
+ long *page_offset;
+ int col, nlist;
+ int line;
+ int stat;
+ char buf[100];
+ int top, bottom, left, right, center;
+ int topx, bottomx, leftx, rightx, widthx;
+ char name[GNAME_MAX], mapset[GMAPSET_MAX], cur_mapset[GMAPSET_MAX];
+ int new_mapset;
+ char debugmsg[200];
+
+ Menu_msg("");
+ debug("ask_gis_files todo\n");
+
+ fd = fopen (file, "r");
+ if (fd == NULL)
+ G_fatal_error ("ask_gis_files: can't read tempfile");
+ if (fread (&len1, sizeof(len1), 1, fd) != 1
+ || fread (&len2, sizeof(len2), 1, fd) != 1
+ || len1 <= 0 || len2 <= 0)
+ {
+ fclose (fd);
+ return 0;
+ }
+
+ sprintf (msg, "Double click on %s file to be plotted", type);
+
+/*
+ * build a popup window at center of the screen.
+ * 35% the height and wide enough to hold 2 columms of file names
+ *
+ * the window is for choosing file names and will be laid out in 2 columns
+ *
+ * ------------------------------------------
+ * | CANCEL | (MORE) | (LESS) |
+ * ------------------------------------------
+ * | mapset |
+ * ------------------------------------------
+ * | name1 | name2 |
+ * ------------------------------------------
+ * | name3 | name4 |
+ * ------------------------------------------
+ * | name5 | name6 |
+ * | . |
+ * | . |
+ * | . |
+ * ------------------------------------------
+ */
+
+/* height of 1 line, based on NLINES taking up 35% vertical space */
+ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP))/NLINES + 1;
+
+/* size of text, 80% of line height */
+ text_size = .8 * height;
+ size = text_size - 1; /* fudge for computing pixels width of text */
+
+/* indent for the text */
+ edge = .1 * height + 1;
+
+/* this is a fudge to determine the length of the largest text */
+ len1 = 2 * len1 ; /* name in 2 columns */
+ len2 += strlen ("mapset ");
+ len = (len1 > len2 ? len1 : len2);
+
+/* width is for max chars plus sidecar for more/less */
+ width = len * size + height;
+ widthx = strlen(msg) * size;
+ if (widthx < width)
+ widthx = width;
+
+/* define the window */
+ top = (SCREEN_TOP + SCREEN_BOTTOM - height*NLINES)/2;
+ bottom = top + height*NLINES;
+
+ center = (SCREEN_LEFT + SCREEN_RIGHT)/2;
+ if (position > 0)
+ {
+ right = (center + SCREEN_RIGHT + width)/2;
+ if (right >= SCREEN_RIGHT)
+ right = SCREEN_RIGHT-1;
+ left = right - width;
+ }
+ else if (position < 0)
+ {
+ left = (center + SCREEN_LEFT - width)/2;
+ if (left <= SCREEN_LEFT)
+ left = SCREEN_LEFT+1;
+ right = left + width;
+ }
+ else
+ {
+ left = center + width/2;
+ right = left + width;
+ }
+
+ topx = top - 3 *height;
+ bottomx = topx + 2*height;
+ leftx = (left+right-widthx)/2;
+ if (leftx < SCREEN_LEFT)
+ leftx = SCREEN_LEFT;
+ rightx = leftx + widthx;
+
+/* save what is under these areas, so they can be restored */
+ R_panel_save (tempfile1, top, bottom, left, right);
+ R_panel_save (tempfile2, topx, bottomx, leftx, rightx);
+
+/* fill it top with GREY, pick area with white */
+ R_standard_color (WHITE);
+ R_box_abs (left, top, right, bottom);
+ R_standard_color (BLACK); /* GREY */
+ R_box_abs (leftx, topx, rightx, bottomx);
+
+ R_standard_color (BLUE); /* BLACK*/
+ Outline_box (top, bottom, left, right);
+ right -=height; /* reduce it to exclude sidecar */
+ Outline_box (top, bottom, left, right);
+
+/* print messages above the files */
+ R_standard_color (ORANGE);/*WHITE*/ /* ADDED */
+ dotext (msg, topx, topx+height, leftx, rightx, 1);
+ dotext ("Double click here to cancel", topx+height, bottomx, leftx, rightx, 1);
+ cancel.top = topx;
+ cancel.bottom = bottomx;
+ cancel.left = leftx;
+ cancel.right = rightx;
+
+/* start the mouse in the cancel box */
+ Set_mouse_xy ((leftx + rightx)/2, (topx + bottomx)/2);
+
+ dobox (&less, "", BLUE, top, right, right+height,0);
+ dobox (&more, "", BLUE, bottom-height, right, right+height,0);
+
+/* as we read the file of names, keep track of pages so we can
+ * page backward
+ */
+ page = 0;
+ page_offset = (long *) G_calloc (npages=1, sizeof(long));
+ *page_offset = ftell(fd);
+
+ nlist = sizeof (list)/ sizeof(list[0]);
+ for (stat = -1; stat < 0;)
+ {
+ line = 0;
+ count = 0;
+ *cur_mapset = 0;
+ col = 0;
+ while(1)
+ {
+ offset = ftell (fd);
+ if (fgets (buf, sizeof buf, fd) == NULL
+ || sscanf (buf, "%s %s", name, mapset) != 2)
+ break;
+ sprintf(debugmsg, "fgets name: %s\n", name);
+ debug(debugmsg);
+ if(new_mapset = (strcmp (cur_mapset,mapset) != 0))
+ {
+ if(line) line++;
+ if (col) line++;
+ col = 0;
+ }
+ if (count >= nlist || line+new_mapset >= NLINES)
+ {
+ if (page+1 == npages)
+ {
+ npages++;
+ page_offset = (long *) G_realloc (page_offset, npages * sizeof (long));
+ page_offset[npages-1] = offset;
+ }
+ break;
+ }
+ if (new_mapset)
+ {
+ struct box dummy;
+ char label[GMAPSET_MAX+7];
+
+ strcpy (cur_mapset, mapset);
+ sprintf (label, "Mapset %s", mapset);
+ dobox (&dummy, label, GREY, top+line*height, left, right, 0);
+ line++;
+ }
+ if (col)
+ {
+ dobox (&list[count].box, name, WHITE, top+line*height, left+width/2, right, 0);
+ line++;
+ col = 0;
+ }
+ else
+ {
+ dobox (&list[count].box, name, WHITE, top+line*height, left, left+width/2, 0);
+ col = 1;
+ }
+
+ strcpy (list[count].name, name);
+ strcpy (list[count].mapset, mapset);
+ count++;
+ }
+
+ downarrow (&more, page+1 < npages ? BLACK : WHITE);
+ uparrow (&less, page > 0 ? BLACK : WHITE);
+ which = -1;
+ switch(Input_pointer(objects))
+ {
+ case -1: /* more or less */
+ break;
+ case -2: /* cancel */
+ stat = 0;
+ continue;
+ default: /* file picked */
+ strcpy (xname, list[which].name);
+ strcpy (xmapset, list[which].mapset);
+ stat = 1;
+ continue;
+ }
+ fseek (fd, page_offset[page], 0);
+ R_standard_color (WHITE);
+ R_box_abs (left+1, top+1, right-1, bottom-1);
+ }
+
+/* all done. restore what was under the window */
+ right += height; /* move it back over the sidecar */
+ R_standard_color (WHITE);
+ R_box_abs (left, top, right, bottom);
+ R_panel_restore (tempfile1);
+ R_panel_restore (tempfile2);
+ R_panel_delete (tempfile1);
+ R_panel_delete (tempfile2);
+ R_flush();
+
+ G_free (page_offset);
+ return stat;
+}
+
+
+
+
+
+
+
+
+
+
+int
+ask_original_map(char *type, char *file, char *xname, char *xmapset, int position)
+{
+ static int use = 1;
+ int pick();
+ static Objects objects[]=
+ {
+ OTHER(pick,&use),
+ {0}
+ };
+
+ char msg[100];
+ FILE *fd;
+ int width;
+ int len1, len2, len;
+ long offset;
+ long *page_offset;
+ int col, nlist;
+ int line;
+ int stat;
+ char buf[100];
+ int top, bottom, left, right, center;
+ int topx, bottomx, leftx, rightx, widthx;
+ char name[GNAME_MAX], mapset[GMAPSET_MAX], cur_mapset[GMAPSET_MAX];
+ int new_mapset;
+
+ Menu_msg("");
+
+ fd = fopen (file, "r");
+ if (fd == NULL)
+ G_fatal_error ("ask_gis_files: can't read tempfile");
+ if (fread (&len1, sizeof(len1), 1, fd) != 1
+ || fread (&len2, sizeof(len2), 1, fd) != 1
+ || len1 <= 0 || len2 <= 0)
+ {
+ fclose (fd);
+ return 0;
+ }
+
+ sprintf (msg, "Double click on the final %s map ", type);
+
+/*
+ * build a popup window at center of the screen.
+ * 35% the height and wide enough to hold 2 columms of file names
+ *
+ * the window is for choosing file names and will be laid out in 2 columns
+ *
+ * ------------------------------------------
+ * | CANCEL | (MORE) | (LESS) |
+ * ------------------------------------------
+ * | mapset |
+ * ------------------------------------------
+ * | name1 | name2 |
+ * ------------------------------------------
+ * | name3 | name4 |
+ * ------------------------------------------
+ * | name5 | name6 |
+ * | . |
+ * | . |
+ * | . |
+ * ------------------------------------------
+ */
+
+
+
+/* height of 1 line, based on NLINES taking up 35% vertical space */
+ height = (.35 * (SCREEN_BOTTOM - SCREEN_TOP))/NLINES + 1;
+
+/* size of text, 80% of line height */
+ text_size = .8 * height;
+ size = text_size - 1; /* fudge for computing pixels width of text */
+
+/* indent for the text */
+ edge = .1 * height + 1;
+
+/* this is a fudge to determine the length of the largest text */
+ len1 = 2 * len1 ; /* name in 2 columns */
+ len2 += strlen ("mapset ");
+ len = (len1 > len2 ? len1 : len2);
+
+/* width is for max chars plus sidecar for more/less */
+ width = len * size + height;
+ widthx = strlen(msg) * size;
+ if (widthx < width)
+ widthx = width;
+
+/* define the window */
+ top = (SCREEN_TOP + SCREEN_BOTTOM - height*NLINES)/2;
+ bottom = top + height*NLINES;
+
+ center = (SCREEN_LEFT + SCREEN_RIGHT)/2;
+ if (position > 0)
+ {
+ right = (center + SCREEN_RIGHT + width)/2;
+ if (right >= SCREEN_RIGHT)
+ right = SCREEN_RIGHT-1;
+ left = right - width;
+ }
+ else if (position < 0)
+ {
+ left = (center + SCREEN_LEFT - width)/2;
+ if (left <= SCREEN_LEFT)
+ left = SCREEN_LEFT+1;
+ right = left + width;
+ }
+ else
+ {
+ left = center + width/2;
+ right = left + width;
+ }
+
+ topx = top - 3 *height;
+ bottomx = topx + 2*height;
+ leftx = (left+right-widthx)/2;
+ if (leftx < SCREEN_LEFT)
+ leftx = SCREEN_LEFT;
+ rightx = leftx + widthx;
+
+
+
+
+/* save what is under these areas, so they can be restored */
+ R_panel_save (tempfile1, top, bottom, left, right);
+ R_panel_save (tempfile2, topx, bottomx, leftx, rightx);
+
+/* fill it top with GREY, pick area with white */
+ R_standard_color (WHITE);
+ R_box_abs (left, top, right, bottom);
+ R_standard_color (BLACK);
+ R_box_abs (leftx, topx, rightx, bottomx);
+
+ R_standard_color (BLUE); /*BLACK */
+ Outline_box (top, bottom, left, right);
+ right -=height; /* reduce it to exclude sidecar */
+ Outline_box (top, bottom, left, right);
+
+/* print messages above the files */
+ R_standard_color (ORANGE); /*BLACK */
+ dotext (msg, topx, topx+height, leftx, rightx, 1);
+ dotext ("Double click here to cancel", topx+height, bottomx, leftx, rightx, 1);
+ cancel.top = topx;
+ cancel.bottom = bottomx;
+ cancel.left = leftx;
+ cancel.right = rightx;
+
+/* start the mouse in the cancel box */
+ Set_mouse_xy ((leftx + rightx)/2, (topx + bottomx)/2);
+
+ dobox (&less, "", BLUE, top, right, right+height,0);
+ dobox (&more, "", BLUE, bottom-height, right, right+height,0);
+
+/* as we read the file of names, keep track of pages so we can
+ * page backward
+ */
+ page = 0;
+ page_offset = (long *) G_calloc (npages=1, sizeof(long));
+ *page_offset = ftell(fd);
+
+
+
+ nlist = sizeof (list)/ sizeof(list[0]);
+ for (stat = -1; stat < 0;)
+ {
+ line = 0;
+ count = 0;
+ *cur_mapset = 0;
+ col = 0;
+ while(1)
+ {
+
+ offset = ftell (fd);
+ if (fgets (buf, sizeof buf, fd) == NULL
+ || sscanf (buf, "%s %s", name, mapset) != 2)
+ break;
+ if(new_mapset = (strcmp (cur_mapset,mapset) != 0))
+ {
+ if(line) line++;
+ if (col) line++;
+ col = 0;
+ }
+ if (count >= nlist || line+new_mapset >= NLINES)
+ {
+ if (page+1 == npages)
+ {
+ npages++;
+ page_offset = (long *) G_realloc (page_offset, npages * sizeof (long));
+ page_offset[npages-1] = offset;
+ }
+ break;
+ }
+ if (new_mapset)
+ {
+ struct box dummy;
+ char label[GMAPSET_MAX+7];
+
+ strcpy (cur_mapset, mapset);
+ sprintf (label, "Mapset %s", mapset);
+ dobox (&dummy, label, GREY, top+line*height, left, right, 0);
+ line++;
+ }
+ if (col)
+ {
+ dobox (&list[count].box, name, WHITE, top+line*height, left+width/2, right, 0);
+ line++;
+ col = 0;
+ }
+ else
+ {
+ dobox (&list[count].box, name, WHITE, top+line*height, left, left+width/2, 0);
+ col = 1;
+ }
+ strcpy (list[count].name, name);
+ strcpy (list[count].mapset, mapset);
+ count++;
+ }
+ downarrow (&more, page+1 < npages ? BLACK : WHITE);
+ uparrow (&less, page > 0 ? BLACK : WHITE);
+ which = -1;
+
+
+
+
+
+ switch(Input_pointer(objects))
+ {
+ case -1: /* more or less */
+ break;
+ case -2: /* cancel */
+ stat = 0;
+ continue;
+ default: /* file picked */
+ strcpy (xname, list[which].name);
+ strcpy (xmapset, list[which].mapset);
+ stat = 1;
+ continue;
+ }
+ fseek (fd, page_offset[page], 0);
+ R_standard_color (WHITE);
+ R_box_abs (left+1, top+1, right-1, bottom-1);
+ }
+
+
+
+/* all done. restore what was under the window */
+ right += height; /* move it back over the sidecar */
+ R_standard_color (WHITE);
+ R_box_abs (left, top, right, bottom);
+ R_panel_restore (tempfile1);
+ R_panel_restore (tempfile2);
+ R_panel_delete (tempfile1);
+ R_panel_delete (tempfile2);
+ R_flush();
+
+
+ G_free (page_offset);
+ return stat;
+}
+
+
+
+
+
+
+
+static int dobox(struct box *box, char *text,int color,int top,int left,int right,int centered)
+{
+ int bottom;
+
+ bottom = top+height;
+/* fill inside of box with color */
+ R_standard_color (color);
+ R_box_abs (left+1, top+1, right-1, bottom-1);
+
+/* draw box outline and text in black */
+ R_standard_color (BLUE); /*BLACK*/
+ Outline_box (top, bottom, left, right);
+ R_standard_color (BLACK); /* ADDED. It determines the colour of text in the table */
+ dotext (text, top, bottom, left, right, centered);
+
+ box->top = top;
+ box->bottom = bottom;
+ box->left = left;
+ box->right = right;
+
+ return 0;
+}
+
+static int uparrow(struct box *box,int color)
+{
+ R_standard_color (color);
+ Uparrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge);
+
+ return 0;
+}
+
+static int downarrow ( struct box *box,int color)
+{
+ R_standard_color (color);
+ Downarrow (box->top+edge, box->bottom-edge, box->left+edge, box->right-edge);
+
+ return 0;
+}
+
+static int pick(int x,int y,int button)
+{
+ int n;
+
+ if (inbox(&more,x,y))
+ {
+ cancel_which();
+ if (page+1 >= npages)
+ return 0;
+ page++;
+ return -1;
+ }
+ if (inbox(&less,x,y))
+ {
+ cancel_which();
+ if (page == 0)
+ return 0;
+ page--;
+ return -1;
+ }
+ if (inbox(&cancel,x,y))
+ {
+ if (which == -2)
+ return -2;
+ cancel_which();
+ which = -2;
+ R_standard_color (RED);
+ Outline_box (cancel.top, cancel.bottom, cancel.left, cancel.right);
+ return 0;
+ }
+/* search name list. handle double click */
+ for (n = 0; n < count; n++)
+ if (inbox(&list[n].box,x,y))
+ {
+ if (n == which) /* second click! */
+ return 1;
+ cancel_which();
+ which = n;
+ R_standard_color (RED);
+ Outline_box (list[n].box.top, list[n].box.bottom,
+ list[n].box.left, list[n].box.right);
+ return 0; /* ignore first click */
+ }
+
+ cancel_which();
+ return 0;
+}
+
+static int
+cancel_which (void)
+{
+ if (which == -2)
+ {
+ R_standard_color (BLACK);
+ Outline_box (cancel.top, cancel.bottom, cancel.left, cancel.right);
+ }
+ else if (which >= 0)
+ {
+ R_standard_color (BLACK);
+ Outline_box (list[which].box.top, list[which].box.bottom,
+ list[which].box.left, list[which].box.right);
+ }
+ which = -1;
+
+ return 0;
+}
+
+static int inbox(struct box *box,int x,int y)
+{
+ return (x>box->left && x right && y>box->top && ybottom);
+}
+
+static int dotext(char *text,int top,int bottom,int left,int right,int centered)
+{
+ R_text_size (text_size, text_size);
+ R_move_abs (left+1+edge, bottom-1-edge);
+ if (centered)
+ R_move_rel ((right-left-strlen(text)*size)/2,0);
+ R_set_window (top, bottom, left, right); /* for text clipping */
+ R_text (text);
+ R_set_window (SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/ask.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/ask_mag.c
===================================================================
--- trunk/grassaddons/i.points.auto/ask_mag.c (rev 0)
+++ trunk/grassaddons/i.points.auto/ask_mag.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,168 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+struct box
+{
+ int top, bottom, left, right;
+};
+
+static struct box plus, minus, value;
+static struct box cancel, accept;
+static int mag;
+static int inbox(struct box *,int,int);
+static int dotext(char *,int,int,int,int,int);
+static int incr(int,int);
+
+int
+ask_magnification (int *magnification)
+{
+ static int use = 1;
+ int incr();
+ int x,y;
+ int height;
+ int stat;
+ int width;
+ int top, bottom, left, right;
+
+ static Objects objects[]=
+ {
+ OTHER(incr, &use),
+ {0}
+ };
+
+ Menu_msg ("");
+
+ mag = *magnification ;
+ if (mag < 1)
+ mag = 1;
+
+ height = VIEW_MENU->nrows;
+ R_text_size (height-4, height-4);
+
+
+ Get_mouse_xy (&x, &y);
+ top = y - height/2;
+ if (top < SCREEN_TOP)
+ top = SCREEN_TOP;
+ bottom = top + 4 * height;
+ if (bottom >= VIEW_MENU->top)
+ {
+ top -= bottom - (VIEW_MENU->top -1);
+ bottom = VIEW_MENU->top-1;
+ }
+ width = Text_width ("MAGNIFICATION") + 4;
+ left = x - width/2;
+ if (left < SCREEN_LEFT)
+ left = SCREEN_LEFT;
+ right = left + width;
+ if (right > SCREEN_RIGHT)
+ {
+ left -= right - SCREEN_RIGHT;
+ right = SCREEN_RIGHT;
+ }
+
+ R_panel_save (tempfile1, top, bottom, left, right);
+ R_standard_color (BLUE); /*WHITE*/
+ R_box_abs (left, top, right, bottom);
+ R_standard_color (RED); /*BLACK*/
+ Outline_box (top, bottom, left, right);
+
+ plus.top = top + height;
+ plus.bottom = plus.top + height;
+ plus.left = left;
+ plus.right = plus.left + Text_width ("++") + 4;
+ Outline_box (plus.top, plus.bottom, plus.left, plus.right);
+
+ minus.top = top + height;
+ minus.bottom = minus.top + height;
+ minus.right = right;
+ minus.left = minus.right - Text_width ("--") - 4;
+ Outline_box (minus.top, minus.bottom, minus.left, minus.right);
+
+ value.top = top + height;
+ value.bottom = value.top + height;
+ value.left = plus.right;
+ value.right = minus.left;
+ Outline_box (value.top, value.bottom, value.left, value.right);
+
+ accept.top = value.bottom;
+ accept.bottom = accept.top + height;
+ accept.left = left;
+ accept.right = right;
+ Outline_box (accept.top, accept.bottom, accept.left, accept.right);
+
+ cancel.top = accept.bottom;
+ cancel.bottom = cancel.top + height;
+ cancel.left = left;
+ cancel.right = right;
+ Outline_box (cancel.top, cancel.bottom, cancel.left, cancel.right);
+
+ dotext ("MAGNIFICATION", top, top+height, left, right, WHITE);
+ dotext ("+", plus.top, plus.bottom, plus.left, plus.right, GREY);
+ dotext ("-", minus.top, minus.bottom, minus.left, minus.right, GREY);
+ dotext ("ACCEPT", accept.top, accept.bottom, accept.left, accept.right, GREY);
+ dotext ("CANCEL", cancel.top, cancel.bottom, cancel.left, cancel.right, GREY);
+ draw_mag();
+
+ stat = Input_pointer (objects);
+
+/* to respond to user */
+ R_standard_color (BLUE); /*WHITE*/
+ R_box_abs (left, top, right, bottom);
+ R_flush();
+
+ R_panel_restore (tempfile1);
+ R_panel_delete (tempfile1);
+
+ *magnification = mag;
+ return stat > 0;
+}
+
+int
+draw_mag (void)
+{
+ char buf[10];
+
+ sprintf (buf, "%d", mag);
+ dotext (buf, value.top, value.bottom, value.left, value.right, WHITE);
+
+ return 0;
+}
+
+static int incr(int x,int y)
+{
+ if (inbox (&accept,x,y))
+ return 1;
+ if (inbox (&cancel,x,y))
+ return -1;
+ if (inbox (&plus,x,y))
+ {
+ mag++;
+ draw_mag();
+ }
+ else if (inbox (&minus,x,y) && mag > 1)
+ {
+ mag--;
+ draw_mag();
+ }
+ return 0;
+}
+
+static int dotext(char *text,int top,int bottom,int left,int right,int background)
+{
+ R_standard_color (BLUE); /*background*/
+ R_box_abs (left+1, top+1, right-1, bottom-1);
+ R_standard_color (WHITE); /*BLACK*/
+ /* center the text */
+ left = (left + right - Text_width (text))/2;
+ Text (text, top, bottom, left, right, 2);
+ R_flush();
+
+ return 0;
+}
+
+static int inbox(struct box *box,int x,int y)
+{
+ return (x>box->left && x right && y>box->top && ybottom);
+}
Property changes on: trunk/grassaddons/i.points.auto/ask_mag.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/call.c
===================================================================
--- trunk/grassaddons/i.points.auto/call.c (rev 0)
+++ trunk/grassaddons/i.points.auto/call.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,58 @@
+#include
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+/*
+ * call a subroutine, but as a child process
+ * allowing interrupts for the child
+ */
+#include
+
+int call (int (*function)(),char *msg)
+{
+ int pid;
+ int w, status;
+ char i_msg[80];
+
+/*
+ * build interrupt msg
+ */
+ sprintf (i_msg, "Hit %s %s\n", G_unctrl(interrupt_char), msg);
+/*
+ * make sure all graphics have gotten to the monitor
+ */
+ R_stabilize();
+
+/* fork to create child */
+ pid = fork();
+ if (pid < 0)
+ {
+ End_curses();
+ perror ("Can't fork");
+ exit (1);
+ }
+
+/* parent just waits for child */
+ Curses_allow_interrupts(1);
+ if (pid)
+ {
+ Curses_write_window (PROMPT_WINDOW, 1, 1, i_msg);
+ while ( (w = wait (&status)) != pid && w != -1)
+ ;
+ Curses_allow_interrupts(0);
+ Curses_write_window (PROMPT_WINDOW, 1, 1, "\n");
+ }
+
+/* child turns on interrupts and calls the function */
+ else
+ {
+ signal (SIGINT, SIG_DFL);
+ (*function)();
+ exit(0);
+ }
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/call.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/cell.c
===================================================================
--- trunk/grassaddons/i.points.auto/cell.c (rev 0)
+++ trunk/grassaddons/i.points.auto/cell.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,100 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int use = 1;
+static int choose_cellfile(char *,char *);
+static int plot(int,int);
+static int cancel(void);
+
+int
+plotcell (int x, int y)
+{
+ int cancel();
+ int plot();
+ static Objects objects[] =
+ {
+ MENU("CANCEL", cancel, &use),
+ INFO("Indicate which side should be plotted", &use),
+ OTHER(plot, &use),
+ {0}
+ };
+/*
+ * if the target cell file list is ready, ask the user which side
+ * should be plotted, otherwise can only plot group files
+ */
+ if (access (cell_list,0) == 0)
+ Input_pointer (objects);
+ else
+ plot (VIEW_MAP1->left+1,0);
+ return 0;
+}
+
+static int
+cancel (void)
+{
+ return 1;
+}
+
+
+static int plot(int x,int y)
+{
+ char name[100], mapset[100];
+ struct Cell_head cellhd;
+
+ if (x > VIEW_MAP1->left && x < VIEW_MAP1->right)
+ {
+ if (!choose_groupfile(name,mapset))
+ return 1;
+ if(G_get_cellhd(name, mapset, &cellhd) < 0)
+ return 1;
+
+ Erase_view (VIEW_MAP1_ZOOM);
+ VIEW_MAP1_ZOOM->cell.configured = 0;
+
+ G_adjust_window_to_box (&cellhd, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows, VIEW_MAP1->ncols);
+ Configure_view (VIEW_MAP1, name, mapset, cellhd.ns_res, cellhd.ew_res);
+ drawcell(VIEW_MAP1);
+ }
+ else if (x > VIEW_MAP2->left && x < VIEW_MAP2->right)
+ {
+ if (!ask_gis_files("raster",group_list,name, mapset,1))
+ return 1;
+ select_target_env();
+
+ if(G_get_cellhd(name, mapset, &cellhd) < 0)
+ {
+ select_current_env();
+ return 1;
+ }
+
+ Erase_view (VIEW_MAP2_ZOOM);
+ VIEW_MAP2_ZOOM->cell.configured = 0;
+
+ G_adjust_window_to_box (&cellhd, &VIEW_MAP2->cell.head, VIEW_MAP2->nrows, VIEW_MAP2->ncols);
+ Configure_view (VIEW_MAP2, name, mapset, cellhd.ns_res, cellhd.ew_res);
+ select_target_env();
+ drawcell(VIEW_MAP2);
+ select_current_env();
+ if (from_screen < 0)
+ {
+ from_flag = 1;
+ from_screen = 0;
+ if (from_keyboard < 0)
+ {
+ from_keyboard = 0;
+ from_screen = 1;
+ }
+ }
+ }
+ else
+ return 0; /* ignore mouse click */
+
+ display_points(1);
+ return 1;
+}
+
+static int choose_cellfile(char *name,char *mapset)
+{
+ return ask_gis_files ("raster", cell_list, name, mapset, 1);
+}
Property changes on: trunk/grassaddons/i.points.auto/cell.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/cellhd.c
===================================================================
--- trunk/grassaddons/i.points.auto/cellhd.c (rev 0)
+++ trunk/grassaddons/i.points.auto/cellhd.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,25 @@
+#include "globals.h"
+#include "local_proto.h"
+
+int
+Outline_cellhd (View *view, struct Cell_head *cellhd)
+{
+ int row,col;
+ int top, bottom, left, right;
+
+ row = northing_to_row (&view->cell.head, cellhd->north) + .5;
+ top = row_to_view (view, row);
+
+ col = easting_to_col (&view->cell.head, cellhd->west) + .5;
+ left = col_to_view (view, col);
+
+ row = northing_to_row (&view->cell.head, cellhd->south) + .5;
+ bottom = row_to_view (view, row);
+
+ col = easting_to_col (&view->cell.head, cellhd->east) + .5;
+ right = col_to_view (view, col);
+
+ Outline_box (top, bottom, left, right);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/cellhd.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/colors.c
===================================================================
--- trunk/grassaddons/i.points.auto/colors.c (rev 0)
+++ trunk/grassaddons/i.points.auto/colors.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,7 @@
+#include
+#include
+int
+set_colors (struct Colors *colors)
+{
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/colors.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/conv.c
===================================================================
--- trunk/grassaddons/i.points.auto/conv.c (rev 0)
+++ trunk/grassaddons/i.points.auto/conv.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,59 @@
+#include "globals.h"
+
+/* conversion routines to convert from view x,y to cell col,row
+ * as well as cell col,row to cell east,north
+ */
+int
+view_to_col (View *view, int x)
+{
+ return x - view->cell.left;
+}
+
+int
+view_to_row (View *view, int y)
+{
+ return y - view->cell.top;
+}
+
+int
+col_to_view (View *view, int col)
+{
+ return view->cell.left + col;
+}
+
+int
+row_to_view (View *view, int row)
+{
+ return view->cell.top + row;
+}
+
+/* in these next 2 routines, location determines if we are
+ * converting from center of the cell (location == .5)
+ * top or left edge (location == 0.0)
+ * bottom or right edge (location == 1.0)
+ */
+
+double
+row_to_northing (struct Cell_head *cellhd, int row, double location)
+{
+ return cellhd->north - (row + location) * cellhd->ns_res;
+}
+
+double
+col_to_easting (struct Cell_head *cellhd, int col, double location)
+{
+ return cellhd->west + (col + location) * cellhd->ew_res;
+}
+
+double
+northing_to_row (struct Cell_head *cellhd, double north)
+{
+ return (cellhd->north - north) / cellhd->ns_res;
+}
+
+double
+easting_to_col (struct Cell_head *cellhd, double east)
+{
+ return (east - cellhd->west) / cellhd->ew_res;
+}
+
Property changes on: trunk/grassaddons/i.points.auto/conv.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/curses.c
===================================================================
--- trunk/grassaddons/i.points.auto/curses.c (rev 0)
+++ trunk/grassaddons/i.points.auto/curses.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,282 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int inited = 0;
+
+static WINDOW *save;
+WINDOW *newwin();
+
+static Window *make_window (int top, int bottom, int left, int right)
+{
+ Window *window;
+
+ if (top < 0 || bottom >= LINES || left < 0 || right >= COLS
+ || bottom-top <= 1 || right-left <= 1)
+ {
+ End_curses();
+ fprintf (stderr, "make_window(%d,%d,%d,%d): illegal screen values\n",
+ top, bottom, left, right);
+ sleep(3);
+ exit(1);
+ }
+ window = (Window *) G_malloc (sizeof(Window));
+ window->top = top;
+ window->bottom = bottom;
+ window->left = left;
+ window->right = right;
+ Curses_clear_window (window);
+ return window;
+}
+
+int Begin_curses (void)
+{
+/* should only be called once at program outset */
+
+ initscr () ; /* initialize curses standard screens */
+ raw() ; /* set tty modes via curses calls */
+ noecho() ;
+ nonl() ;
+
+ inited = 1;
+
+/* make a window to save stdscr */
+ save = newwin(LINES,COLS,0,0);
+
+/* make_window (nrows, ncols, start_row, start_col) */
+ INFO_WINDOW = make_window (0, LINES-4, COLS/2, COLS-1);
+ MENU_WINDOW = make_window (0, LINES-4, 0, COLS/2);
+ PROMPT_WINDOW = make_window (LINES-4, LINES-1, 0, COLS-1);
+ refresh();
+
+
+ return 0;
+}
+
+int End_curses (void)
+{
+/* should only be called upon program exit */
+
+ clear() ; /* clear the screen */
+ refresh() ;
+ endwin() ; /* let curses reset the tty now */
+
+ return 0;
+}
+
+int Suspend_curses (void)
+{
+ overwrite (stdscr, save);
+ clear();
+ refresh();
+ endwin();
+
+ return 0;
+}
+
+int Resume_curses (void)
+{
+ clear();
+ refresh();
+ overwrite (save, stdscr);
+ refresh();
+
+ return 0;
+}
+
+int Curses_allow_interrupts (int ok)
+{
+ refresh();
+ if (ok)
+ noraw();
+ else
+ raw();
+
+ return 0;
+}
+
+int Curses_clear_window (Window *window)
+{
+ int y,x;
+
+if (!inited) return 1;
+ for (y = window->top+1; y < window->bottom; y++)
+ {
+ move (y, x=window->left+1);
+ while (x++ < window->right)
+ addch (' ');
+ }
+ Curses_outline_window (window);
+ refresh();
+
+ return 0;
+}
+
+int Curses_outline_window (Window *window)
+{
+ int x, y;
+
+ move (window->top, x=window->left+1);
+ while (x++ < window->right)
+ addch ('-');
+ move (window->bottom, x=window->left+1);
+ while (x++ < window->right)
+ addch ('-');
+ for (y=window->top+1; y < window->bottom; y++)
+ {
+ move (y, window->left);
+ addch ('|');
+ move (y, window->right);
+ addch ('|');
+ }
+ move (window->top, window->left);
+ addch ('+');
+ move (window->top, window->right);
+ addch ('+');
+ move (window->bottom, window->left);
+ addch ('+');
+ if (window->bottom < LINES-1 || window->right < COLS-1)
+ {
+ move (window->bottom, window->right);
+ addch ('+');
+ }
+
+ return 0;
+}
+
+int Curses_write_window (Window *window, int line, int col, char *message)
+{
+ int y,x,i;
+
+if (!inited)
+{
+ fprintf (stderr, "%s\n", message);
+ return 1;
+}
+ if (line <= 0 || line >= window->bottom-window->top)
+ return 1;
+ if (col <= 0 || col >= window->right-window->left)
+ return 1;
+ move(y=window->top+line, x=window->left+col);
+ while (*message != 0 && *message != '\n' && x < window->right)
+ {
+ addch (*message);
+ message++;
+ x++;
+ }
+ if (*message == '\n')
+ for (i = x; i < window->right; i++)
+ addch (' ');
+ move (y, x);
+ refresh();
+
+ return 0;
+}
+
+
+int
+Curses_replot_screen (void)
+{
+ int x,y;
+ getyx (stdscr, y, x);
+ wrefresh(curscr) ;
+ move (y, x);
+ refresh();
+
+ return 0;
+}
+
+int Curses_prompt_gets (char *prompt, char *answer)
+{
+ char c ;
+ int n;
+ int y,x;
+
+ *answer = 0;
+ n = 0;
+
+ Curses_write_window (PROMPT_WINDOW, 1, 1, "\n");
+ Curses_write_window (PROMPT_WINDOW, 1, 1, prompt);
+
+ for(;;)
+ {
+ refresh ();
+ c = Curses_getch(0) ;
+ if (c == '\n' || c == '\r')
+ break;
+
+ getyx (stdscr, y, x);
+ if (c > 037 && c < 0177)
+ {
+ if (x < PROMPT_WINDOW->right)
+ {
+ *answer++ = c ;
+ *answer = 0 ;
+ addch(c) ;
+ n++;
+ }
+ continue;
+ }
+ if (c == '\b')
+ {
+ if (n > 0)
+ {
+ answer--;
+ *answer = 0;
+ move (y, x-1);
+ addch (' ');
+ move (y, x-1);
+ n--;
+ }
+ continue;
+ }
+ Beep();
+ }
+
+ return 0;
+}
+
+int
+Beep (void)
+{
+ putchar ('\7');
+ fflush (stdout);
+
+ return 0;
+}
+
+int
+Curses_getch (int with_echo)
+{
+ char achar;
+ int c;
+ int kill;
+
+if (!inited) return 0;
+ kill = 0;
+ while(1)
+ {
+ c = getch() & 0177;
+ if (c == interrupt_char)
+ {
+ if (kill++ >= 3)
+ {
+ End_curses();
+ exit(0);
+ }
+ continue;
+ }
+ kill = 0;
+ if (c != 18)
+ break;
+ Curses_replot_screen();
+ }
+ if (with_echo)
+ {
+ achar = c;
+ addch(achar);
+ refresh();
+ }
+ return c;
+}
Property changes on: trunk/grassaddons/i.points.auto/curses.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/debug.c
===================================================================
--- trunk/grassaddons/i.points.auto/debug.c (rev 0)
+++ trunk/grassaddons/i.points.auto/debug.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,13 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+int
+debug (char *msg)
+{
+ R_stabilize();
+ Curses_write_window (PROMPT_WINDOW, 1, 1, msg);
+ /* Curses_getch(0);*/
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/debug.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/defs.h
===================================================================
--- trunk/grassaddons/i.points.auto/defs.h (rev 0)
+++ trunk/grassaddons/i.points.auto/defs.h 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,72 @@
+#include
+#include
+
+/* this is a curses structure */
+typedef struct
+{
+ int top, left, bottom, right;
+} Window;
+
+/* this is a graphics structure */
+typedef struct
+{
+ int top, bottom ,left, right;
+ int nrows, ncols;
+ struct
+ {
+ int configured;
+ struct Cell_head head;
+ struct Colors colors;
+ char name[100];
+ char mapset[100];
+ int top, bottom ,left, right;
+ double ew_res, ns_res; /* original map resolution */
+ } cell;
+} View;
+
+
+typedef struct
+{
+ char name[100];
+ struct Ref ref;
+ struct Control_Points points;
+ double E12[3], N12[3], E21[3], N21[3];
+ int equation_stat;
+} Group;
+
+typedef struct
+{
+ int type; /* object type */
+ int (*handler)(); /* routine to handle the event */
+ char *label; /* label to display if MENU or OPTION */
+ int binding; /* OPTION bindings */
+ int *status; /* MENU,OPTION status */
+ int top,bottom,left,right;
+} Objects;
+
+#define MENU_OBJECT 1
+#define OPTION_OBJECT 2
+#define INFO_OBJECT 3
+#define OTHER_OBJECT 4
+
+
+#define MENU(label,handler,status) \
+ {MENU_OBJECT,handler,label,0,status,0,0,0,0}
+#define OPTION(label,binding,status) \
+ {OPTION_OBJECT,NULL,label,binding,status,0,0,0,0}
+#define INFO(label,status) \
+ {INFO_OBJECT,NULL,label,0,status,0,0,0,0}
+#define OTHER(handler,status) \
+ {OTHER_OBJECT,handler,NULL,0,status,0,0,0,0}
+
+typedef struct
+{
+ double *t1;
+ double *u1;
+ double *t2;
+ double *u2;
+ int *status;
+ double E12[3], N12[3], E21[3], N21[3];
+ int count;
+ int line_stat;
+} Lines;
Property changes on: trunk/grassaddons/i.points.auto/defs.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/description.html
===================================================================
--- trunk/grassaddons/i.points.auto/description.html (rev 0)
+++ trunk/grassaddons/i.points.auto/description.html 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,55 @@
+DESCRIPTION
+
+This module allows a search of GCP's on two raster-maps with differents levels
+of automation.
+
+The manual search is the default search, so it's possible to
+determine the GCP's manually with the mouse.
+
+Semiautomated-search
+You have to determine with the mouse some corrispondent areas
+(with a discrete precision) in the two maps and the module searches the GCP's in these areas.
+
+Automated-search
+At the start of module you have to load the maps that the algorithm uses to the search,
+so it's recommended to use the maps filtered with the filters DIVERSITY or STDDEV
+(of GRASS) with a window of 3x3 or 5x5 pixels. However, the algorithm sometimes work
+well with the original maps too.
+
+You click the button Automated-Search and then you have to load the maps that you want to
+visualize at the end of the search (with the GCP's), usually they are the original maps.
+
+If the maps have strong geometric distortion and strong geometric differencies, maybe
+the results of the search (with the default options) are not good, so you can click the
+button LESS-GCP's and then repeat the operation.
+
+The Overlap-Points (O.P.) era two corresponding points (one for every maps) that is
+used from the algorithm to determine the overlapping-area in the two maps.
+The Master-map is considered the map on the left, and the Slave-map is the map on the right.
+
+Center, top, bottom, left, right are the position of the Master Overlap-Point (on the
+left map) that will be searched on the Slave map (right map). Center is the point at the
+center of the map. Top, bottom, left, right are the position of the O.P. respect to
+the center of the map. If you choose one of these possibilities, then you have to
+choose the shift from the center, measured in percentage of the dimensions of the map; there
+are two possibilities: 5% and 10%.
+This type of search is the most automated (fully-automated ).
+
+If you choose -MARK SLAVE O.P.-, then the module visualizes a blue point at the center
+of the master map, and you have to mark the corrispondent point on the slave map.
+You can use this function if the maps are overlapped for more of 50% and if the
+algorithm doesn't have success in the fully-automated search.
+
+If the maps have a overlapping area less of 50%, you can use the function -MARK M and S O.P.-.
+You have to mark a point in the master map and the corresponding point on the slave map.
+
+At the end of search it's possible to exclude automatically the points not really
+corresponding. This function use the rms with a threshold. The default-value for
+the threshold is 2.5, but (before to active the Auto-Exclusion) you can change it,
+chossing one of different proposed values; you can choose an arbitrary value with
+click on -OTHER-, so you go on the shell and digit the value from keyboard and confirm
+with ENTER.
+
+AUTHOR
+
+Last changed: $Date: 2006/06/22 07:46:46 $
Added: trunk/grassaddons/i.points.auto/digit.c
===================================================================
--- trunk/grassaddons/i.points.auto/digit.c (rev 0)
+++ trunk/grassaddons/i.points.auto/digit.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,129 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int setup(void);
+static int oops(void);
+static int yes(void);
+static int no(void);
+
+int
+setup_digitizer (void)
+{
+ static int use = 1;
+ int setup(), no(), yes();
+ static Objects objects[]=
+ {
+ INFO("Do you wish to use the digitizer? ", &use),
+ MENU("YES", yes, &use),
+ MENU("NO", no, &use),
+ {0}
+ };
+ char command[1024];
+
+ use_digitizer = 0;
+/*
+ * test to see if we have a digitizer (geo.quest)
+ * make sure this program has execute permission first.
+ * then run the program and check its exit status
+ * 0 means can use digitizer, other means can't
+ */
+ sprintf (command, "%s/etc/geo.quest", G_gisbase());
+ if (access (command, 1) != 0)
+ return 0;
+ if (system(command))
+ return 0;
+
+
+/*
+ * ask the user if he/she wishes to use it
+ */
+ Start_mouse_in_menu();
+ Input_pointer (objects);
+ if (use_digitizer)
+ Input_other (setup, "Keyboard");
+
+ return 0;
+}
+
+static int
+setup (void)
+{
+ char command[1024];
+/*
+ * setup the digitizer. system() call must exit with 0 to indicate
+ * everything went fine
+ */
+ sprintf (command, "%s/etc/geo.reg %s %d",
+ G_gisbase(), digit_points, getpid());
+ Suspend_curses();
+ if (system (command))
+ {
+ use_digitizer = 0;
+ sleep(3);
+ }
+ Resume_curses();
+
+ return 0;
+}
+
+int
+digitizer_point (double *east, double *north)
+{
+ char command[1024];
+ FILE *fd;
+ int stat;
+
+/* make sure digitzer is to be used */
+ if (!use_digitizer)
+ return 0;
+
+ sprintf (command, "%s/etc/geo.point %s %s",
+ G_gisbase(), digit_points, digit_results);
+
+ Suspend_curses();
+ if(system (command))
+ {
+ sleep(3);
+ Resume_curses();
+ oops();
+ return 0;
+ }
+ Resume_curses();
+ fd = fopen (digit_results, "r");
+ if (fd == NULL)
+ {
+ oops();
+ return 0;
+ }
+ stat = (fscanf (fd, "%lf %lf", east, north) == 2);
+ fclose (fd);
+
+ if (stat == 0)
+ oops();
+ return stat;
+}
+
+static int
+oops (void)
+{
+ Curses_clear_window (MENU_WINDOW);
+ Curses_write_window (MENU_WINDOW, 3,2,"Can't get data from digitizer");
+
+ return 0;
+}
+
+static int
+no (void)
+{
+ use_digitizer = 0;
+ return 1;
+}
+
+static int
+yes (void)
+{
+ use_digitizer = 1;
+ return 1;
+}
Property changes on: trunk/grassaddons/i.points.auto/digit.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/dot.c
===================================================================
--- trunk/grassaddons/i.points.auto/dot.c (rev 0)
+++ trunk/grassaddons/i.points.auto/dot.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,55 @@
+#include
+#include "globals.h"
+
+int
+dot (int x, int y)
+{
+ int vx[5], vy[5];
+
+ vx[0] = x; vy[0] = y - dotsize;
+ vx[1] = x - dotsize; vy[1] = y;
+ vx[2] = x; vy[2] = y + dotsize;
+ vx[3] = x + dotsize; vy[3] = y;
+ vx[4] = x; vy[4] = y - dotsize;
+
+ R_polygon_abs (vx, vy, 5);
+/*
+ int i;
+
+ for (i = 0; i < dotsize; i++)
+ {
+ R_move_abs (x-i, y+i-dotsize);
+ R_cont_rel (i+i,0);
+ R_move_abs (x-i, y+dotsize-i);
+ R_cont_rel (i+i,0);
+ }
+ R_move_abs (x-dotsize, y);
+ R_cont_rel (dotsize+dotsize, 0);
+*/
+
+ return 0;
+}
+
+int
+save_under_dot (int x, int y)
+{
+ R_panel_save (tempfile1, y-dotsize, y+dotsize, x-dotsize, x+dotsize);
+
+ return 0;
+}
+
+int
+restore_under_dot (void)
+{
+ R_panel_restore (tempfile1);
+
+ return 0;
+}
+
+int
+release_under_dot (void)
+{
+ R_panel_delete (tempfile1);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/dot.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/drawcell.c
===================================================================
--- trunk/grassaddons/i.points.auto/drawcell.c (rev 0)
+++ trunk/grassaddons/i.points.auto/drawcell.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,77 @@
+#include
+#include
+#include "globals.h"
+#include
+#include
+#include "local_proto.h"
+
+int drawcell(View *view)
+{
+ int fd;
+ int left, top;
+ int ncols, nrows;
+ int row;
+ DCELL *dcell;
+ struct Colors *colors;
+ int read_colors;
+ char msg[GNAME_MAX];
+
+
+ if (!view->cell.configured) return 0;
+ if (view == VIEW_MAP1 || view == VIEW_MAP1_ZOOM)
+ {
+ colors = &VIEW_MAP1->cell.colors;
+ read_colors = view == VIEW_MAP1;
+ }
+ else
+ {
+ colors = &VIEW_MAP2->cell.colors;
+ read_colors = view == VIEW_MAP2;
+ }
+ if (read_colors)
+ {
+ G_free_colors (colors);
+ if(G_read_colors (view->cell.name, view->cell.mapset, colors) < 0)
+ return 0;
+ }
+
+ display_title (view);
+
+ set_colors (colors);
+
+ G_set_window (&view->cell.head);
+ nrows = G_window_rows();
+ ncols = G_window_cols();
+
+ left = view->cell.left;
+ top = view->cell.top;
+
+ R_standard_color (BLUE);
+ Outline_box (top, top+nrows-1, left, left+ncols-1);
+
+ if (getenv("NO_DRAW"))
+ return 1;
+
+ fd = G_open_cell_old (view->cell.name, view->cell.mapset);
+ if (fd < 0)
+ return 0;
+ dcell = G_allocate_d_raster_buf();
+
+ sprintf (msg, "Plotting %s ...", view->cell.name);
+ Menu_msg(msg);
+
+ D_cell_draw_setup(top, top + nrows, left, left + ncols);
+ for (row = 0; row < nrows; row++)
+ {
+ if(G_get_d_raster_row_nomask(fd, dcell, row) < 0)
+ break;
+ D_draw_d_raster (row, dcell, colors);
+ }
+ D_cell_draw_end();
+ G_close_cell (fd);
+ G_free (dcell);
+ if(colors != &VIEW_MAP1->cell.colors)
+ set_colors(&VIEW_MAP1->cell.colors);
+
+ return row==nrows;
+}
Property changes on: trunk/grassaddons/i.points.auto/drawcell.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/driver.c
===================================================================
--- trunk/grassaddons/i.points.auto/driver.c (rev 0)
+++ trunk/grassaddons/i.points.auto/driver.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,63 @@
+#include "globals.h"
+#include "local_proto.h"
+
+static int use = 1;
+static int stop(void);
+static int dont_stop(void);
+static int really_quit(void);
+
+int driver (void)
+{
+ static Objects objects[] =
+ {
+ MENU(" QUIT ",really_quit,&use),
+ MENU(" ZOOM ",zoom,&use),
+ MENU(" PLOT RASTER ",plotcell,&use),
+ MENU(" LINE ",line,&use),
+ MENU(" ANALYZE ",analyze,&use),
+ MENU(" SEMIAUTOMATED SEARCH ",Extract_matrix_semi,&use),
+ MENU(" AUTOMATED SEARCH ",automated_search,&use),
+ OTHER(mark, &use),
+ {0}
+ };
+
+ Input_pointer (objects);
+ Menu_msg ("");
+
+ return 0;
+}
+
+
+
+
+
+
+static int
+really_quit (void)
+{
+ static Objects objects[] =
+ {
+ INFO("really quit? ",&use),
+ MENU(" NO ",dont_stop,&use),
+ MENU(" YES ",stop,&use),
+ {0}
+ };
+ if (Input_pointer (objects) < 0)
+ return -1;
+ return 0; /* don't quit */
+}
+
+
+static int
+dont_stop (void)
+{
+ return 1;
+}
+
+static int
+stop (void)
+{
+ return -1;
+}
+
+
Property changes on: trunk/grassaddons/i.points.auto/driver.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/equ.c
===================================================================
--- trunk/grassaddons/i.points.auto/equ.c (rev 0)
+++ trunk/grassaddons/i.points.auto/equ.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,11 @@
+#include "globals.h"
+#include "local_proto.h"
+
+int
+Compute_equation (void)
+{
+ group.equation_stat = compute_georef_equations(&group.points,
+ group.E12, group.N12, group.E21, group.N21);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/equ.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/find.c
===================================================================
--- trunk/grassaddons/i.points.auto/find.c (rev 0)
+++ trunk/grassaddons/i.points.auto/find.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,21 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+/*
+ * run etc/i.find command find all cell, vect files
+ * in the target location.
+ */
+int find_target_files (void)
+{
+ char command[1024];
+
+ select_target_env();
+ sprintf (command, "%s/etc/i.find %s %s cell %s dig %s",
+ G_gisbase(), G_location(), G_mapset(), cell_list, vect_list);
+ select_current_env();
+
+ system(command);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/find.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/find_points.c
===================================================================
--- trunk/grassaddons/i.points.auto/find_points.c (rev 0)
+++ trunk/grassaddons/i.points.auto/find_points.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,2212 @@
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#ifdef HAVE_FFTW_H
+#include
+#endif
+#ifdef HAVE_DFFTW_H
+#include
+#endif
+
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+#ifdef NULL_VALUE
+#undef NULL_VALUE
+#endif
+#define NULL_VALUE -1
+
+
+double *fft_first[2];
+double *fft_second[2];
+double *fft_prod_con[2];
+
+int n=1; /*If (n==1) then the algorithm is searching the Overlapping-Area, if (n==2), it is searching the GCP's*/
+int pos_point;
+int dist;
+int ncols1, ncols2, nrows1, nrows2;
+int nrows1_img, ncols1_img, nrows2_img, ncols2_img;
+int r1, c1; /* Central (or around the central) point of the first img */
+int r2, c2; /* Corresponding point in the second img */
+int r2c, c2c; /* Central point of the first img */
+
+char *group_name;
+char *group_MAPSET;
+char *group_LOCATION_NAME;
+char *group_GISDBASE;
+int q;
+FILE *fp;
+FILE *fp_old;
+/*int i;*/
+char file_name[500];
+
+char name1[100];
+char name2[100];
+char mapset[100];
+
+int dist_r, dist_c;
+
+int z;
+
+
+int n_points=0; /* When "LESS_GCP's" is activated, then (n_points==0) */
+int man_op=0; /* Variable for the option "Manual_OP". It's 1 if the option is activated */
+double e_man2, n_man2; /* Coordinates for the manual_OP */
+int man_m_s_op=0;
+double e_man1, n_man1;
+
+View *m1, *m2;
+
+
+
+
+int min(int a, int b)
+{
+
+ if(a <= b)
+ {
+ return a;
+ }
+ else
+ {
+ return b;
+ }
+}
+
+static int main_menu();
+static int cancel();
+static int shift1();
+static int shift2();
+
+static int less_GCPs();
+static int manual_op();
+static int manual_op1();
+static int mark_op(int x,int y,int button);
+static int mark_point_op (View *view,int x, int y);
+
+static int central();
+static int top();
+static int bottom();
+static int left();
+static int right();
+
+static int manual_m_s_op();
+static int manual_m_s_op1();
+static int mark_m_s_op(int x,int y,int button);
+static int mark_point_m_s_op (View *view,int x, int y);
+
+/* variables for function "TRY_AGAIN" */
+char name1_initial[100];
+char name2_initial[100];
+char mapset_initial[100];
+static int try_again();
+static int store_points();
+
+
+
+
+/* Variables and functions for the Auto-Exclusion */
+static int curp, first_point;
+static double *xres, *yres, *gnd, *tres, *ures, *lgnd;
+static int offsetx, offsety;
+static int xmax, ymax, gmax;
+static int tmax, umax, lgmax;
+static double rms,l_rms;
+static double th=2.5; /*Default threshold of the rms for the Auto-Exclusion.*/
+char file_name1[500];
+static int auto_exclusion();
+static int change_rms_th();
+static int compute_transformation(void);
+static int th_1();
+static int th_2();
+static int th_3();
+static int th_4();
+static int th_5();
+static int other_th();
+static int pre_analyze();
+
+
+
+
+
+
+
+
+
+int automated_search()
+{
+
+ static int use = 1;
+
+ ask_original_map ("raster", group_list, name1,mapset, -1);
+ ask_original_map ("raster", group_list, name2,mapset, 1);
+
+
+
+ static Objects objects1[]=
+ {
+ MENU(" MAIN MENU ",cancel,&use),
+ INFO(" O.P. -> ",&use),
+ MENU(" Central ",central,&use),
+ MENU(" Top ",top,&use),
+ MENU(" Bottom ",bottom,&use),
+ MENU(" Left ",left,&use),
+ MENU(" Right ",right,&use),
+ INFO(" ",&use),
+ MENU(" LESS GCPs ",less_GCPs,&use),
+ MENU(" Mark Slave-O.P. ",manual_op,&use),
+ MENU(" Mark M&S-O.P. ",manual_m_s_op,&use),
+ {0}
+ };
+
+
+ Input_pointer (objects1);
+
+ m=0;
+
+ return 0;
+
+}
+
+
+
+
+
+
+void Extract_matrix()
+{
+ struct GModule *module;
+ struct Control_Points *cp1;
+ char buf[256];
+ char *s;
+ int rows, cols;
+
+ char *first_map_R_mapset;
+ char *first_map_R_name;
+ int first_map_R_fd;
+ char *second_map_R_mapset;
+ char *second_map_R_name;
+ int second_map_R_fd;
+
+ int K;
+
+ int correlation_window_dim;
+ int search_window_dim;
+ int search_window_dim1;
+ int search_window_dim2;
+
+
+ int squared_search_window_dim;
+ int search_jump;
+
+ int left1, top1, left2, top2;
+ int repeat;
+
+ int n_1, e_1, n_2, e_2, s_1, s_2, w_1, w_2;
+ int r1_1, r1_2, r2_1, r2_2;
+ int c1_1, c1_2, c2_1, c2_2;
+
+ int i;
+
+ int h1_r;
+ int h1_c;
+ int h2_r;
+ int h2_c;
+
+
+ DCELL *rowbuf1_R;
+ DCELL *tf1_R;
+ DCELL *rowbuf2_R;
+ DCELL *tf2_R;
+ double **search_window;
+ double **mat1,**mat2;
+ int r,c;
+ int search_border;
+ int p1;
+ int dim_win_c, dim_win_r;
+ char first_sites[500];
+ char second_sites[500];
+ char file_name_old[500];
+ FILE *first_fp;
+ FILE *second_fp;
+
+ int xp1, yp1, xs1, ys1;
+ int xp2, yp2, xs2, ys2;
+ int nimg;
+
+ static int use = 1;
+
+
+
+
+ if(n==1)
+ {
+ m1=VIEW_MAP1;
+ m2=VIEW_MAP2;
+ }
+
+ else
+ {
+
+ if( (r2 >= r1) && (c2 >= c1 ) )
+ {
+ xp1 = (c1 - (min(c1,c2)))+1;
+ xp2 = (c2 - (c1-xp1));
+ xs2 = (c2 + min((ncols1-c1),(ncols2-c2)))-1;
+ xs1 = (c1 + (xs2 - c2));
+ yp1 = (r1 - (min(r1,r2)))+1;
+ yp2 = (r2 - (r1 - yp1));
+ ys2 = (r2 + min((nrows1-r1),(nrows2-r2)))-1;
+ ys1 = (r1 + (ys2 - r2));
+ }
+ else if( (r2 <= r1) && (c2 <= c1) )
+ {
+ xp2 = (c2 - (min(c2,c1)))+1;
+ xp1 = (c1 - (c2 - xp2));
+ xs1 = (c1 + min((ncols1-c1),(ncols2-c2)))-1;
+ xs2 = (c2 + (xs1 - c1));
+ yp2 = (r2 - min(r2,r1))+1;
+ yp1 = (r1 - (r2 - yp2));
+ ys1 = (r1 + min((nrows1-r1),(nrows2-r2)))-1;
+ ys2 = (r2 + (ys1 - r1));
+ }
+ else if( (r2 >= r1) && (c2 <= c1) )
+ {
+ xp2 = (c2 - min(c2,c1))+1;
+ xp1 = (c1 - (c2 - xp2));
+ xs1 = (c1 + min((ncols1-c1),(ncols2-c2)))-1;
+ xs2 = (c2 + (xs1 - c1));
+ yp1 = (r1 - min(r1,r2))+1;
+ yp2 = (r2 - (r1 - yp1));
+ ys2 = (r2 + min((nrows1-r1),(nrows2-r2)))-1;
+ ys1 = (r1 + (ys2 - r2));
+ }
+ else if( (r2 <= r1) && (c2 >= c1) )
+ {
+ xp1 = (c1 - min(c1,c2))+1;
+ xp2 = (c2 - (c1 - xp1));
+ xs2 = (c2 + min((ncols2-c2),(ncols1-c1)))-1;
+ xs1 = (c1 + (xs2 - c2));
+ yp2 = (r2 - min(r1,r2))+1;
+ yp1 = (r1 - (r2 - yp2));
+ ys1 = (r1 + min((nrows1-r1),(nrows2-r2)))-1;
+ ys2 = (r2 + (ys1 - r1));
+ }
+
+
+ /* overlap_area(): function that extracts a window from the angle-points
+ * top_left (xp1, yp1) and down_right (xs1, ys1)
+ */
+ nimg = 1;
+ overlap_area(xp1, yp1, xs1, ys1, nimg, ncols1, nrows1);
+
+
+ nimg = 2;
+ overlap_area(xp2, yp2, xs2, ys2, nimg, ncols2, nrows2);
+
+
+ m1=VIEW_MAP1_ZOOM;
+ m2=VIEW_MAP2_ZOOM;
+
+ }
+
+
+
+ first_map_R_name=m1->cell.name;
+ second_map_R_name=m2->cell.name;
+
+
+
+
+
+ /* rows & cols of the view in m1 */
+ n_1=m1->cell.head.north;
+ e_1=m1->cell.head.east;
+ s_1=m1->cell.head.south;
+ w_1=m1->cell.head.west;
+ left1 = m1->cell.left;
+ top1 = m1->cell.top;
+
+ r1_1=s_1/m1->cell.ns_res;
+ r1_2=n_1/m1->cell.ns_res;
+ c1_1=w_1/m1->cell.ew_res;
+ c1_2=e_1/m1->cell.ew_res;
+
+ nrows1=r1_2-r1_1;
+ ncols1=c1_2-c1_1;
+
+
+ /* rows & cols of the view in m2 */
+ n_2=m2->cell.head.north;
+ e_2=m2->cell.head.east;
+ s_2=m2->cell.head.south;
+ w_2=m2->cell.head.west;
+ left2 = m2->cell.left;
+ top2 = m2->cell.top;
+
+ r2_1=s_2/m2->cell.ns_res;
+ r2_2=n_2/m2->cell.ns_res;
+ c2_1=w_2/m2->cell.ew_res;
+ c2_2=e_2/m2->cell.ew_res;
+
+ nrows2=r2_2-r2_1;
+ ncols2=c2_2-c2_1;
+
+
+ if(n==1)
+ {
+ nrows1_img = nrows1;
+ ncols1_img = ncols1;
+ nrows2_img = nrows2;
+ ncols2_img = ncols2;
+ }
+
+
+ /* Initialize the GIS calls */
+ module = G_define_module();
+ module->description = "Fine registration of two stereo images";
+
+ /* Load environmental vars*/
+ group_LOCATION_NAME=buf;
+ group_LOCATION_NAME=G_getenv("LOCATION_NAME");
+ group_GISDBASE=buf;
+ group_GISDBASE=G_getenv("GISDBASE");
+ group_MAPSET=buf;
+ group_MAPSET=G_getenv("MAPSET");
+
+
+ if(n==1)
+ {
+
+ strcpy (name1_initial,first_map_R_name);
+ strcpy (name2_initial,second_map_R_name);
+ strcpy (mapset_initial,group_MAPSET);
+
+ }
+
+
+ /* Correlation parameters */
+ if(n==1)
+ {
+
+ if(ncols1 <= nrows1)
+ {
+ search_window_dim1 = ncols1;
+ }
+ else
+ {
+ search_window_dim1 = nrows1;
+ }
+
+ if(ncols2 <= nrows2)
+ {
+ search_window_dim2 = ncols2;
+ }
+ else
+ {
+ search_window_dim2 = nrows2;
+ }
+
+
+
+ if(search_window_dim1 <= search_window_dim2)
+ {
+ search_window_dim = search_window_dim1;
+ }
+ else
+ {
+ search_window_dim = search_window_dim2;
+ }
+ }
+
+
+ else if(n==2)
+ {
+ correlation_window_dim=((ncols1/10+nrows1/10)/4);
+
+
+
+ if(n_points==1)
+ {
+
+ K=((ncols1/4+nrows1/4)/3);
+ search_window_dim = (correlation_window_dim + K);
+ n_points = 0;
+
+ }
+ else
+ {
+
+ K=((ncols1/4+nrows1/4)/8);
+ search_window_dim = G_math_max_pow2(correlation_window_dim + K);
+
+ }
+
+
+
+ search_jump=search_window_dim / 2;
+ }
+
+
+
+
+ group_name=group.name;
+ squared_search_window_dim=search_window_dim*search_window_dim;
+
+
+ if(n==1)
+ {
+ Menu_msg ("Loading first image...");
+ }
+
+ else
+ {
+ Menu_msg ("Loading first overlapping_image...");
+ }
+
+ /* Open first real map*/
+
+ if((first_map_R_mapset = G_find_cell2(first_map_R_name, "")) == NULL)
+ {
+ sprintf(buf,"Raster map [%s] not available",first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+
+ if((first_map_R_fd = G_open_cell_old(first_map_R_name,
+ first_map_R_mapset)) < 0)
+ {
+ sprintf(buf,"Error opening raster map [%s]", first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+ /* Set region to first map definition region < m1 > */
+ G_get_cellhd (first_map_R_name, first_map_R_mapset, &cellhd1);
+ G_set_window(&cellhd1);
+ h1_r=cellhd1.rows;
+ h1_c=cellhd1.cols;
+
+
+
+ /* Memory allocation for the first overlapping_map */
+
+ mat1 = (DCELL **) G_calloc(nrows1,sizeof(DCELL *));
+ for(r=0;rcell.ns_res;
+ cellhd1.south=r1_1*m1->cell.ns_res;
+ cellhd1.east=c1_2*m1->cell.ew_res;
+ cellhd1.west=c1_1*m1->cell.ew_res;
+
+ /* Set cellhd2 to overlapping_map_2 */
+ cellhd2.rows=nrows2;
+ cellhd2.cols=ncols2;
+ cellhd2.north=r2_2*m2->cell.ns_res;
+ cellhd2.south=r1_1*m2->cell.ns_res;
+ cellhd2.east=c2_2*m2->cell.ew_res;
+ cellhd2.west=c2_1*m2->cell.ew_res;
+
+ /* Set windows to cellhd1 */
+ G_set_window(&cellhd1);
+
+
+
+ /******************************************/
+ /* function --> Search_correlation_points */
+ /******************************************/
+ Search_correlation_points(mat1, mat2,
+ search_window_dim,
+ squared_search_window_dim,
+ search_jump,group_name, nrows1, ncols1,
+ search_window, r1_2, c1_1, r2_2, c2_1,
+ h1_r, h2_r, h1_c, h2_c, nrows2, ncols2, n );
+
+
+
+
+ sprintf(file_name,"%s/%s/%s/group/%s/TARGET",group_GISDBASE,
+ group_LOCATION_NAME, group_MAPSET,group_name);
+ fp = fopen(file_name,"w");
+ fprintf(fp,"%s\n%s\n",group_LOCATION_NAME,group_MAPSET);
+ fclose(fp);
+
+
+ if(n==2)
+ {
+
+ G_get_cellhd (name1, mapset, &cellhd1);
+ G_adjust_window_to_box (&cellhd1, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows, VIEW_MAP1->ncols);
+ Configure_view (VIEW_MAP1, name1, mapset, cellhd1.ns_res, cellhd1.ew_res);
+ drawcell(VIEW_MAP1);
+ display_points(1);
+ R_flush();
+ Curses_clear_window (PROMPT_WINDOW);
+
+
+ G_get_cellhd (name2, mapset, &cellhd2);
+ G_adjust_window_to_box (&cellhd2, &VIEW_MAP2->cell.head, VIEW_MAP2->nrows, VIEW_MAP2->ncols);
+ Configure_view (VIEW_MAP2, name2, mapset, cellhd2.ns_res, cellhd2.ew_res);
+ drawcell(VIEW_MAP2);
+ display_points(1);
+ R_flush();
+ Curses_clear_window (PROMPT_WINDOW);
+
+ nimg = 1;
+ overlap_area(xp1, yp1, xs1, ys1, nimg, ncols1_img, nrows1_img);
+
+ nimg = 2;
+ overlap_area(xp2, yp2, xs2, ys2, nimg, ncols2_img, nrows2_img);
+
+
+ }
+
+
+
+ select_current_env ();
+
+
+ display_points_in_view_diff_color (VIEW_MAP1, 1,
+ sPoints.e1, sPoints.n1,
+ sPoints.status, sPoints.count);
+
+
+ display_points_in_view_diff_color (VIEW_MAP2, 1,
+ sPoints.e2, sPoints.n2,
+ sPoints.status, sPoints.count);
+
+
+
+
+ display_points_in_view_diff_color (VIEW_MAP1_ZOOM, 1,
+ sPoints.e1, sPoints.n1,
+ sPoints.status, sPoints.count);
+
+
+
+ display_points_in_view_diff_color (VIEW_MAP2_ZOOM, 1,
+ sPoints.e2, sPoints.n2,
+ sPoints.status, sPoints.count);
+
+ R_flush();
+
+
+
+ if(n==2)
+ {
+
+ static Objects objects[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" STORE POINTS IN FILE ",store_points,&use),
+ MENU(" TRY AGAIN ",try_again,&use),
+ INFO(" ",&use),
+ MENU(" rms-th ",change_rms_th,&use),
+ MENU(" Auto-Exclusion GCPs ",auto_exclusion,&use),
+ {0}
+ };
+
+ Input_pointer (objects);
+
+
+ return 0;
+ }
+
+
+
+
+
+ /* Free memory */
+
+ free( rowbuf1_R);
+ free( rowbuf2_R);
+
+
+ for(r=0;r cross-correlation at differnet lag
+ between the two orig. (complex) windows */
+ fft(1,fft_prod_con,squared_search_window_dim,search_window_dim,
+ search_window_dim);
+
+
+
+
+ /* Search the lag coresponding to the maximum correlation */
+ cc = 0.0;
+
+ for(i=0;i cc)
+ {
+ cc = fft_prod_con[0][i];
+ tmp_r=i/search_window_dim;
+ tmp_c=i%search_window_dim;
+
+ }
+ }
+
+
+
+
+ /* Get coordinates of "ending" point */
+ if((tmp_r <= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c1 - tmp_c,&cellhd2) + dist_c;
+ north2 = G_row_to_northing((double) r1 - tmp_r,&cellhd2) + dist_r;
+
+ }
+ if((tmp_r <= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c1 - (tmp_c-search_window_dim-1),&cellhd2) + dist_c;
+ north2 = G_row_to_northing((double) r1 - tmp_r,&cellhd2) + dist_r;
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c1 - tmp_c,&cellhd2) + dist_c;
+ north2 = G_row_to_northing((double) r1 - (tmp_r-search_window_dim-1),&cellhd2) + dist_r;
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c1 - (tmp_c-search_window_dim-1),&cellhd2) + dist_c;
+ north2 = G_row_to_northing((double) r1 - (tmp_r-search_window_dim-1),&cellhd2) + dist_r;
+
+ }
+
+
+
+ r2 = G_northing_to_row(north2,&cellhd2);
+ c2 = G_easting_to_col(east2,&cellhd2);
+
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+ }
+
+
+
+
+ else if(man_op==1)
+ {
+
+ east1 = G_col_to_easting((double) c1, &cellhd1);
+ north1 = G_row_to_northing((double) r1, &cellhd1);
+
+
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+
+
+
+ R_standard_color (BLUE);
+ display_one_point(VIEW_MAP1,east1,north1);
+
+
+ manual_op1();
+
+
+ east2 = e_man2;
+ north2 = n_man2;
+
+
+ r2 = G_northing_to_row(north2,&cellhd2);
+ c2 = G_easting_to_col(east2,&cellhd2);
+
+
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+
+ display_points_in_view_diff_color (VIEW_MAP2, 1,
+ sPoints.e2, sPoints.n2,
+ sPoints.status, sPoints.count);
+
+
+
+ R_flush();
+
+
+ }
+
+
+
+
+ /* Fill the POINTS file*/
+ sPoints.status[sPoints.count-1] = 1;
+ sPoints.count += 1;
+ sPoints.e1=(double *)G_realloc(sPoints.e1,sPoints.count*sizeof(double));
+ sPoints.n1=(double *)G_realloc(sPoints.n1,sPoints.count*sizeof(double));
+ sPoints.e2=(double *)G_realloc(sPoints.e2,sPoints.count*sizeof(double));
+ sPoints.n2=(double *)G_realloc(sPoints.n2,sPoints.count*sizeof(double));
+ sPoints.status=(int *)G_realloc(sPoints.status,sPoints.count*sizeof(int));
+
+
+ }
+
+
+ else if( (n==1) && (man_m_s_op==1) )
+ {
+ manual_m_s_op1();
+
+ east1 = e_man1;
+ north1 = n_man1;
+
+ r1 = G_northing_to_row(north1,&cellhd1);
+ c1 = G_easting_to_col(east1,&cellhd1);
+
+
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+
+
+ R_standard_color (BLUE);
+ display_one_point(VIEW_MAP1,east1,north1);
+
+
+
+ manual_op1();
+
+
+ east2 = e_man2;
+ north2 = n_man2;
+
+
+ r2 = G_northing_to_row(north2,&cellhd2);
+ c2 = G_easting_to_col(east2,&cellhd2);
+
+
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+
+
+ display_points_in_view_diff_color (VIEW_MAP2, 1,
+ sPoints.e2, sPoints.n2,
+ sPoints.status, sPoints.count);
+
+
+
+ R_flush();
+
+
+ /* Fill the POINTS file*/
+ sPoints.status[sPoints.count-1] = 1;
+ sPoints.count += 1;
+ sPoints.e1=(double *)G_realloc(sPoints.e1,sPoints.count*sizeof(double));
+ sPoints.n1=(double *)G_realloc(sPoints.n1,sPoints.count*sizeof(double));
+ sPoints.e2=(double *)G_realloc(sPoints.e2,sPoints.count*sizeof(double));
+ sPoints.n2=(double *)G_realloc(sPoints.n2,sPoints.count*sizeof(double));
+ sPoints.status=(int *)G_realloc(sPoints.status,sPoints.count*sizeof(int));
+
+
+
+ }
+
+
+
+
+ else
+ {
+
+
+ /*Begin computation*/
+ search_border = search_window_dim / 2;
+
+ for(r = search_border; r < dim_win_r - search_border; r += search_jump)
+ {
+ for(c = search_border; c < dim_win_c - search_border; c += search_jump)
+ {
+
+ /* Reinizialize fft vectors */
+
+ for(i=0;i=nrows2)||(c-search_border+2*search_border>=ncols2))
+ {
+ if (sPoints.count<=1)
+ {
+ Menu_msg("DEFINE A NEW REGION.");
+ sleep(3);
+ pause;
+ }
+ return 0;
+ }
+
+ Extract_portion_of_double_matrix(r,c,search_border,search_border,
+ mat2_R,search_window);
+ mean = 0.0;
+ for(i=0;i cross-correlation at differnet lag
+ between the two orig. (complex) windows */
+ fft(1,fft_prod_con,squared_search_window_dim,search_window_dim,
+ search_window_dim);
+
+
+
+
+
+ /* Search the lag coresponding to the maximum correlation */
+ cc = 0.0;
+
+ for(i=0;i cc)
+ {
+ cc = fft_prod_con[0][i];
+ tmp_r=i/search_window_dim;
+ tmp_c=i%search_window_dim;
+
+ }
+ }
+
+ /* Get coordinates of "ending" point */
+ if((tmp_r <= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r <= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+
+
+
+ /* Fill the POINTS file*/
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+
+ sPoints.status[sPoints.count-1] = 1;
+ sPoints.count += 1;
+ sPoints.e1=(double *)G_realloc(sPoints.e1,sPoints.count*sizeof(double));
+ sPoints.n1=(double *)G_realloc(sPoints.n1,sPoints.count*sizeof(double));
+ sPoints.e2=(double *)G_realloc(sPoints.e2,sPoints.count*sizeof(double));
+ sPoints.n2=(double *)G_realloc(sPoints.n2,sPoints.count*sizeof(double));
+ sPoints.status=(int *)G_realloc(sPoints.status,sPoints.count*sizeof(int));
+ }
+ G_percent (r,dim_win_r, 1);
+ }
+
+
+
+ }
+
+}
+
+void Extract_portion_of_double_matrix(int r,int c,int br,int bc,DCELL **mat,DCELL **wind)
+ /*
+ extract a squared portion of a matrix mat
+ given a the indeces of the center [r,c]
+ and the semilength of the borders [br,bc]
+ Output to array wind
+ */
+{
+ int i,j;
+ for(i=0;(i <2*br);i++)
+ for(j = 0;(j <2*bc);j++)
+ {
+ wind[i][j] = mat[r - br + i][c - bc +j];
+ }
+}
+
+
+
+
+
+
+
+static int less_GCPs()
+{
+
+ n_points = 1;
+
+ return 0;
+}
+
+
+
+
+
+static int manual_op()
+{
+ man_op = 1;
+
+ n=1;
+
+ Extract_matrix();
+
+ return 0;
+}
+
+
+
+
+static int manual_op1()
+{
+
+ static int use = 1;
+
+
+ static Objects objects[] =
+ {
+ INFO(" Mark on the second img the Overlap-Point ",&use),
+ OTHER(mark_op, &use),
+ {0}
+ };
+
+ Input_pointer (objects);
+ Menu_msg ("");
+
+
+
+ return 0;
+
+
+}
+
+
+
+
+
+static int mark_op(int x,int y,int button)
+{
+
+ static int use = 1;
+
+ if (button != 1)
+ return where (x,y);
+
+ if (VIEW_MAP2->cell.configured && In_view (VIEW_MAP2, x, y))
+ mark_point_op(VIEW_MAP2, x, y);
+
+ else
+ return 0;
+
+ return -1 ; /* return but don't quit */
+}
+
+
+
+
+static int mark_point_op (View *view,int x, int y)
+{
+
+ /* convert x,y to east,north at center of cell */
+ c2= view_to_col (view, x);
+ e_man2 = col_to_easting (&view->cell.head, c2, 0.5);
+ r2= view_to_row (view, y);
+ n_man2 = row_to_northing (&view->cell.head, r2, 0.5);
+
+
+
+ return 0 ;
+
+
+}
+
+
+
+static int manual_m_s_op()
+{
+ man_m_s_op = 1;
+
+ n=1;
+
+ Extract_matrix();
+
+
+ return 0;
+}
+
+
+static int manual_m_s_op1()
+{
+
+ static int use = 1;
+
+
+ static Objects objects[] =
+ {
+ INFO(" Mark on the first img the Overlap-Point ",&use),
+ OTHER(mark_m_s_op, &use),
+ {0}
+ };
+
+ Input_pointer (objects);
+ Menu_msg ("");
+
+
+ return 0;
+}
+
+
+static int mark_m_s_op(int x,int y,int button)
+{
+
+ static int use = 1;
+
+ if (button != 1)
+ return where (x,y);
+
+ if (VIEW_MAP1->cell.configured && In_view (VIEW_MAP1, x, y))
+ mark_point_m_s_op(VIEW_MAP1, x, y);
+
+ else
+ return 0;
+
+ return -1 ; /* return but don't quit */
+}
+
+
+
+
+static int mark_point_m_s_op (View *view,int x, int y)
+{
+
+ /* convert x,y to east,north at center of cell */
+ c1= view_to_col (view, x);
+ e_man1 = col_to_easting (&view->cell.head, c1, 0.5);
+ r1= view_to_row (view, y);
+ n_man1 = row_to_northing (&view->cell.head, r1, 0.5);
+
+
+
+ return 0 ;
+
+
+}
+
+
+
+
+static int central()
+{
+ n=1;
+ pos_point = 0;
+ man_op=0;
+
+ Extract_matrix();
+
+ return 0;
+
+}
+
+
+static int shift1()
+{
+ double nn_1,ee_1,ss_1,ww_1,rr1_1,rr1_2,cc1_1,cc1_2,nnrows1,nncols1;
+ int shift1;
+
+ nn_1=VIEW_MAP1->cell.head.north;
+ ee_1=VIEW_MAP1->cell.head.east;
+ ss_1=VIEW_MAP1->cell.head.south;
+ ww_1=VIEW_MAP1->cell.head.west;
+
+ rr1_1=ss_1/VIEW_MAP1->cell.ns_res;
+ rr1_2=nn_1/VIEW_MAP1->cell.ns_res;
+ cc1_1=ww_1/VIEW_MAP1->cell.ew_res;
+ cc1_2=ee_1/VIEW_MAP1->cell.ew_res;
+
+ nnrows1=rr1_2-rr1_1;
+ nncols1=cc1_2-cc1_1;
+
+
+
+ shift1 = (((nnrows1 + nncols1)/2)/100)*5;
+
+ switch (pos_point)
+ {
+
+ case 1: dist = shift1;
+ dist_r = -shift1;
+ dist_c = 0;
+ break;
+ case 2: dist = shift1;
+ dist_r = shift1;
+ dist_c = 0;
+ break;
+ case 3: dist = shift1;
+ dist_c = shift1;
+ dist_r = 0;
+ break;
+ case 4: dist = shift1;
+ dist_c = -shift1;
+ dist_r = 0;
+ break;
+ }
+
+
+
+ Extract_matrix();
+
+ return 0;
+}
+
+
+
+
+static int shift2()
+{
+
+ double nn_1,ee_1,ss_1,ww_1,rr1_1,rr1_2,cc1_1,cc1_2,nnrows1,nncols1;
+ int shift2;
+
+ nn_1=VIEW_MAP1->cell.head.north;
+ ee_1=VIEW_MAP1->cell.head.east;
+ ss_1=VIEW_MAP1->cell.head.south;
+ ww_1=VIEW_MAP1->cell.head.west;
+
+ rr1_1=ss_1/VIEW_MAP1->cell.ns_res;
+ rr1_2=nn_1/VIEW_MAP1->cell.ns_res;
+ cc1_1=ww_1/VIEW_MAP1->cell.ew_res;
+ cc1_2=ee_1/VIEW_MAP1->cell.ew_res;
+
+ nnrows1=rr1_2-rr1_1;
+ nncols1=cc1_2-cc1_1;
+
+
+
+ shift2 = (((nnrows1 + nncols1)/2)/100)*10;
+
+
+
+ switch (pos_point)
+ {
+
+ case 1: dist = shift2;
+ dist_r = -shift2;
+ dist_c = 0;
+ break;
+ case 2: dist = shift2;
+ dist_r = shift2;
+ dist_c = 0;
+ break;
+ case 3: dist = shift2;
+ dist_c = shift2;
+ dist_r = 0;
+ break;
+ case 4: dist = shift2;
+ dist_c = -shift2;
+ dist_r = 0;
+ break;
+ }
+
+
+
+ Extract_matrix();
+
+ return 0;
+}
+
+
+
+
+
+static int top()
+{
+ static int use = 1;
+
+ n=1;
+ pos_point = 1;
+ man_op=0;
+
+ static Objects objects2[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" <-- ",cancel,&use),
+ INFO(" Shift O.P. (% of map) -> ",&use),
+ MENU(" 5% ",shift1,&use),
+ MENU(" 10% ",shift2,&use),
+ {0}
+ };
+
+ Input_pointer (objects2);
+
+
+ return 0;
+
+}
+
+
+
+
+
+static int bottom()
+{
+ static int use = 1;
+
+ n=1;
+ pos_point = 2;
+ man_op=0;
+
+ static Objects objects3[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" <-- ",cancel,&use),
+ INFO(" Shift O.P. (% of map) -> ",&use),
+ MENU(" 5% ",shift1,&use),
+ MENU(" 10% ",shift2,&use),
+ {0}
+ };
+
+ Input_pointer (objects3);
+
+
+ return 0;
+
+}
+
+
+
+static int left()
+{
+ static int use = 1;
+
+ n=1;
+ pos_point = 3;
+ man_op=0;
+
+ static Objects objects4[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" <-- ",cancel,&use),
+ INFO(" Shift O.P. (% of map) -> ",&use),
+ MENU(" 5% ",shift1,&use),
+ MENU(" 10% ",shift2,&use),
+ {0}
+ };
+
+ Input_pointer (objects4);
+
+
+ return 0;
+
+}
+
+
+
+static int right()
+{
+ static int use = 1;
+
+ n=1;
+ pos_point = 4;
+ man_op=0;
+
+ static Objects objects5[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" <-- ",cancel,&use),
+ INFO(" Shift O.P. (% of map) -> ",&use),
+ MENU(" 5% ",shift1,&use),
+ MENU(" 10% ",shift2,&use),
+ {0}
+ };
+
+ Input_pointer (objects5);
+
+
+ return 0;
+
+}
+
+
+
+
+
+
+static int try_again()
+{
+
+ static int use = 1;
+
+ G_get_cellhd (name1_initial, mapset_initial, &cellhd1);
+ G_adjust_window_to_box (&cellhd1, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows, VIEW_MAP1->ncols);
+ Configure_view (VIEW_MAP1, name1_initial, mapset_initial, cellhd1.ns_res, cellhd1.ew_res);
+ drawcell(VIEW_MAP1);
+ display_points(1);
+ R_flush();
+ Curses_clear_window (PROMPT_WINDOW);
+
+ Erase_view (VIEW_MAP1_ZOOM);
+
+
+ G_get_cellhd (name2_initial, mapset_initial, &cellhd2);
+ G_adjust_window_to_box (&cellhd2, &VIEW_MAP2->cell.head, VIEW_MAP2->nrows, VIEW_MAP2->ncols);
+ Configure_view (VIEW_MAP2, name2_initial, mapset_initial, cellhd2.ns_res, cellhd2.ew_res);
+ drawcell(VIEW_MAP2);
+ display_points(1);
+ R_flush();
+ Curses_clear_window (PROMPT_WINDOW);
+
+ Erase_view (VIEW_MAP2_ZOOM);
+
+
+ static Objects objects3[]=
+ {
+
+
+ MENU(" MAIN MENU ",cancel,&use),
+ INFO(" O.P. -> ",&use),
+ MENU(" Central ",central,&use),
+ MENU(" Top ",top,&use),
+ MENU(" Bottom ",bottom,&use),
+ MENU(" Left ",left,&use),
+ MENU(" Right ",right,&use),
+ INFO(" ",&use),
+ MENU(" LESS GCPs ",less_GCPs,&use),
+ MENU(" Mark Slave-O.P. ",manual_op,&use),
+ MENU(" Mark M&S-O.P. ",manual_m_s_op,&use),
+ {0}
+ };
+
+
+ Input_pointer (objects3);
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+static int store_points()
+{
+
+ int i;
+
+
+ sPoints.count -= 1;
+ if(sPoints.count > 0)
+ {
+
+ sprintf(file_name,"%s/%s/%s/group/%s/POINTS",group_GISDBASE,
+ group_LOCATION_NAME,group_MAPSET,group_name);
+
+ fp = fopen(file_name,"w");
+ fprintf (fp,"# %7s %15s %15s %15s %9s status\n","",
+ "provaimage","","target","");
+ fprintf (fp,"# %15s %15s %15s %15s (1=ok)\n",
+ "east","north","east","north");
+ fprintf (fp,"#\n");
+
+ for (i = 1; i < sPoints.count; i++) /* i=1 because the sPoints[0] is the O.P. */
+ if ( sPoints.status[i] != -1)
+ fprintf (fp, " %15f %15f %15f %15f %4d\n",
+ sPoints.e1[i], sPoints.n1[i], sPoints.e2[i], sPoints.n2[i], sPoints.status[i]);
+
+
+ fclose (fp);
+ }
+
+
+
+ /* Load new control points */
+
+ for (i = 1; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ I_new_control_point (&group.points,sPoints.e1[i], sPoints.n1[i],
+ sPoints.e2[i], sPoints.n2[i], sPoints.status[i] );
+
+
+
+ m=1; /* To directly return to the main menu */
+
+
+ return 0;
+
+}
+
+
+
+
+
+static int main_menu()
+{
+ m=1;
+
+ return 0;
+}
+
+
+static int
+cancel (void)
+{
+ return -1;
+}
+
+
+
+
+
+
+static int change_rms_th()
+{
+ static int use = 1;
+
+ static Objects objects[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" <-- ",cancel,&use),
+ INFO(" ",&use),
+ MENU(" 1 ",th_1,&use),
+ MENU(" 2 ",th_2,&use),
+ MENU(" 3 ",th_3,&use),
+ MENU(" 4 ",th_4,&use),
+ MENU(" 5 ",th_5,&use),
+ MENU(" OTHER ",other_th,&use),
+ /*
+ OPTION(" 1 ", 2, &after_OPTION_out),
+ OPTION(" 2 ", 2, &temp_th_2),
+ OPTION(" 3 ", 2, &temp_th_3),
+ OPTION(" 4 ", 2, &temp_th_4),
+ OPTION(" 5 ", 2, &temp_th_5),*/
+ {0}
+ };
+
+
+
+ Input_pointer (objects);
+
+
+ return 0;
+}
+
+
+
+static int after_th()
+{
+ static int use = 1;
+
+
+ static Objects objects3[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" STORE POINTS IN FILE ",store_points,&use),
+ MENU(" TRY AGAIN ",try_again,&use),
+ INFO(" ",&use),
+ MENU(" rms-th ",change_rms_th,&use),
+ MENU(" Auto-Exclusion GCPs ",auto_exclusion,&use),
+ {0}
+ };
+
+
+ Input_pointer (objects3);
+
+
+
+ return 0;
+}
+
+
+
+
+
+
+static int th_1()
+{
+ th=1;
+
+ after_th();
+
+ return 0;
+}
+
+
+static int th_2()
+{
+ th=2;
+
+ after_th();
+
+ return 0;
+}
+
+
+static int th_3()
+{
+ th=3;
+
+ after_th();
+
+ return 0;
+}
+
+
+static int th_4()
+{
+ th=4;
+
+ after_th();
+
+ return 0;
+}
+
+static int th_5()
+{
+ th=5;
+
+ after_th();
+
+ return 0;
+}
+
+
+
+static int other_th()
+{
+ char buf[100];
+ double tmp_th;
+
+ G_clear_screen();
+
+ while(1)
+ {
+ Curses_prompt_gets ("Insert the rms-threshold desired: ", buf);
+ sscanf (buf, "%lf", &tmp_th);
+ if(tmp_th!=0) break;
+
+ }
+
+ th = tmp_th;
+
+ after_th();
+
+ return 0;
+}
+
+
+
+
+
+int auto_exclusion(void)
+{
+ int k;
+ int i;
+ static int use = 1;
+
+ sPoints.count = sPoints.count -1;
+
+ /* Load new control points */
+
+ for (i = 1; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ I_new_control_point (&group.points,sPoints.e1[i], sPoints.n1[i],
+ sPoints.e2[i], sPoints.n2[i], sPoints.status[i] );
+
+
+
+
+ first_point = 0;
+
+ /* allocate predicted values */
+ xres = (double *) G_calloc (group.points.count, sizeof (double));
+ yres = (double *) G_calloc (group.points.count, sizeof (double));
+ gnd = (double *) G_calloc (group.points.count, sizeof (double));
+
+
+ compute_transformation();
+
+
+ while(rms>=th)
+ {
+ for(k=0; k < group.points.count; k++)
+ {
+
+ if(group.equation_stat > 0 && group.points.status[k]==1)
+ {
+
+ if (k == xmax || k == ymax || k == gmax)
+ {
+ group.points.status[k] = 0;
+ }
+ }
+ compute_transformation();
+
+ }
+ }
+ display_points(1);
+
+
+
+ static Objects objects[]=
+ {
+ MENU(" MAIN MENU ",main_menu,&use),
+ MENU(" ANALYZE & STORE ",pre_analyze,&use),
+ {0}
+ };
+
+ Input_pointer (objects);
+
+
+ free (xres); free (yres); free (gnd);
+
+ return 0;
+}
+
+
+
+static int pre_analyze()
+{
+
+ analyze();
+
+ m=1;
+
+ return 0;
+}
+
+
+
+
+
+
+static int compute_transformation (void)
+{
+ int n, count;
+ double d,d1,d2,sum;
+ double e1, e2, n1, n2;
+ double t1, t2, u1, u2;
+ double xval, yval, gval;
+ double tval, uval, lgval;
+
+ xmax = ymax = gmax = 0;
+ xval = yval = gval = 0.0;
+
+ Compute_equation();
+
+ /* compute the row,col error plus ground error
+ * keep track of largest and second largest error
+ */
+ sum = 0.0;
+ rms = 0.0;
+ count = 0;
+ for (n = 0; n < group.points.count && group.equation_stat>0; n++)
+ {
+ if (group.points.status[n] !=1) continue;
+ count++;
+ georef (group.points.e2[n], group.points.n2[n], &e1, &n1, group.E21, group.N21);
+ georef (group.points.e1[n], group.points.n1[n], &e2, &n2, group.E12, group.N12);
+
+ if((d = xres[n] = e1-group.points.e1[n]) < 0)
+ d = -d;
+ if (d > xval)
+ {
+ xmax = n;
+ xval = d;
+ }
+
+ if ((d = yres[n] = n1-group.points.n1[n]) < 0)
+ d = -d;
+ if (d > yval)
+ {
+ ymax = n;
+ yval = d;
+ }
+
+ /* compute ground error (ie along diagonal) */
+ d1 = e2 - group.points.e2[n];
+ d2 = n2 - group.points.n2[n];
+ d = d1*d1 + d2*d2;
+ sum += d; /* add it to rms sum, before taking sqrt */
+ d = sqrt(d);
+ gnd[n] = d;
+ if (d > gval) /* is this one the max? */
+ {
+ gmax = n;
+ gval = d;
+ }
+
+ }
+ /* compute overall rms error */
+ if (count)
+ rms = sqrt (sum/count);
+
+
+ return 0;
+}
+
+
+
+
+
+
Property changes on: trunk/grassaddons/i.points.auto/find_points.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/find_points_semi.c
===================================================================
--- trunk/grassaddons/i.points.auto/find_points_semi.c (rev 0)
+++ trunk/grassaddons/i.points.auto/find_points_semi.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,778 @@
+#include
+#include
+#include
+#include
+
+#include
+#ifdef HAVE_FFTW_H
+#include
+#endif
+#ifdef HAVE_DFFTW_H
+#include
+#endif
+
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+#ifdef NULL_VALUE
+#undef NULL_VALUE
+#endif
+#define NULL_VALUE -1
+
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+double *fft_first_s[2];
+double *fft_second_s[2];
+double *fft_prod_con_s[2];
+
+View *ms1, *ms2;
+
+void Extract_matrix_semi()
+{
+ struct GModule *module;
+ struct Control_Points *cp1;
+ char buf[256];
+ char *s;
+ int rows, cols;
+ char *first_map_R_mapset;
+ char *first_map_R_name;
+ int first_map_R_fd;
+ char *second_map_R_mapset;
+ char *second_map_R_name;
+ int second_map_R_fd;
+
+ int K;
+
+ int correlation_window_dim;
+ int search_window_dim;
+
+ int squared_search_window_dim;
+ int search_jump;
+
+ int ncols1, ncols2, nrows1, nrows2;
+ int left1, top1, left2, top2;
+ int repeat;
+
+ int n_1, e_1, n_2, e_2, s_1, s_2, w_1, w_2;
+ int r1_1, r1_2, r2_1, r2_2;
+ int c1_1, c1_2, c2_1, c2_2;
+
+ int i;
+
+ int h1_r;
+ int h1_c;
+ int h2_r;
+ int h2_c;
+
+
+ char *group_name;
+ char *group_MAPSET;
+ char *group_LOCATION_NAME;
+ char *group_GISDBASE;
+ DCELL *rowbuf1_R;
+ DCELL *tf1_R;
+ DCELL *rowbuf2_R;
+ DCELL *tf2_R;
+ double **search_window;
+ double **mat1,**mat2;
+ int r,c;
+ int search_border;
+ int q;
+ int p1;
+ int dim_win_c, dim_win_r;
+ char first_sites[500];
+ char second_sites[500];
+ char file_name[500];
+ char file_name_old[500];
+ FILE *first_fp;
+ FILE *second_fp;
+ FILE *fp;
+ FILE *fp_old;
+
+
+
+ /* Read VIEW_MAP1_ZOOM & VIEW_MAP2_ZOOM informations */
+
+
+ ms1=VIEW_MAP1_ZOOM;
+ ms2=VIEW_MAP2_ZOOM;
+
+ first_map_R_name=ms1->cell.name;
+ second_map_R_name=ms2->cell.name;
+
+ /* rows & cols of VIEW_MAP1_ZOOM */
+ n_1=ms1->cell.head.north;
+ e_1=ms1->cell.head.east;
+ s_1=ms1->cell.head.south;
+ w_1=ms1->cell.head.west;
+ left1 = ms1->cell.left;
+ top1 = ms1->cell.top;
+
+ r1_1=s_1/ms1->cell.ns_res;
+ r1_2=n_1/ms1->cell.ns_res;
+ c1_1=w_1/ms1->cell.ew_res;
+ c1_2=e_1/ms1->cell.ew_res;
+
+ nrows1=r1_2-r1_1;
+ ncols1=c1_2-c1_1;
+
+
+ /* rows & cols of VIEW_MAP2_ZOOM */
+ n_2=ms2->cell.head.north;
+ e_2=ms2->cell.head.east;
+ s_2=ms2->cell.head.south;
+ w_2=ms2->cell.head.west;
+ left2 = ms2->cell.left;
+ top2 = ms2->cell.top;
+
+ r2_1=s_2/ms2->cell.ns_res;
+ r2_2=n_2/ms2->cell.ns_res;
+ c2_1=w_2/ms2->cell.ew_res;
+ c2_2=e_2/ms2->cell.ew_res;
+
+ nrows2=r2_2-r2_1;
+ ncols2=c2_2-c2_1;
+
+
+
+ /* Initialize the GIS calls */
+ module = G_define_module();
+ module->description = "Fine registration of two stereo images";
+
+ /* Load environmental vars*/
+ group_LOCATION_NAME=buf;
+ group_LOCATION_NAME=G_getenv("LOCATION_NAME");
+ group_GISDBASE=buf;
+ group_GISDBASE=G_getenv("GISDBASE");
+ group_MAPSET=buf;
+ group_MAPSET=G_getenv("MAPSET");
+
+
+ /* Correlation parameters */
+ correlation_window_dim=((ncols1/10+nrows1/10)/2);
+ K=((ncols1/4+nrows1/4)/2);
+
+ search_window_dim = G_math_max_pow2(correlation_window_dim + K);
+ group_name=group.name;
+ squared_search_window_dim=search_window_dim*search_window_dim;
+ search_jump=search_window_dim / 2;
+
+
+
+ Menu_msg ("Loading first zoom_image...");
+
+ /* Open first real map*/
+ if((first_map_R_mapset = G_find_cell2(first_map_R_name, "")) == NULL)
+ {
+ sprintf(buf,"Raster map [%s] not available",first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+
+ if((first_map_R_fd = G_open_cell_old(first_map_R_name,
+ first_map_R_mapset)) < 0)
+ {
+ sprintf(buf,"Error opening raster map [%s]", first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+ /* Set region to first map definition region < ms1 > */
+ G_get_cellhd (first_map_R_name, first_map_R_mapset, &cellhd1);
+ G_set_window(&cellhd1);
+ h1_r=cellhd1.rows;
+ h1_c=cellhd1.cols;
+
+
+
+ /* Memory allocation for zoom_map_1 */
+
+ mat1 = (DCELL **) G_calloc(nrows1,sizeof(DCELL *));
+ for(r=0;rcell.ns_res;
+ cellhd1.south=r1_1*ms1->cell.ns_res;
+ cellhd1.east=c1_2*ms1->cell.ew_res;
+ cellhd1.west=c1_1*ms1->cell.ew_res;
+
+ /* Set cellhd2 to zoom_map_2 */
+ cellhd2.rows=nrows2;
+ cellhd2.cols=ncols2;
+ cellhd2.north=r2_2*ms2->cell.ns_res;
+ cellhd2.south=r1_1*ms2->cell.ns_res;
+ cellhd2.east=c2_2*ms2->cell.ew_res;
+ cellhd2.west=c2_1*ms2->cell.ew_res;
+
+ /* Set windows to cellhd1 */
+ G_set_window(&cellhd1);
+
+
+
+ /******************************************/
+ /* function --> Search_correlation_points */
+ /******************************************/
+ Search_correlation_points_semi(mat1, mat2,
+ search_window_dim,
+ squared_search_window_dim,
+ search_jump,group_name, nrows1, ncols1,
+ search_window, r1_2, c1_1, r2_2, c2_1,
+ h1_r, h2_r, h1_c, h2_c, nrows2, ncols2 );
+
+
+
+
+ /* Build group/POINTS file */
+ sPoints.count -= 1;
+ if(sPoints.count > 0)
+ {
+ sprintf(file_name,"%s/%s/%s/group/%s/POINTS",group_GISDBASE,
+ group_LOCATION_NAME,group_MAPSET,group_name);
+ fp_old = fopen(file_name,"r");
+ if( fp_old==NULL)
+ {
+ q=0;
+ }
+ else
+ {
+ q=1;
+ fclose(fp_old);
+ }
+
+ if (q==0)
+ {
+ fp = fopen(file_name,"a");
+ fprintf (fp,"# %7s %15s %15s %15s %9s status\n","",
+ "image","","target","");
+ fprintf (fp,"# %15s %15s %15s %15s (1=ok)\n",
+ "east","north","east","north");
+ fprintf (fp,"#\n");
+
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ fprintf (fp, " %15f %15f %15f %15f %4d\n",
+ sPoints.e1[i], sPoints.n1[i], sPoints.e2[i], sPoints.n2[i], sPoints.status[i]);
+
+ }
+ if(q==1)
+ {
+ fp = fopen(file_name,"a");
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ fprintf (fp, " %15f %15f %15f %15f %4d\n", sPoints.e1[i], sPoints.n1[i], sPoints.e2[i], sPoints.n2[i], sPoints.status[i]);
+ }
+ fclose (fp);
+ }
+
+ /* Load new control points */
+
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ I_new_control_point (&group.points,sPoints.e1[i], sPoints.n1[i],
+ sPoints.e2[i], sPoints.n2[i], sPoints.status[i] );
+
+ /* Build group/REF file */
+ /*
+ sprintf(file_name,"%s/%s/%s/group/%s/REF",group_GISDBASE,
+ group_LOCATION_NAME, group_MAPSET,group_name);
+ fp = fopen(file_name,"w");
+ fprintf(fp,"%s %s\n",first_map_R_name,first_map_R_mapset);
+
+ fclose(fp);
+ */
+
+ /* Build group/TARGET file */
+ sprintf(file_name,"%s/%s/%s/group/%s/TARGET",group_GISDBASE,
+ group_LOCATION_NAME, group_MAPSET,group_name);
+ fp = fopen(file_name,"w");
+ fprintf(fp,"%s\n%s\n",group_LOCATION_NAME,group_MAPSET);
+ fclose(fp);
+
+ /* Display new points */
+ select_current_env ();
+ display_points_in_view (VIEW_MAP1, 1,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP1_ZOOM, 1,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2, 1,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2_ZOOM, 1,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+ R_flush();
+
+ /* Free memory */
+
+ free( rowbuf1_R);
+ free( rowbuf2_R);
+
+
+ for(r=0;r=nrows2)||(c-search_border+2*search_border>=ncols2))
+ {
+ if (sPoints.count<=1)
+ {
+ Menu_msg("DEFINE A NEW REGION.");
+ sleep(3);
+ pause;
+ }
+ return 0;
+ }
+
+ Extract_portion_of_double_matrix_semi(r,c,search_border,search_border,
+ mat2_R,search_window);
+ mean = 0.0;
+ for(i=0;i cross-correlation at differnet lag
+ between the two orig. (complex) windows */
+ fft(1,fft_prod_con_s,squared_search_window_dim,search_window_dim,
+ search_window_dim);
+
+#ifdef DEBUG
+ for(i=0;i cc)
+ {
+ cc = fft_prod_con_s[0][i];
+ tmp_r=i/search_window_dim;
+ tmp_c=i%search_window_dim;
+
+ }
+ }
+
+ /* Get coordinates of "ending" point */
+ if((tmp_r <= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r <= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+
+
+ /* Fill the POINTS file*/
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+
+ sPoints.status[sPoints.count-1] = 1;
+ sPoints.count += 1;
+ sPoints.e1=(double *)G_realloc(sPoints.e1,sPoints.count*sizeof(double));
+ sPoints.n1=(double *)G_realloc(sPoints.n1,sPoints.count*sizeof(double));
+ sPoints.e2=(double *)G_realloc(sPoints.e2,sPoints.count*sizeof(double));
+ sPoints.n2=(double *)G_realloc(sPoints.n2,sPoints.count*sizeof(double));
+ sPoints.status=(int *)G_realloc(sPoints.status,sPoints.count*sizeof(int));
+ }
+ G_percent (r,dim_win_r, 1);
+ }
+ }
+
+
+void Extract_portion_of_double_matrix_semi(int r,int c,int br,int bc,DCELL **mat,DCELL **wind)
+ /*
+ extract a squared portion of a matrix mat
+ given a the indeces of the center [r,c]
+ and the semilength of the borders [br,bc]
+ Output to array wind
+ */
+{
+ int i,j;
+ for(i=0;(i <2*br);i++)
+ for(j = 0;(j <2*bc);j++)
+ {
+ wind[i][j] = mat[r - br + i][c - bc +j];
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Property changes on: trunk/grassaddons/i.points.auto/find_points_semi.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/georef.c
===================================================================
--- trunk/grassaddons/i.points.auto/georef.c (rev 0)
+++ trunk/grassaddons/i.points.auto/georef.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,326 @@
+#include
+#include "globals.h"
+
+static int floating_exception;
+static void catch(int);
+static double determinant(double,double,
+ double,double,double,double,double,double,double);
+
+void (*sigfpe)();
+
+/* find coefficients A,B,C for e2 = A + B*e1 + C*n1
+ * also compute the reverse equations
+ *
+ * return 0 if no points
+ * -1 if not solvable
+ * 1 if ok
+ *
+ * method is least squares.
+ * the least squares problem reduces to solving the following
+ * system of equations for A,B,C
+ *
+ * s0*A + s1*B + s2*C = x0
+ * s1*A + s3*B + s4*C = x1
+ * s2*A + s4*B + s5*C = x2
+ *
+ * use Cramer's rule
+ *
+ * | x0 s1 s2 | | s0 x0 s2 | | s0 s1 x0 |
+ * | x1 s3 s4 | | s1 x1 s4 | | s1 s3 x1 |
+ * | x2 s4 s5 | | s2 x2 s5 | | s2 s4 x2 |
+ * A = ------------ B = ------------ C = ------------
+ * | s0 s1 s2 | | s0 s1 s2 | | s0 s1 s2 |
+ * | s1 s3 s4 | | s1 s3 s4 | | s1 s3 s4 |
+ * | s2 s4 s5 | | s2 s4 s5 | | s2 s4 s5 |
+ *
+ */
+
+int compute_georef_equations(
+ struct Control_Points *cp,
+ double E12[3], double N12[3], double E21[3], double N21[3])
+{
+ double s0,s1,s2,s3,s4,s5;
+ double x0,x1,x2;
+ double det;
+ int i;
+
+
+ s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ s0 += 1.0;
+ s1 += cp->e1[i];
+ s2 += cp->n1[i];
+ s3 += cp->e1[i] * cp->e1[i];
+ s4 += cp->e1[i] * cp->n1[i];
+ s5 += cp->n1[i] * cp->n1[i];
+ }
+ if (s0 < 0.5) return 0;
+
+ floating_exception = 0;
+ sigfpe = signal (SIGFPE, catch);
+
+/* eastings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ x0 += cp->e2[i];
+ x1 += cp->e1[i] * cp->e2[i];
+ x2 += cp->n1[i] * cp->e2[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ E12[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ E12[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ E12[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* northings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ x0 += cp->n2[i];
+ x1 += cp->e1[i] * cp->n2[i];
+ x2 += cp->n1[i] * cp->n2[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ N12[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ N12[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ N12[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* the inverse equations */
+
+ s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ s0 += 1.0;
+ s1 += cp->e2[i];
+ s2 += cp->n2[i];
+ s3 += cp->e2[i] * cp->e2[i];
+ s4 += cp->e2[i] * cp->n2[i];
+ s5 += cp->n2[i] * cp->n2[i];
+ }
+
+/* eastings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ x0 += cp->e1[i];
+ x1 += cp->e2[i] * cp->e1[i];
+ x2 += cp->n2[i] * cp->e1[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ E21[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ E21[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ E21[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* northings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < cp->count; i++)
+ {
+ if (cp->status[i] != 1)
+ continue;
+ x0 += cp->n1[i];
+ x1 += cp->e2[i] * cp->n1[i];
+ x2 += cp->n2[i] * cp->n1[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ N21[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ N21[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ N21[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+ signal (SIGFPE, sigfpe);
+ return floating_exception ? -1 : 1;
+}
+
+
+int compute_georef_equations_lp (Lines *ln)
+{
+ double s0,s1,s2,s3,s4,s5;
+ double x0,x1,x2;
+ double det;
+ int i;
+
+
+ s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ s0 += 1.0;
+ s1 += ln->t1[i];
+ s2 += ln->u1[i];
+ s3 += ln->t1[i] * ln->t1[i];
+ s4 += ln->t1[i] * ln->u1[i];
+ s5 += ln->u1[i] * ln->u1[i];
+ }
+ if (s0 < 0.5) return 0;
+
+ floating_exception = 0;
+ sigfpe = signal (SIGFPE, catch);
+
+/* eastings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ x0 += ln->t2[i];
+ x1 += ln->t1[i] * ln->t2[i];
+ x2 += ln->u1[i] * ln->t2[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ ln->E12[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ ln->E12[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ ln->E12[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* northings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ x0 += ln->u2[i];
+ x1 += ln->t1[i] * ln->u2[i];
+ x2 += ln->u1[i] * ln->u2[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ ln->N12[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ ln->N12[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ ln->N12[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* the inverse equations */
+
+ s0 = s1 = s2 = s3 = s4 = s5 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ s0 += 1.0;
+ s1 += ln->t2[i];
+ s2 += ln->u2[i];
+ s3 += ln->t2[i] * ln->t2[i];
+ s4 += ln->t2[i] * ln->u2[i];
+ s5 += ln->u2[i] * ln->u2[i];
+ }
+
+/* eastings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ x0 += ln->t1[i];
+ x1 += ln->t2[i] * ln->t1[i];
+ x2 += ln->u2[i] * ln->t1[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ ln->E21[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ ln->E21[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ ln->E21[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+/* northings */
+ x0 = x1 = x2 = 0.0;
+ for (i = 0; i < ln->count; i++)
+ {
+ if (ln->status[i] != 2)
+ continue;
+ x0 += ln->u1[i];
+ x1 += ln->t2[i] * ln->u1[i];
+ x2 += ln->u2[i] * ln->u1[i];
+ }
+
+ det = determinant (s0,s1,s2,s1,s3,s4,s2,s4,s5);
+ if (det == 0.0)
+ {
+ signal (SIGFPE, sigfpe);
+ return -1;
+ }
+ ln->N21[0] = determinant (x0,s1,s2,x1,s3,s4,x2,s4,s5)/det;
+ ln->N21[1] = determinant (s0,x0,s2,s1,x1,s4,s2,x2,s5)/det;
+ ln->N21[2] = determinant (s0,s1,x0,s1,s3,x1,s2,s4,x2)/det;
+
+ signal (SIGFPE, sigfpe);
+ return floating_exception ? -1 : 1;
+}
+
+
+
+static double determinant (
+ double a, double b, double c, double d, double e,
+ double f, double g, double h, double i)
+{
+/* compute determinant of 3x3 matrix
+ * | a b c |
+ * | d e f |
+ * | g h i |
+ */
+ return a * (e*i - f*h) - b * (d*i - f*g) + c * (d*h - e*g) ;
+}
+
+static void catch(int n)
+{
+ floating_exception = 1;
+ signal (n, catch);
+}
+
+int georef (
+ double e1,double n1,
+ double *e2,double *n2,
+ double E[3],double N[3])
+{
+ *e2 = E[0] + E[1] * e1 + E[2] * n1;
+ *n2 = N[0] + N[1] * e1 + N[2] * n1;
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/georef.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/globals.h
===================================================================
--- trunk/grassaddons/i.points.auto/globals.h (rev 0)
+++ trunk/grassaddons/i.points.auto/globals.h 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,85 @@
+#include "defs.h"
+
+#ifndef GLOBAL
+# define GLOBAL extern
+# define INIT(x)
+#else
+# define INIT(x) = x
+#endif
+
+GLOBAL struct Control_Points sPoints;
+GLOBAL struct Cell_head cellhd1;
+GLOBAL struct Cell_head cellhd2;
+
+
+
+/* Variable for the botton "Main-Menu". */
+GLOBAL int m;
+
+GLOBAL int G_get_color();
+
+GLOBAL int SCREEN_TOP;
+GLOBAL int SCREEN_BOTTOM;
+GLOBAL int SCREEN_LEFT;
+GLOBAL int SCREEN_RIGHT;
+
+GLOBAL int correlation_window_dim;
+GLOBAL int K;
+
+GLOBAL Window *INFO_WINDOW;
+GLOBAL Window *MENU_WINDOW;
+GLOBAL Window *PROMPT_WINDOW;
+
+GLOBAL View *VIEW_MAP1;
+GLOBAL View *VIEW_TITLE1;
+GLOBAL View *VIEW_MAP1_ZOOM;
+GLOBAL View *VIEW_TITLE1_ZOOM;
+
+GLOBAL View *VIEW_MAP2;
+GLOBAL View *VIEW_TITLE2;
+GLOBAL View *VIEW_MAP2_ZOOM;
+GLOBAL View *VIEW_TITLE2_ZOOM;
+
+GLOBAL View *VIEW_MENU;
+
+GLOBAL Group group;
+
+GLOBAL char interrupt_char;
+GLOBAL char *tempfile1;
+GLOBAL char *tempfile2;
+GLOBAL char *tempfile3;
+GLOBAL char *digit_points; /* digitizer control points */
+GLOBAL char *digit_results; /* digitizer results */
+GLOBAL int use_digitizer INIT(0); /* is there a digitizer out there? */
+
+/* group file list, target cell,vector files */
+GLOBAL char *group_list INIT(NULL);
+GLOBAL char *cell_list INIT(NULL);
+GLOBAL char *vect_list INIT(NULL);
+
+GLOBAL int from_keyboard INIT(-1); /* input method */
+GLOBAL int from_digitizer INIT(-1);
+GLOBAL int from_screen INIT(-1);
+GLOBAL int from_flag INIT(0);
+
+GLOBAL int dotsize INIT(4);
+
+GLOBAL int THE_COLORS[10];
+#define BLACK THE_COLORS[0]
+#define BLUE THE_COLORS[1]
+#define BROWN THE_COLORS[2]
+#define GREEN THE_COLORS[3]
+#define GREY THE_COLORS[4]
+#define ORANGE THE_COLORS[5]
+#define PURPLE THE_COLORS[6]
+#define RED THE_COLORS[7]
+#define WHITE THE_COLORS[8]
+#define YELLOW THE_COLORS[9]
+
+double row_to_northing();
+double col_to_easting();
+double northing_to_row();
+double easting_to_col();
+
+#undef INIT
+
Property changes on: trunk/grassaddons/i.points.auto/globals.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/graphics.c
===================================================================
--- trunk/grassaddons/i.points.auto/graphics.c (rev 0)
+++ trunk/grassaddons/i.points.auto/graphics.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,149 @@
+#include "globals.h"
+#include "local_proto.h"
+#include
+#include
+
+static View *
+makeview (double bottom, double top, double left, double right)
+{
+ View *view;
+
+ view = (View *) G_malloc (sizeof (View));
+
+ top = 100-top;
+ bottom = 100-bottom;
+
+ view->top = SCREEN_TOP + (SCREEN_BOTTOM - SCREEN_TOP) * top / 100.0 ;
+ view->bottom = SCREEN_TOP + (SCREEN_BOTTOM - SCREEN_TOP) * bottom / 100.0 ;
+ view->left = SCREEN_LEFT + (SCREEN_RIGHT - SCREEN_LEFT) * left / 100.0 ;
+ view->right = SCREEN_LEFT + (SCREEN_RIGHT - SCREEN_LEFT) * right / 100.0 ;
+
+ if (view->top < SCREEN_TOP)
+ view->top = SCREEN_TOP;
+ if (view->bottom > SCREEN_BOTTOM)
+ view->bottom = SCREEN_BOTTOM;
+ if (view->left < SCREEN_LEFT)
+ view->left = SCREEN_LEFT;
+ if (view->right > SCREEN_RIGHT)
+ view->right = SCREEN_RIGHT;
+
+ Outline_box (view->top, view->bottom, view->left, view->right);
+
+ view->top++;
+ view->bottom--;
+ view->left++;
+ view->right--;
+
+ view->nrows = view->bottom - view->top + 1;
+ view->ncols = view->right - view->left + 1;
+ view->cell.configured = 0;
+
+ return view;
+}
+
+int
+Init_graphics (void)
+{
+ D_full_screen();
+
+
+ SCREEN_TOP = R_screen_top();
+ SCREEN_BOTTOM = R_screen_bot();
+ SCREEN_LEFT = R_screen_left();
+ SCREEN_RIGHT = R_screen_rite();
+
+
+ BLACK = D_translate_color ("black");
+ BLUE = D_translate_color ("blue");
+ BROWN = D_translate_color ("brown");
+ GREEN = D_translate_color ("green");
+ GREY = D_translate_color ("grey");
+ ORANGE = D_translate_color ("orange");
+ PURPLE = D_translate_color ("purple");
+ RED = D_translate_color ("red");
+ WHITE = D_translate_color ("white");
+ YELLOW = D_translate_color ("yellow");
+
+ R_standard_color (WHITE);
+
+ VIEW_TITLE1 = makeview (97.5, 100.0, 0.0, 50.0);
+ VIEW_TITLE2 = makeview (97.5, 100.0, 50.0, 100.0);
+ VIEW_MAP1 = makeview (51.0, 97.5, 0.0, 50.0);
+ VIEW_MAP2 = makeview (51.0, 97.5, 50.0, 100.0);
+ VIEW_TITLE1_ZOOM = makeview (47.5, 51.0, 0.0, 50.0);
+ VIEW_TITLE2_ZOOM = makeview (47.5, 51.0, 50.0, 100.0);
+ VIEW_MAP1_ZOOM = makeview (2.5, 47.5, 0.0, 50.0);
+ VIEW_MAP2_ZOOM = makeview (2.5, 47.5, 50.0, 100.0);
+ VIEW_MENU = makeview (0.0, 2.5, 0.0, 100.0);
+
+ G_init_colors (&VIEW_MAP1->cell.colors);
+ G_init_colors (&VIEW_MAP2->cell.colors);
+
+ Erase_view (VIEW_MAP1);
+ Erase_view (VIEW_MAP1_ZOOM);
+ Erase_view (VIEW_MAP2);
+ Erase_view (VIEW_MAP2_ZOOM);
+
+ return 0;
+}
+
+int
+Outline_box (int top, int bottom, int left, int right)
+{
+ R_move_abs (left, top);
+ R_cont_abs (left, bottom);
+ R_cont_abs (right, bottom);
+ R_cont_abs (right, top);
+ R_cont_abs (left, top);
+
+ return 0;
+}
+
+
+int
+Text_width (char *text)
+{
+ int top, bottom, left, right;
+
+ R_get_text_box (text, &top, &bottom, &left, &right);
+
+ if (right > left)
+ return right-left+1;
+ else
+ return left-right+1;
+}
+
+int
+Text (char *text, int top, int bottom, int left, int right, int edge)
+{
+ R_set_window (top, bottom, left, right);
+ R_move_abs (left+edge, bottom-edge);
+ R_text (text);
+ R_set_window (SCREEN_TOP, SCREEN_BOTTOM, SCREEN_LEFT, SCREEN_RIGHT);
+
+ return 0;
+}
+
+int
+Uparrow (int top, int bottom, int left, int right)
+{
+ R_move_abs ((left+right)/2, bottom);
+ R_cont_abs ((left+right)/2, top);
+ R_cont_rel ((left-right)/2, (bottom-top)/2);
+ R_move_abs ((left+right)/2, top);
+ R_cont_rel ((right-left)/2, (bottom-top)/2);
+
+ return 0;
+}
+
+int
+Downarrow (int top, int bottom, int left, int right)
+{
+ R_move_abs ((left+right)/2, top);
+ R_cont_abs ((left+right)/2, bottom);
+ R_cont_rel ((left-right)/2, (top-bottom)/2);
+ R_move_abs ((left+right)/2, bottom);
+ R_cont_rel ((right-left)/2, (top-bottom)/2);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/graphics.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/group.c
===================================================================
--- trunk/grassaddons/i.points.auto/group.c (rev 0)
+++ trunk/grassaddons/i.points.auto/group.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,70 @@
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int cmp(const void *, const void *);
+
+int prepare_group_list (void)
+{
+ FILE *fd;
+ int *idx;
+ int n;
+ int len,len1,len2;
+
+/* open file to store group file names */
+ fd = fopen (group_list, "w");
+ if (fd == NULL)
+ G_fatal_error ("Can't open any tempfiles");
+
+/*
+ * build sorted index into group files
+ * so that all cell files for a mapset to appear together
+ */
+ idx = (int *) G_calloc (group.ref.nfiles, sizeof (int));
+ for (n = 0; n < group.ref.nfiles; n++)
+ idx[n] = n;
+ qsort (idx, group.ref.nfiles, sizeof(int), cmp);
+
+/* determine length of longest mapset name, and longest cell file name */
+ len1 = len2 = 0;
+ for (n = 0; n < group.ref.nfiles; n++)
+ {
+ len = strlen (group.ref.file[n].name);
+ if (len > len1)
+ len1 = len;
+ len = strlen (group.ref.file[n].mapset);
+ if (len > len2)
+ len2 = len;
+ }
+
+/* write lengths, names to file */
+ fwrite (&len1, sizeof (len1), 1, fd);
+ fwrite (&len2, sizeof (len2), 1, fd);
+ for (n = 0; n < group.ref.nfiles; n++)
+ fprintf (fd, "%s %s\n", group.ref.file[idx[n]].name, group.ref.file[idx[n]].mapset);
+ fclose (fd);
+
+ G_free (idx);
+
+ return 0;
+}
+
+static int cmp (const void *aa, const void *bb)
+{
+ const int *a = aa, *b = bb;
+ int n;
+
+ if(n = strcmp (group.ref.file[*a].mapset, group.ref.file[*b].mapset))
+ return n;
+ return strcmp (group.ref.file[*a].name, group.ref.file[*b].name);
+}
+
+/* ask the user to pick a file */
+int choose_groupfile (char *name,char *mapset)
+{
+ int stat;
+ stat = ask_gis_files ("raster", group_list, name, mapset, -1);
+ return(stat);
+}
Property changes on: trunk/grassaddons/i.points.auto/group.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/input.c
===================================================================
--- trunk/grassaddons/i.points.auto/input.c (rev 0)
+++ trunk/grassaddons/i.points.auto/input.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,296 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int active = 0;
+static int replot;
+static int mouse (Objects *,int,int,int);
+static int use_mouse_msg(void);
+static int draw_objects (Objects *);
+static Objects *find (Objects *,int, int);
+static int select_option (Objects *,Objects *);
+static int draw_option_boxes (Objects *);
+static int visible( Objects *);
+
+#define TEXT_COLOR ORANGE /*WHITE*/
+#define FILL_COLOR BLACK /*BLUE*/
+#define OUTLINE_COLOR RED
+
+/* Input: drive mouse. returns status of handler that returns != 0 */
+int Input_pointer (Objects *objects)
+{
+ return mouse (objects,0,0,0);
+}
+
+int Input_box (Objects *objects,int ax,int ay)
+{
+ return mouse (objects,ax,ay,1);
+}
+
+int Input_other (int (*function)(), char *type)
+{
+ int stat;
+ char msg[1024];
+
+ sprintf (msg, "%s input required", type);
+ Menu_msg(msg);
+
+ stat = (*function)();
+ if (active)
+ {
+ use_mouse_msg();
+ }
+
+ Menu_msg("");
+ return stat;
+}
+
+static int mouse (Objects *objects,int ax,int ay,int box)
+{
+ int first;
+ int stat;
+ int x,y,button;
+ Objects *obj;
+ Objects *find();
+
+
+ first = !active;
+ active = 1;
+ if (first)
+ use_mouse_msg();
+
+ if (box)
+ {
+ x = ax + 20;
+ y = ay + 20;
+ }
+ stat = 0;
+ replot = 1;
+ while (stat == 0)
+ {
+
+
+ draw_objects (objects);
+
+ if (box)
+ Mouse_box_anchored (ax, ay, &x, &y, &button) ;
+ else
+ Mouse_pointer (&x, &y, &button) ;
+
+ if (!(obj = find (objects, x, y)))
+ continue;
+
+
+
+ switch (obj->type)
+ {
+ case MENU_OBJECT:
+ case OTHER_OBJECT:
+ stat = (*obj->handler)(x,y,button);
+ break;
+ case OPTION_OBJECT:
+ select_option (objects, obj);
+ draw_option_boxes(objects);
+ break;
+ }
+
+
+ /*This expression is necessary for the button "Main-Menu". */
+ if(m!=0)
+ return -1;
+
+
+ }
+
+/* if we are first call, mark not active
+ * indicate that objects above use must be replotted.
+ */
+ if (first)
+ active = 0;
+ Menu_msg("");
+
+
+ return stat;
+}
+
+
+static int
+use_mouse_msg (void)
+{
+ Curses_write_window (PROMPT_WINDOW, 1, 1, "Use mouse now ...\n");
+
+ return 0;
+}
+
+static int draw_objects (Objects *objects)
+{
+ Objects *obj;
+ int top, bottom, left, right;
+ int size, edge;
+
+
+/* erase the menu window */
+ Erase_view (VIEW_MENU);
+ R_flush();
+
+/* determine sizes and text indentation */
+ size = VIEW_MENU->nrows - 4; /* TEXT-SIZE FOR THE BUTTONS */
+ edge = 2;
+
+ R_text_size (size, size);
+
+ left = VIEW_MENU->left;
+ top = VIEW_MENU->top;
+ bottom = VIEW_MENU->bottom;
+
+
+/* put the (boxed) text on the menu view */
+ for (obj = objects; obj->type; obj++)
+ {
+ if (!visible(obj))
+ continue;
+ switch (obj->type)
+ {
+ case OPTION_OBJECT:
+ case MENU_OBJECT:
+ right = left + 2*edge + Text_width (obj->label);
+ if(!strcmp(obj->label,"LINE")){
+ obj->left = left+1;
+ obj->right = right+1;
+ } else {
+ obj->left = left;
+ obj->right = right;
+
+ }
+
+ obj->top = top;
+ obj->bottom = bottom;
+
+ R_standard_color (FILL_COLOR);
+ R_box_abs (left, top, right, bottom);
+
+ R_standard_color (TEXT_COLOR);
+ Text (obj->label, top, bottom, left, right, edge);
+
+ if(!strcmp(obj->label,"LINE"))
+ R_standard_color(BLUE);
+ else R_standard_color (OUTLINE_COLOR);
+ Outline_box (top, bottom, left, right);
+
+ left = right;
+ break;
+
+ case INFO_OBJECT:
+ if (*obj->label == 0) break;
+ if (*obj->status < 0) break;
+ right = left + 2*edge + Text_width (obj->label);
+ R_standard_color (WHITE);
+ Text (obj->label, top, bottom, left, right, edge);
+
+ left = right;
+ break;
+ }
+ }
+ draw_option_boxes (objects);
+ R_flush();
+
+ return 0;
+}
+
+static Objects *find (Objects *objects,int x, int y)
+{
+ Objects *other;
+ other = NULL;
+ for (; objects->type; objects++)
+ {
+ if (!visible (objects))
+ continue;
+ switch (objects->type)
+ {
+ case MENU_OBJECT:
+ case OPTION_OBJECT:
+ if (x >= objects->left && x <= objects->right
+ && y >= objects->top && y <= objects->bottom)
+ return objects;
+ break;
+ case OTHER_OBJECT:
+ other = objects;
+ break;
+ }
+ }
+ return other;
+}
+
+static int select_option (Objects *objects,Objects *obj)
+{
+ while (objects->type)
+ {
+ if (objects->type == OPTION_OBJECT && *objects->status >= 0 &&
+ objects->binding == obj->binding)
+ *objects->status = 0;
+ objects++;
+ }
+ *obj->status = 1;
+
+ return 0;
+}
+
+static int draw_option_boxes (Objects *objects)
+{
+ Objects *x;
+
+ R_standard_color (OUTLINE_COLOR);
+ for (x = objects; x->type; x++)
+ {
+ if (x->type == OPTION_OBJECT && *x->status == 0)
+ Outline_box (x->top, x->bottom, x->left, x->right);
+ }
+ R_standard_color (GREEN);
+ for (x = objects; x->type; x++)
+ {
+ if (x->type == OPTION_OBJECT && *x->status > 0)
+ Outline_box (x->top, x->bottom, x->left, x->right);
+ }
+
+ return 0;
+}
+
+static int visible( Objects *object)
+{
+ if (object->type == OPTION_OBJECT)
+ return (*object->status >= 0);
+ return (*object->status > 0);
+}
+
+int Menu_msg(char *msg)
+{
+ int size, edge;
+
+ size = VIEW_MENU->nrows - 4;
+ edge = 2;
+
+ Erase_view (VIEW_MENU);
+
+ if (*msg)
+ {
+ R_text_size (size, size);
+ R_standard_color (WHITE);
+ Text (msg, VIEW_MENU->top, VIEW_MENU->bottom,
+ VIEW_MENU->left, VIEW_MENU->right, edge);
+ }
+ R_flush();
+ replot = 1;
+
+ return 0;
+}
+
+int
+Start_mouse_in_menu (void)
+{
+ Set_mouse_xy (
+ (VIEW_MENU->left+2*VIEW_MENU->right)/3,
+ (VIEW_MENU->top+VIEW_MENU->bottom)/2);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/input.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/line.c
===================================================================
--- trunk/grassaddons/i.points.auto/line.c (rev 0)
+++ trunk/grassaddons/i.points.auto/line.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,226 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int cancel();
+static int select(int x1,int y1,int button);
+
+
+double temp_e1,temp_e2,temp_n1,temp_n2;
+static int flag;
+void find_position (int *x1, int *x2,int *y1,int *y2);
+int xtemp[2],ytemp[2], first_linex[2],first_liney[2];
+
+int
+line (void)
+{
+ int stat,row,col,i;
+ static int use = 1;
+ double e1,e2,e3,e4,n1,n2,n3,n4;
+ static Objects objects1[]=
+ {
+ MENU("CANCEL",cancel,&use),
+ INFO("select first line (left side) ",&use),
+ OTHER(select, &use),
+ {0}
+ };
+
+ static Objects objects2[]=
+ {
+ MENU("CANCEL",cancel,&use),
+ INFO("select second line (right side) ",&use),
+ OTHER(select, &use),
+ {0}
+ };
+
+
+ flag =0;
+ stat= Input_pointer (objects1);
+ if (stat==-1) return 0;
+
+ e1=temp_e1;
+ e2=temp_e2;
+ n1=temp_n1;
+ n2=temp_n2;
+ flag = 1;
+
+ for (i=0;i<2;i++)
+ {
+ first_linex[i]=xtemp[i];
+ first_liney[i]=ytemp[i];
+ }
+
+ stat=Input_pointer (objects2);
+ if (stat==-1)
+ {
+ R_panel_restore (tempfile2); /* serve al ripristino del quadrato che contiene la linea collogante i 2 punti */
+ R_panel_restore (tempfile3); /* serve al ripristino del secondo punto*/
+ R_panel_restore (tempfile1); /* serve al ripristino del primo punto*/
+ R_panel_delete (tempfile1);
+ R_panel_delete (tempfile2);
+ R_panel_delete (tempfile3);
+
+ return 0;
+ }
+
+
+ e3=temp_e1;
+ e4=temp_e2;
+ n3=temp_n1;
+ n4=temp_n2;
+ I_new_control_point (&group.points, e1, n1, e3, n3, 2);
+ I_put_control_points (group.name, &group.points);
+ Compute_equation();
+ display_points(1) ;
+ I_new_control_point (&group.points, e2, n2, e4, n4, 3);
+ I_put_control_points (group.name, &group.points);
+ Compute_equation();
+ display_points(1) ;
+ R_standard_color (GREEN);
+ R_polyline_abs (first_linex ,first_liney,2);
+ R_polyline_abs (xtemp ,ytemp,2);
+ R_flush();
+
+ return 0; /* return, but don't QUIT */
+}
+
+static int select(int x,int y,int button)
+{
+ if (button != 1)
+ return where (x,y);
+
+ if (flag==0) {
+ if (VIEW_MAP1->cell.configured && In_view (VIEW_MAP1, x, y))
+ select_line (VIEW_MAP1, x, y);
+ else if (VIEW_MAP1_ZOOM->cell.configured && In_view (VIEW_MAP1_ZOOM, x, y))
+ select_line (VIEW_MAP1_ZOOM, x, y);
+ else return 0;
+ }
+ if (flag==1) {
+ if (VIEW_MAP2->cell.configured && In_view (VIEW_MAP2, x, y))
+ select_line (VIEW_MAP2, x, y);
+ else if (VIEW_MAP2_ZOOM->cell.configured && In_view (VIEW_MAP2_ZOOM, x, y))
+ select_line (VIEW_MAP2_ZOOM, x, y);
+ else return 0;
+ }
+ return 1 ; /* return but don't quit */
+
+};
+
+int select_line (View *view,int x1, int y1)
+{
+ int col, row;
+ int x2,y2,button=0;
+ char buf[50];
+
+
+
+ col = view_to_col (view, x1);
+ temp_e1 = col_to_easting (&view->cell.head, col, 0.5);
+ row = view_to_row (view, y1);
+ temp_n1 = row_to_northing (&view->cell.head, row, 0.5);
+
+ if (flag== 0)
+ {
+ Curses_clear_window (INFO_WINDOW);
+ Curses_clear_window (MENU_WINDOW);
+ sprintf (buf, "Point %d marked on image at", group.points.count+1);
+ Curses_write_window (MENU_WINDOW, 1, 1, buf);
+ sprintf (buf, "East: %10.2f", temp_e1);
+ Curses_write_window (MENU_WINDOW, 3, 3, buf);
+ sprintf (buf, "North: %10.2f", temp_n1);
+ Curses_write_window (MENU_WINDOW, 4, 3, buf);
+ }
+ else
+ {
+
+ sprintf (buf, "Point %d marked on target image at", group.points.count+1);
+ Curses_write_window (INFO_WINDOW, 1, 1, buf);
+ sprintf (buf, "East: %10.2f",temp_e1);
+ Curses_write_window (INFO_WINDOW, 3, 3, buf);
+ sprintf (buf, "North: %10.2f", temp_n1);
+ Curses_write_window (INFO_WINDOW, 4, 3, buf);
+ }
+
+ R_standard_color (ORANGE);
+ R_panel_save (tempfile1, y1-dotsize, y1+dotsize, x1-dotsize, x1+dotsize);
+ dot(x1,y1);
+
+ while (button!=1)
+ {
+ R_get_location_with_line (x1,y1,&x2,&y2,&button);
+ if( button!=1)
+ where (x2,y2);
+ if (!(view->cell.configured && In_view (view, x2, y2)))
+ button=0;
+ }
+
+ col = view_to_col (view, x2);
+ temp_e2 = col_to_easting (&view->cell.head, col, 0.5);
+ row = view_to_row (view, y2);
+ temp_n2 = row_to_northing (&view->cell.head, row, 0.5);
+
+ if (flag== 0)
+ {
+ sprintf (buf, "Point %d marked on image at", group.points.count+2);
+ Curses_write_window (MENU_WINDOW, 6, 1, buf);
+ sprintf (buf, "East: %10.2f", temp_e2);
+ Curses_write_window (MENU_WINDOW, 8, 3, buf);
+ sprintf (buf, "North: %10.2f", temp_n2);
+ Curses_write_window (MENU_WINDOW, 9, 3, buf);
+ }
+ else
+ {
+ sprintf (buf, "Point %d marked on target image at", group.points.count+2);
+ Curses_write_window (INFO_WINDOW, 6, 1, buf);
+ sprintf (buf, "East: %10.2f",temp_e2);
+ Curses_write_window (INFO_WINDOW, 8, 3, buf);
+ sprintf (buf, "North: %10.2f", temp_n2);
+ Curses_write_window (INFO_WINDOW, 9, 3, buf);
+ }
+
+ R_standard_color (ORANGE);
+ R_panel_save (tempfile3, y2-dotsize, y2+dotsize, x2-dotsize, x2+dotsize);
+ dot(x2,y2);
+
+ xtemp[0]= x1;
+ xtemp[1]= x2;
+ ytemp[0]= y1;
+ ytemp[1]= y2;
+
+ find_position (&x1,&x2,&y1,&y2);
+ R_panel_save (tempfile2, y1, y2, x1, x2);
+ R_polyline_abs (xtemp ,ytemp,2);
+
+ return 1 ;
+
+ }
+
+ void find_position (int *x1, int *x2,int *y1,int *y2)
+ { int temp;
+ if (*y2<*y1) {
+ temp=*y1;
+ *y1=*y2;
+ *y2= temp;
+ }
+ else if (*y2==*y1) { *y2= *y2+dotsize;
+ *y1= *y1 - dotsize ;
+ }
+ if (*x2<*x1) {
+ temp=*x1;
+ *x1=*x2;
+ *x2= temp;
+ }
+ else if (*x2==*x1) { *x2= *x2+dotsize;
+ *x1= *x1 - dotsize ;
+ }
+ }
+
+
+ static int cancel()
+ {
+ return -1 ;
+}
+
+
Property changes on: trunk/grassaddons/i.points.auto/line.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/local_proto.h
===================================================================
--- trunk/grassaddons/i.points.auto/local_proto.h (rev 0)
+++ trunk/grassaddons/i.points.auto/local_proto.h 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,142 @@
+/* analyze.c */
+int analyze(void);
+int points_to_line (double, double, double, double, double *, double *);
+/* ask.c */
+int ask_gis_files(char *, char *, char *, char *, int);
+int ask_original_map(char *, char *, char *, char *, int); /* AGGIUNTA */
+/* ask_mag.c */
+int ask_magnification(int *);
+int draw_mag(void);
+/* call.c */
+int call(int (*)(), char *);
+/* cell.c */
+int plotcell(int, int);
+/* cellhd.c */
+int Outline_cellhd(View *, struct Cell_head *);
+/* colors.c */
+int set_colors(struct Colors *);
+/* conv.c */
+int view_to_col(View *, int);
+int view_to_row(View *, int);
+int col_to_view(View *, int);
+int row_to_view(View *, int);
+double row_to_northing(struct Cell_head *, int, double);
+double col_to_easting(struct Cell_head *, int, double);
+double northing_to_row(struct Cell_head *, double);
+double easting_to_col(struct Cell_head *, double);
+/* curses.c */
+int Begin_curses(void);
+int End_curses(void);
+int Suspend_curses(void);
+int Resume_curses(void);
+int Curses_allow_interrupts(int);
+int Curses_clear_window(Window *);
+int Curses_outline_window(Window *);
+int Curses_write_window(Window *, int, int, char *);
+int Curses_replot_screen(void);
+int Curses_prompt_gets(char *, char *);
+int Beep(void);
+int Curses_getch(int);
+/* debug.c */
+int debug(char *);
+/* digit.c */
+int setup_digitizer(void);
+int digitizer_point(double *, double *);
+/* dot.c */
+int dot(int, int);
+int save_under_dot(int, int);
+int restore_under_dot(void);
+int release_under_dot(void);
+/* drawcell.c */
+int drawcell(View *);
+/* driver.c */
+int driver(void);
+/* equ.c */
+int Compute_equation(void);
+/* find_points.c */
+int automated_search(void);
+void Extract_matrix(void);
+void Search_correlation_points(DCELL**, DCELL**, int, int, int, char *,
+ int, int, DCELL **, int, int, int, int, int, int, int, int,int,int, int); /*Aggiunta*/
+void Extract_portion_of_double_matrix(int, int, int, int, DCELL**, DCELL**);
+
+
+
+/* find_points_semi */
+extern void Extract_matrix_semi(void);
+extern void Search_correlation_points_semi(DCELL**, DCELL**, int, int, int, char *,
+ int, int, DCELL **, int, int, int, int, int, int, int, int,int,int);
+extern void Extract_portion_of_double_matrix_semi(int, int, int, int, DCELL**, DCELL**);
+
+
+/* find.c */
+int find_target_files(void);
+/*georef.c*/
+int compute_georef_equations(struct Control_Points *cp, double E12[3], double N12[3], double E21[3], double N21[3]);
+int compute_georef_equations_lp (Lines *ln);
+int georef (double e1,double n1,double *e2,double *n2,double E[3],double N[3]);
+/* graphics.c */
+int Init_graphics(void);
+int Outline_box(int, int, int, int);
+int Text_width(char *);
+int Text(char *, int, int, int, int, int);
+int Uparrow(int, int, int, int);
+int Downarrow(int, int, int, int);
+/* group.c */
+int prepare_group_list(void);
+int choose_groupfile(char *, char *);
+/* input.c */
+int Input_pointer(Objects *);
+int Input_box(Objects *, int, int);
+int Input_other(int (*)(), char *);
+int Menu_msg(char *);
+int Start_mouse_in_menu(void);
+/* line.c */
+int line(void);
+int select_line (View *, int, int);
+/* main.c */
+int quit(int);
+int error(char *, int);
+/* mark.c */
+int mark(int, int, int);
+int mark_point(View *, int, int);
+/* mouse.c */
+int Mouse_pointer(int *, int *, int *);
+int Mouse_box_anchored(int, int, int *, int *, int *);
+int Get_mouse_xy(int *, int *);
+int Set_mouse_xy(int, int);
+/* points.c */
+int display_points(int);
+int display_points_in_view(View *, int, double *, double *, int *, int);
+int display_points_in_view_diff_color(View *, int, double *, double *, int *, int);
+int display_points_in_view_diff_color_if_active(View *, int, double *, double *, int *, int);
+int display_one_point(View *, double, double);
+/* target.c */
+int get_target(void);
+int select_current_env(void);
+int select_target_env(void);
+/* title.c */
+int display_title(View *);
+/* view.c */
+int Configure_view(View *, char *, char *, double, double);
+int In_view(View *, int, int);
+int Erase_view(View *);
+double magnification(View *);
+/* where.c */
+int where(int, int);
+/*write_line.c*/
+int put_control_points ( char *group, struct Control_Points *cp);
+int read_control_points (FILE *fd, struct Control_Points *cp);
+int new_control_point (struct Control_Points *cp,double e1,double n1,double e2,double n2, int status);
+int write_control_points(FILE *fd, struct Control_Points *cp);
+int get_control_points (char *group, struct Control_Points *cp);
+/* zoom.c */
+int zoom(void);
+static int which_zoom(int x, int y, int button);
+/* overlap_area.c */
+int overlap_area(int,int,int,int,int, int,int);
+/* zoom_box.c */
+int zoom_box(int ,int );
+/* zoom_pnt.c */
+int zoom_point(int , int );
+int zoom_pnt (int ,int );
Property changes on: trunk/grassaddons/i.points.auto/local_proto.h
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/main.c
===================================================================
--- trunk/grassaddons/i.points.auto/main.c (rev 0)
+++ trunk/grassaddons/i.points.auto/main.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,204 @@
+/*****************************************************************************
+*
+* MODULE: i.points.auto
+* AUTHOR(S): based on i.points; additions by
+* Ivan Michelazzi, Luca Miori (MSc theses at ITC-irst)
+* http://gisws.media.osaka-cu.ac.jp/grass04/viewpaper.php?id=37
+* Supervisors: Markus Neteler, Stefano Merler, ITC-irst 2003, 2004
+*
+* PURPOSE: semi-automated image registration based in FFT correlation
+* COPYRIGHT: GPL >=2
+*
+*****************************************************************************/
+
+#define GLOBAL
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+#ifdef __GNUC_MINOR__
+int quit (int) __attribute__ ((__noreturn__));
+#else
+int quit (int);
+#endif
+int error (char *, int);
+
+
+
+int main (int argc, char *argv[])
+{
+ char name[GNAME_MAX], mapset[GMAPSET_MAX];
+ struct Cell_head cellhd;
+ struct GModule *module;
+
+ G_gisinit (argv[0]);
+ module = G_define_module();
+ module->description =
+ _("Mark or search ground control points on image to be rectified.");
+
+ G_suppress_masking(); /* need to do this for target location */
+
+ interrupt_char = G_intr_char();
+ tempfile1 = G_tempfile();
+ tempfile2 = G_tempfile();
+ tempfile3 = G_tempfile();
+ cell_list = G_tempfile();
+ vect_list = G_tempfile();
+ group_list = G_tempfile();
+ digit_points = G_tempfile();
+ digit_results = G_tempfile();
+
+ if (R_open_driver() != 0)
+ G_fatal_error(_("No graphics device selected"));
+
+ /* temporary parser code: */
+ if(argc == 2) {
+ strncpy(group.name, argv[1], GNAME_MAX);
+ if(group.name[0] == '-')
+ G_fatal_error(_("The parser doesn't work here."));
+ }
+ else {
+ if (!I_ask_group_old (_("Enter imagery group to be registered"), group.name))
+ exit(EXIT_FAILURE);
+ }
+
+ if (!I_get_group_ref (group.name, &group.ref))
+ G_fatal_error ( _("Group [%s] contains no files"), group.name);
+
+ if (group.ref.nfiles <= 0)
+ G_fatal_error ( _( "Group [%s] contains no files"), group.name);
+
+/* write group files to group list file */
+ prepare_group_list();
+ debug("prepare_group_list done");
+
+/* get target info and enviroment */
+ get_target();
+ find_target_files();
+ debug("find_target_files done");
+
+/* read group control points, if any */
+ G_suppress_warnings(1);
+ if (!I_get_control_points (group.name, &group.points))
+ group.points.count = 0;
+ G_suppress_warnings(0);
+
+/* determine tranformation equation */
+ G_debug(0, "starting Compute_equation()");
+ Compute_equation();
+
+ signal (SIGINT, SIG_IGN);
+/* signal (SIGQUIT, SIG_IGN); */
+
+ R_standard_color (BLUE);
+
+ Init_graphics();
+ display_title (VIEW_MAP1);
+
+ G_debug(0, "select_target_env");
+ select_target_env ();
+ display_title (VIEW_MAP2);
+ select_current_env ();
+ G_debug(0, "select_target_env done");
+
+ Begin_curses();
+ G_debug(0, "Begin_curses done");
+ G_set_error_routine (error);
+
+/*
+#ifdef SIGTSTP
+ signal (SIGTSTP, SIG_IGN);
+#endif
+*/
+
+/* ask user for group file to be displayed */
+ G_debug(0, "ask user for group file to be displayed");
+ do
+ {
+ if(!choose_groupfile (name, mapset))
+ quit(0);
+
+/* display this file in "map1" */
+ }
+ while (G_get_cellhd (name, mapset, &cellhd) < 0);
+ G_adjust_window_to_box (&cellhd, &VIEW_MAP1->cell.head, VIEW_MAP1->nrows, VIEW_MAP1->ncols);
+ Configure_view (VIEW_MAP1, name, mapset, cellhd.ns_res, cellhd.ew_res);
+
+ drawcell(VIEW_MAP1);
+ display_points(1);
+ R_flush();
+
+ Curses_clear_window (PROMPT_WINDOW);
+
+ Erase_view (VIEW_MAP1_ZOOM);
+
+
+/* determine initial input method. */
+ setup_digitizer();
+ if (use_digitizer)
+ {
+ from_digitizer = 1;
+ from_keyboard = 0;
+ from_flag = 1;
+ }
+
+/* go do the work */
+ driver();
+
+ quit(0);
+}
+
+int quit (int n)
+{
+ char command[1024];
+
+ End_curses();
+ R_close_driver();
+ if (use_digitizer)
+ {
+ sprintf (command, "%s/etc/geo.unlock %s",
+ G_gisbase(), digit_points);
+ system (command);
+ }
+ unlink (tempfile1);
+ unlink (tempfile2);
+ unlink (tempfile3);
+ unlink (cell_list);
+ unlink (group_list);
+ unlink (vect_list);
+ unlink (digit_points);
+ unlink (digit_results);
+ exit(n);
+}
+
+int error (char *msg, int fatal)
+{
+ char buf[200];
+ int x,y,button;
+
+Curses_clear_window (PROMPT_WINDOW);
+Curses_write_window (PROMPT_WINDOW,1,1, "LOCATION:\n");
+Curses_write_window (PROMPT_WINDOW,1,12,G_location());
+Curses_write_window (PROMPT_WINDOW,2,1, "MAPSET:\n");
+Curses_write_window (PROMPT_WINDOW,2,12,G_location());
+ Beep();
+ if (fatal)
+ sprintf (buf, "ERROR: %s", msg);
+ else
+ sprintf (buf, "WARNING: %s (click mouse to continue)", msg);
+ Menu_msg (buf);
+
+ if (fatal)
+ quit(1);
+ Mouse_pointer (&x, &y, &button);
+ Curses_clear_window (PROMPT_WINDOW);
+
+ return 0;
+}
+
Property changes on: trunk/grassaddons/i.points.auto/main.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/mark.c
===================================================================
--- trunk/grassaddons/i.points.auto/mark.c (rev 0)
+++ trunk/grassaddons/i.points.auto/mark.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,205 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int get_point2 (double *,double *);
+static int keyboard();
+static int _keyboard();
+static int screen (int,int,int);
+static int digitizer();
+static int cancel();
+
+int mark(int x,int y,int button)
+{
+ if (button != 1)
+ return where (x,y);
+
+ if (VIEW_MAP1->cell.configured && In_view (VIEW_MAP1, x, y))
+ mark_point (VIEW_MAP1, x, y);
+ else if (VIEW_MAP1_ZOOM->cell.configured && In_view (VIEW_MAP1_ZOOM, x, y))
+ mark_point (VIEW_MAP1_ZOOM, x, y);
+ return 0 ; /* return but don't quit */
+
+
+}
+
+int mark_point (View *view,int x, int y)
+{
+ double e1,n1;
+ double e2,n2;
+ int row,col;
+
+ char buf[100];
+
+/* convert x,y to east,north at center of cell */
+ col = view_to_col (view, x);
+ e1 = col_to_easting (&view->cell.head, col, 0.5);
+ row = view_to_row (view, y);
+ n1 = row_to_northing (&view->cell.head, row, 0.5);
+
+ Curses_clear_window (MENU_WINDOW);
+ sprintf (buf, "Point %d marked on image at", group.points.count+1);
+ Curses_write_window (MENU_WINDOW, 1, 1, buf);
+ sprintf (buf, "East: %10.2f", e1);
+ Curses_write_window (MENU_WINDOW, 3, 3, buf);
+ sprintf (buf, "North: %10.2f", n1);
+ Curses_write_window (MENU_WINDOW, 4, 3, buf);
+ Curses_clear_window (INFO_WINDOW);
+
+ R_standard_color (ORANGE);
+ save_under_dot (x,y);
+ dot(x,y);
+
+ if (!get_point2(&e2, &n2))
+ {
+ Curses_clear_window (MENU_WINDOW);
+ restore_under_dot();
+ }
+ else
+ {
+ Curses_write_window (MENU_WINDOW, 7, 1, "Point located at");
+ sprintf (buf, "East: %10.2f", e2);
+ Curses_write_window (MENU_WINDOW, 9, 3, buf);
+ sprintf (buf, "North: %10.2f", n2);
+ Curses_write_window (MENU_WINDOW,10, 3, buf);
+ I_new_control_point (&group.points, e1, n1, e2, n2, 1);
+ I_put_control_points (group.name, &group.points);
+ Compute_equation();
+ display_points(1);
+ }
+ release_under_dot();
+
+ return 0;
+}
+
+static double N,E;
+
+static int get_point2 (double *east,double *north)
+{
+ int digitizer();
+ int keyboard();
+ int stat;
+ int screen();
+ int cancel();
+ static int use = 1;
+ static Objects objects[] =
+ {
+ MENU ("CANCEL", cancel, &use),
+ INFO ("Mark point on target image", &use),
+ OTHER (screen, &use),
+ {0}
+ };
+
+ if (from_digitizer > 0)
+ {
+ stat = Input_other (digitizer, "Digitizer");
+ }
+ else if (from_screen > 0)
+ {
+ set_colors (&VIEW_MAP2->cell.colors);
+ stat = Input_pointer(objects) > 0;
+ set_colors (&VIEW_MAP1->cell.colors);
+ }
+ else
+ stat = Input_other (keyboard, "Keyboard");
+
+ if(stat)
+ {
+ *east = E;
+ *north = N;
+ }
+
+ return stat ;
+}
+
+static int
+keyboard (void)
+{
+ int ok;
+ Curses_clear_window (INFO_WINDOW);
+ ok = _keyboard ();
+ Curses_clear_window (INFO_WINDOW);
+ return ok;
+}
+
+static int
+_keyboard (void)
+{
+ char buf[100];
+
+ while(1)
+ {
+ Curses_prompt_gets ("Enter coordinates as east north: ", buf);
+ G_strip (buf);
+ if (*buf == 0)
+ {
+ return 0;
+ }
+ if (sscanf (buf, "%lf %lf", &E, &N) != 2)
+ {
+ Beep();
+ continue;
+ }
+ Curses_clear_window (INFO_WINDOW);
+ sprintf (buf, "East: %f\n", E);
+ Curses_write_window (INFO_WINDOW, 2, 2, buf);
+ sprintf (buf, "North: %f\n", N);
+ Curses_write_window (INFO_WINDOW, 3, 2, buf);
+ Curses_write_window (INFO_WINDOW, 5, 1, "Look ok? (y/n) ");
+
+ while(1)
+ {
+ int c;
+ c = Curses_getch(0);
+ if (c == 'y' || c == 'Y')
+ return 1;
+ if (c == 'n' || c == 'N')
+ break;
+ Beep();
+ }
+ }
+
+ return 0;
+}
+
+static int
+digitizer (void)
+{
+ return digitizer_point (&E, &N);
+}
+
+
+static int screen (int x,int y,int button)
+{
+ int row,col;
+ char buf[50];
+
+ View *view;
+ if (In_view (VIEW_MAP2, x, y) && VIEW_MAP2->cell.configured)
+ view = VIEW_MAP2;
+ else if (In_view (VIEW_MAP2_ZOOM, x, y) && VIEW_MAP2_ZOOM->cell.configured)
+ view = VIEW_MAP2_ZOOM;
+ else
+ return 0; /* ignore mouse event */
+
+ col = view_to_col (view, x);
+ E = col_to_easting (&view->cell.head, col, 0.5);
+ row = view_to_row (view, y);
+ N = row_to_northing (&view->cell.head, row, 0.5);
+
+ if (button == 1)
+ return 1;
+
+ sprintf (buf, "East: %10.2f\n", E);
+ Curses_write_window (INFO_WINDOW, 2, 2, buf);
+ sprintf (buf, "North: %10.2f\n", N);
+ Curses_write_window (INFO_WINDOW, 3, 2, buf);
+
+ return 0;
+}
+
+static int
+cancel (void)
+{
+ return -1;
+}
Property changes on: trunk/grassaddons/i.points.auto/mark.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/mouse.c
===================================================================
--- trunk/grassaddons/i.points.auto/mouse.c (rev 0)
+++ trunk/grassaddons/i.points.auto/mouse.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,59 @@
+#include
+#include "globals.h"
+
+static int first = 1;
+static int curx, cury;
+
+int
+Mouse_pointer (int *x, int *y, int *button)
+{
+ if (first)
+ {
+ curx = (SCREEN_LEFT + SCREEN_RIGHT)/2;
+ cury = (SCREEN_TOP + SCREEN_BOTTOM)/2;
+ first = 0;
+ }
+ R_get_location_with_pointer (&curx, &cury, button);
+ *x = curx;
+ *y = cury;
+
+#ifdef BUTTON3
+ if (*button == 3) quit(0);
+#endif
+
+ return 0;
+}
+
+int
+Mouse_box_anchored (int x1, int y1, int *x2, int *y2, int *button)
+{
+ R_get_location_with_box (x1, y1, x2, y2, button);
+ curx = *x2;
+ cury = *y2;
+ first = 0;
+
+#ifdef BUTTON3
+ if (*button == 3) quit(0);
+#endif
+
+ return 0;
+}
+
+int
+Get_mouse_xy (int *x, int *y)
+{
+ *x = curx;
+ *y = cury;
+
+ return 0;
+}
+
+int
+Set_mouse_xy (int x, int y)
+{
+ first = 0;
+ curx = x;
+ cury = y;
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/mouse.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/orig/find_points_semi.c.org
===================================================================
--- trunk/grassaddons/i.points.auto/orig/find_points_semi.c.org (rev 0)
+++ trunk/grassaddons/i.points.auto/orig/find_points_semi.c.org 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,776 @@
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+#include "raster.h"
+#include "imagery.h"
+#include "gmath.h"
+
+#ifdef NULL_VALUE
+#undef NULL_VALUE
+#endif
+#define NULL_VALUE -1
+
+
+#ifdef DEBUG
+#undef DEBUG
+#endif
+
+struct Cell_head cellhd1;
+struct Cell_head cellhd2;
+
+struct Control_Points sPoints;
+
+double *fft_first[2];
+double *fft_second[2];
+double *fft_prod_con[2];
+
+
+
+View *m1, *m2;
+
+void Extract_matrix_semi()
+{
+ struct GModule *module;
+ struct Control_Points *cp1;
+ char buf[256];
+ char *s;
+ int rows, cols;
+ char *first_map_R_mapset;
+ char *first_map_R_name;
+ int first_map_R_fd;
+ char *second_map_R_mapset;
+ char *second_map_R_name;
+ int second_map_R_fd;
+
+ int K;
+
+ int correlation_window_dim;
+ int search_window_dim;
+
+ int squared_search_window_dim;
+ int search_jump;
+
+ int ncols1, ncols2, nrows1, nrows2;
+ int left1, top1, left2, top2;
+ int repeat;
+
+ int n_1, e_1, n_2, e_2, s_1, s_2, w_1, w_2;
+ int r1_1, r1_2, r2_1, r2_2;
+ int c1_1, c1_2, c2_1, c2_2;
+
+ int i;
+
+ int h1_r;
+ int h1_c;
+ int h2_r;
+ int h2_c;
+
+
+ char *group_name;
+ char *group_MAPSET;
+ char *group_LOCATION_NAME;
+ char *group_GISDBASE;
+ DCELL *rowbuf1_R;
+ DCELL *tf1_R;
+ DCELL *rowbuf2_R;
+ DCELL *tf2_R;
+ double **search_window;
+ double **mat1,**mat2;
+ int r,c;
+ int search_border;
+ int q;
+ int p1;
+ int dim_win_c, dim_win_r;
+ char first_sites[500];
+ char second_sites[500];
+ char file_name[500];
+ char file_name_old[500];
+ FILE *first_fp;
+ FILE *second_fp;
+ FILE *fp;
+ FILE *fp_old;
+
+
+
+ /* Read VIEW_MAP1_ZOOM & VIEW_MAP2_ZOOM informations */
+
+
+ m1=VIEW_MAP1_ZOOM;
+ m2=VIEW_MAP2_ZOOM;
+
+ first_map_R_name=m1->cell.name;
+ second_map_R_name=m2->cell.name;
+
+ /* rows & cols of VIEW_MAP1_ZOOM */
+ n_1=m1->cell.head.north;
+ e_1=m1->cell.head.east;
+ s_1=m1->cell.head.south;
+ w_1=m1->cell.head.west;
+ left1 = m1->cell.left;
+ top1 = m1->cell.top;
+
+ r1_1=s_1/m1->cell.ns_res;
+ r1_2=n_1/m1->cell.ns_res;
+ c1_1=w_1/m1->cell.ew_res;
+ c1_2=e_1/m1->cell.ew_res;
+
+ nrows1=r1_2-r1_1;
+ ncols1=c1_2-c1_1;
+
+
+ /* rows & cols of VIEW_MAP2_ZOOM */
+ n_2=m2->cell.head.north;
+ e_2=m2->cell.head.east;
+ s_2=m2->cell.head.south;
+ w_2=m2->cell.head.west;
+ left2 = m2->cell.left;
+ top2 = m2->cell.top;
+
+ r2_1=s_2/m2->cell.ns_res;
+ r2_2=n_2/m2->cell.ns_res;
+ c2_1=w_2/m2->cell.ew_res;
+ c2_2=e_2/m2->cell.ew_res;
+
+ nrows2=r2_2-r2_1;
+ ncols2=c2_2-c2_1;
+
+
+
+ /* Initialize the GIS calls */
+ module = G_define_module();
+ module->description = "Fine registration of two stereo images";
+
+ /* Load environmental vars*/
+ group_LOCATION_NAME=buf;
+ group_LOCATION_NAME=G_getenv("LOCATION_NAME");
+ group_GISDBASE=buf;
+ group_GISDBASE=G_getenv("GISDBASE");
+ group_MAPSET=buf;
+ group_MAPSET=G_getenv("MAPSET");
+
+
+ /* Correlation parameters */
+ correlation_window_dim=((ncols1/10+nrows1/10)/2);
+ K=((ncols1/4+nrows1/4)/2);
+
+ search_window_dim = max_pow2(correlation_window_dim + K);
+ group_name=group.name;
+ squared_search_window_dim=search_window_dim*search_window_dim;
+ search_jump=search_window_dim / 2;
+
+
+
+ Menu_msg ("Loading first zoom_image...");
+
+ /* Open first real map*/
+ if((first_map_R_mapset = G_find_cell2(first_map_R_name, "")) == NULL)
+ {
+ sprintf(buf,"Raster map [%s] not available",first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+
+ if((first_map_R_fd = G_open_cell_old(first_map_R_name,
+ first_map_R_mapset)) < 0)
+ {
+ sprintf(buf,"Error opening raster map [%s]", first_map_R_name);
+ G_fatal_error(buf);
+ }
+
+ /* Set region to first map definition region < m1 > */
+ G_get_cellhd (first_map_R_name, first_map_R_mapset, &cellhd1);
+ G_set_window(&cellhd1);
+ h1_r=cellhd1.rows;
+ h1_c=cellhd1.cols;
+
+
+
+ /* Memory allocation for zoom_map_1 */
+
+ mat1 = (DCELL **) G_calloc(nrows1,sizeof(DCELL *));
+ for(r=0;rcell.ns_res;
+ cellhd1.south=r1_1*m1->cell.ns_res;
+ cellhd1.east=c1_2*m1->cell.ew_res;
+ cellhd1.west=c1_1*m1->cell.ew_res;
+
+ /* Set cellhd2 to zoom_map_2 */
+ cellhd2.rows=nrows2;
+ cellhd2.cols=ncols2;
+ cellhd2.north=r2_2*m2->cell.ns_res;
+ cellhd2.south=r1_1*m2->cell.ns_res;
+ cellhd2.east=c2_2*m2->cell.ew_res;
+ cellhd2.west=c2_1*m2->cell.ew_res;
+
+ /* Set windows to cellhd1 */
+ G_set_window(&cellhd1);
+
+
+
+ /******************************************/
+ /* function --> Search_correlation_points */
+ /******************************************/
+ Search_correlation_points_semi(mat1, mat2,
+ search_window_dim,
+ squared_search_window_dim,
+ search_jump,group_name, nrows1, ncols1,
+ search_window, r1_2, c1_1, r2_2, c2_1,
+ h1_r, h2_r, h1_c, h2_c, nrows2, ncols2 );
+
+
+
+
+ /* Build group/POINTS file */
+ sPoints.count -= 1;
+ if(sPoints.count > 0)
+ {
+ sprintf(file_name,"%s/%s/%s/group/%s/POINTS",group_GISDBASE,
+ group_LOCATION_NAME,group_MAPSET,group_name);
+ fp_old = fopen(file_name,"r");
+ if( fp_old==NULL)
+ {
+ q=0;
+ }
+ else
+ {
+ q=1;
+ fclose(fp_old);
+ }
+
+ if (q==0)
+ {
+ fp = fopen(file_name,"a");
+ fprintf (fp,"# %7s %15s %15s %15s %9s status\n","",
+ "image","","target","");
+ fprintf (fp,"# %15s %15s %15s %15s (1=ok)\n",
+ "east","north","east","north");
+ fprintf (fp,"#\n");
+
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ fprintf (fp, " %15f %15f %15f %15f %4d\n",
+ sPoints.e1[i], sPoints.n1[i], sPoints.e2[i], sPoints.n2[i], sPoints.status[i]);
+
+ }
+ if(q==1)
+ {
+ fp = fopen(file_name,"a");
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ fprintf (fp, " %15f %15f %15f %15f %4d\n", sPoints.e1[i], sPoints.n1[i], sPoints.e2[i], sPoints.n2[i], sPoints.status[i]);
+ }
+ fclose (fp);
+ }
+
+ /* Load new control points */
+
+ for (i = 0; i < sPoints.count; i++)
+ if ( sPoints.status[i] != -1)
+ new_control_point (&group.points,sPoints.e1[i], sPoints.n1[i],
+ sPoints.e2[i], sPoints.n2[i], sPoints.status[i] );
+
+ /* Build group/REF file */
+ /*
+ sprintf(file_name,"%s/%s/%s/group/%s/REF",group_GISDBASE,
+ group_LOCATION_NAME, group_MAPSET,group_name);
+ fp = fopen(file_name,"w");
+ fprintf(fp,"%s %s\n",first_map_R_name,first_map_R_mapset);
+
+ fclose(fp);
+ */
+
+ /* Build group/TARGET file */
+ sprintf(file_name,"%s/%s/%s/group/%s/TARGET",group_GISDBASE,
+ group_LOCATION_NAME, group_MAPSET,group_name);
+ fp = fopen(file_name,"w");
+ fprintf(fp,"%s\n%s\n",group_LOCATION_NAME,group_MAPSET);
+ fclose(fp);
+
+ /* Display new points */
+ select_current_env ();
+ display_points_in_view (VIEW_MAP1, 1,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP1_ZOOM, 1,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2, 1,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2_ZOOM, 1,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+ R_flush();
+
+ /* Free memory */
+
+ free( rowbuf1_R);
+ free( rowbuf2_R);
+
+
+ for(r=0;r=nrows2)||(c-search_border+2*search_border>=ncols2))
+ {
+ if (sPoints.count<=1)
+ {
+ Menu_msg("DEFINE A NEW REGION.");
+ sleep(3);
+ pause;
+ }
+ return 0;
+ }
+
+ Extract_portion_of_double_matrix_semi(r,c,search_border,search_border,
+ mat2_R,search_window);
+ mean = 0.0;
+ for(i=0;i cross-correlation at differnet lag
+ between the two orig. (complex) windows */
+ fft(1,fft_prod_con,squared_search_window_dim,search_window_dim,
+ search_window_dim);
+
+#ifdef DEBUG
+ for(i=0;i cc)
+ {
+ cc = fft_prod_con[0][i];
+ tmp_r=i/search_window_dim;
+ tmp_c=i%search_window_dim;
+
+ }
+ }
+
+ /* Get coordinates of "ending" point */
+ if((tmp_r <= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r <= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - tmp_r,&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c <= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - tmp_c,&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+ if((tmp_r >= search_window_dim/2) && (tmp_c >= search_window_dim/2))
+ {
+
+ east2 = G_col_to_easting((double) c - (tmp_c-search_window_dim-1),&cellhd2);
+ north2 = G_row_to_northing((double) r - (tmp_r-search_window_dim-1),&cellhd2);
+
+ }
+
+
+ /* Fill the POINTS file*/
+ sPoints.e1[sPoints.count-1] = east1;
+ sPoints.n1[sPoints.count-1] = north1;
+ sPoints.e2[sPoints.count-1] = east2;
+ sPoints.n2[sPoints.count-1] = north2;
+
+ sPoints.status[sPoints.count-1] = 1;
+ sPoints.count += 1;
+ sPoints.e1=(double *)G_realloc(sPoints.e1,sPoints.count*sizeof(double));
+ sPoints.n1=(double *)G_realloc(sPoints.n1,sPoints.count*sizeof(double));
+ sPoints.e2=(double *)G_realloc(sPoints.e2,sPoints.count*sizeof(double));
+ sPoints.n2=(double *)G_realloc(sPoints.n2,sPoints.count*sizeof(double));
+ sPoints.status=(int *)G_realloc(sPoints.status,sPoints.count*sizeof(int));
+ }
+ G_percent (r,dim_win_r, 1);
+ }
+ }
+
+
+void Extract_portion_of_double_matrix_semi(int r,int c,int br,int bc,DCELL **mat,DCELL **wind)
+ /*
+ extract a squared portion of a matrix mat
+ given a the indeces of the center [r,c]
+ and the semilength of the borders [br,bc]
+ Output to array wind
+ */
+{
+ int i,j;
+ for(i=0;(i <2*br);i++)
+ for(j = 0;(j <2*bc);j++)
+ {
+ wind[i][j] = mat[r - br + i][c - bc +j];
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Added: trunk/grassaddons/i.points.auto/orig/globals.h.org
===================================================================
--- trunk/grassaddons/i.points.auto/orig/globals.h.org (rev 0)
+++ trunk/grassaddons/i.points.auto/orig/globals.h.org 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,114 @@
+#include "defs.h"
+
+#ifndef GLOBAL
+# define GLOBAL extern
+# define INIT(x)
+#else
+# define INIT(x) = x
+#endif
+
+
+
+
+/* Variable for the botton "Main-Menu". */
+GLOBAL int m;
+
+
+
+
+
+GLOBAL int G_get_color();
+
+GLOBAL int SCREEN_TOP;
+GLOBAL int SCREEN_BOTTOM;
+GLOBAL int SCREEN_LEFT;
+GLOBAL int SCREEN_RIGHT;
+
+GLOBAL int correlation_window_dim;
+GLOBAL int K;
+GLOBAL char *group_name;
+
+
+
+GLOBAL Window *INFO_WINDOW;
+GLOBAL Window *MENU_WINDOW;
+GLOBAL Window *PROMPT_WINDOW;
+
+GLOBAL View *VIEW_MAP1;
+GLOBAL View *VIEW_TITLE1;
+GLOBAL View *VIEW_MAP1_ZOOM;
+GLOBAL View *VIEW_TITLE1_ZOOM;
+
+GLOBAL View *VIEW_MAP2;
+GLOBAL View *VIEW_TITLE2;
+GLOBAL View *VIEW_MAP2_ZOOM;
+GLOBAL View *VIEW_TITLE2_ZOOM;
+
+GLOBAL View *VIEW_MENU;
+
+GLOBAL Group group;
+
+GLOBAL char interrupt_char;
+GLOBAL char *tempfile1;
+GLOBAL char *tempfile2;
+GLOBAL char *tempfile3;
+GLOBAL char *digit_points; /* digitizer control points */
+GLOBAL char *digit_results; /* digitizer results */
+GLOBAL int use_digitizer INIT(0); /* is there a digitizer out there? */
+
+/* group file list, target cell,vector files */
+GLOBAL char *group_list INIT(NULL);
+GLOBAL char *cell_list INIT(NULL);
+GLOBAL char *vect_list INIT(NULL);
+
+GLOBAL int from_keyboard INIT(-1); /* input method */
+GLOBAL int from_digitizer INIT(-1);
+GLOBAL int from_screen INIT(-1);
+GLOBAL int from_flag INIT(0);
+
+GLOBAL int dotsize INIT(4);
+
+GLOBAL int THE_COLORS[10];
+#define BLACK THE_COLORS[0]
+#define BLUE THE_COLORS[1]
+#define BROWN THE_COLORS[2]
+#define GREEN THE_COLORS[3]
+#define GREY THE_COLORS[4]
+#define ORANGE THE_COLORS[5]
+#define PURPLE THE_COLORS[6]
+#define RED THE_COLORS[7]
+#define WHITE THE_COLORS[8]
+#define YELLOW THE_COLORS[9]
+
+double row_to_northing();
+double col_to_easting();
+double northing_to_row();
+double easting_to_col();
+
+#undef INIT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Added: trunk/grassaddons/i.points.auto/overlap_area.c
===================================================================
--- trunk/grassaddons/i.points.auto/overlap_area.c (rev 0)
+++ trunk/grassaddons/i.points.auto/overlap_area.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,141 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static View *pick_view, *zoom_view, *main_view;
+static int target_flag;
+
+
+int overlap_area(int xp, int yp, int xs, int ys, int n_img, int ncols, int nrows)
+{
+
+ int x_1, y_1, x_2, y_2;
+ int tmp_right, tmp_left;
+ int tmp_bottom, tmp_top;
+ int tmp_ncols;
+ int tmp_nrows;
+
+ int top, bottom, left, right;
+ int row,col;
+ struct Cell_head cellhd;
+
+
+
+ if(n_img==1)
+ {
+ pick_view = VIEW_MAP1;
+ main_view = VIEW_MAP1;
+ zoom_view = VIEW_MAP1_ZOOM;
+ target_flag = 0;
+ printf("info VIEW_MAP1_ZOOM: nrows=%d ncols=%d",zoom_view->nrows,zoom_view->ncols);
+ }
+
+ else if (n_img==2)
+ {
+ pick_view = VIEW_MAP2;
+ main_view = VIEW_MAP2;
+ zoom_view = VIEW_MAP2_ZOOM;
+ target_flag = 1;
+ }
+
+ else
+ return 0;
+ if (!pick_view->cell.configured) return 0; /* just to be sure */
+
+
+ tmp_right = pick_view->cell.right;
+ tmp_left = pick_view->cell.left;
+ tmp_ncols = (tmp_right - tmp_left);
+
+ tmp_bottom = pick_view->cell.bottom;
+ tmp_top = pick_view->cell.top;
+ tmp_nrows = (tmp_bottom - tmp_top);
+
+
+ x_1 = ((tmp_ncols*xp)/ncols);
+ y_1 = (((pick_view->nrows)*yp)/nrows);
+ x_2 = ((tmp_ncols*xs)/ncols);
+ y_2 = (((pick_view->nrows)*ys)/nrows);
+
+
+
+
+ if (x_1 == x_2 || y_1 == y_2) return 0; /* ignore event */
+
+
+
+ top = row_to_view (pick_view, y_1);
+ left = col_to_view (pick_view, x_1);
+ bottom = row_to_view (pick_view, y_2);
+ right = col_to_view (pick_view, x_2);
+
+
+ if (!In_view (pick_view,right,bottom)) return 0;
+
+
+ Menu_msg("");
+
+
+ G_copy (&cellhd, &pick_view->cell.head, sizeof(cellhd));
+
+
+ col = view_to_col(pick_view,left);
+ row = view_to_row(pick_view,top);
+ cellhd.north = row_to_northing (&pick_view->cell.head,row,0.0);
+ cellhd.west = col_to_easting (&pick_view->cell.head,col,0.0);
+
+
+ col = view_to_col(pick_view,right);
+ row = view_to_row(pick_view,bottom);
+ cellhd.south = row_to_northing (&pick_view->cell.head,row,1.0);
+ cellhd.east = col_to_easting (&pick_view->cell.head,col,1.0);
+
+
+
+ cellhd.rows = bottom-top+1;
+ cellhd.cols = right-left+1;
+ cellhd.ns_res = (cellhd.north-cellhd.south)/cellhd.rows;
+ cellhd.ew_res = (cellhd.east-cellhd.west)/cellhd.cols;
+
+ if (zoom_view->cell.configured)
+ {
+ R_standard_color (GREY);
+ Outline_cellhd (main_view, &zoom_view->cell.head);
+ }
+ R_standard_color (RED);
+ Outline_cellhd (main_view, &cellhd);
+
+ if (target_flag)
+ select_target_env();
+ G_adjust_window_to_box (&cellhd, &zoom_view->cell.head, zoom_view->nrows,
+ zoom_view->ncols);
+ Configure_view (zoom_view, pick_view->cell.name, pick_view->cell.mapset,
+ pick_view->cell.ns_res, pick_view->cell.ew_res);
+
+
+ drawcell (zoom_view);
+ select_current_env();
+ display_points(1);
+
+
+ return 0;
+
+}
+
+
+static int
+
+cancel (void)
+{
+ return -1;
+}
+
+
+
+
+
+
+
+
+
+
Property changes on: trunk/grassaddons/i.points.auto/overlap_area.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/points.c
===================================================================
--- trunk/grassaddons/i.points.auto/points.c (rev 0)
+++ trunk/grassaddons/i.points.auto/points.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,184 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+int display_line (View *view, double *east, double *north,int *status,int count);
+
+int display_points (int in_color)
+{
+ display_points_in_view (VIEW_MAP1, in_color,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP1_ZOOM, in_color,
+ group.points.e1, group.points.n1,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2, in_color,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+
+ display_points_in_view (VIEW_MAP2_ZOOM, in_color,
+ group.points.e2, group.points.n2,
+ group.points.status, group.points.count);
+
+ return 0;
+}
+
+int display_points_in_view (View *view, int in_color,
+ double *east, double *north, int *status, int count)
+{
+ if (!view->cell.configured) return 1;
+ D_cell_draw_setup(view->top, view->bottom, view->left, view->right);
+ D_set_clip_window(view->top, view->bottom, view->left, view->right);
+ while (count-- > 0)
+ {
+ if (in_color && ((*status ==2)||(*status ==-2)))
+ display_line(view,east, north, status,count);
+ if (in_color && (*status > 0))
+ R_standard_color (GREEN);
+ else if (in_color && ((*status == 0)||(*status <= -2)))
+ R_standard_color (RED);
+ else
+ R_standard_color (GREEN);
+
+ status++;
+ display_one_point (view, *east++, *north++);
+ }
+
+ return 0;
+}
+
+/*The first point is displayed with BLUE, and the others with GREEN */
+int display_points_in_view_diff_color (View *view, int in_color,
+ double *east, double *north, int *status, int count)
+{
+ if (!view->cell.configured) return 1;
+ D_cell_draw_setup(view->top, view->bottom, view->left, view->right);
+ D_set_clip_window(view->top, view->bottom, view->left, view->right);
+
+ count--;
+ if (in_color && (*status > 0))
+ R_standard_color (BLUE);
+ status++;
+ display_one_point (view, *east++, *north++);
+
+
+ while (count-- > 0)
+ {
+ if (in_color && ((*status ==2)||(*status ==-2)))
+ display_line(view,east, north, status,count);
+ if (in_color && (*status > 0))
+ R_standard_color (GREEN);
+
+ else if (in_color && ((*status == 0)||(*status <= -2)))
+ R_standard_color (RED);
+ else
+ R_standard_color (GREEN);
+
+ status++;
+ display_one_point (view, *east++, *north++);
+ }
+
+ return 0;
+}
+
+
+
+/*Displays only the active points (with GREEN) */
+int display_points_in_view_diff_color_if_active (View *view, int in_color,
+ double *east, double *north, int *status, int count)
+{
+ if (!view->cell.configured) return 1;
+ D_cell_draw_setup(view->top, view->bottom, view->left, view->right);
+ D_set_clip_window(view->top, view->bottom, view->left, view->right);
+
+ count--;
+ if (in_color && (*status > 0))
+ R_standard_color (BLUE);
+ status++;
+ display_one_point (view, *east++, *north++);
+
+
+ while (count-- > 0)
+ {
+ if (in_color && (*status > 0))
+ {
+ R_standard_color (GREEN);
+ status++;
+ display_one_point (view, *east++, *north++);
+ }
+ else if (in_color && ((*status == 0)||(*status <= -2)))
+ {
+ R_standard_color (RED);
+ status++;
+ *east++;
+ *north++;
+ }
+ else
+ {
+ R_standard_color (GREEN);
+
+ status++;
+ display_one_point (view, *east++, *north++);
+ }
+
+ }
+
+ return 0;
+}
+
+
+
+
+
+
+
+
+
+
+
+int display_one_point (View *view, double east, double north)
+{
+ int row, col, x, y;
+
+ row = northing_to_row (&view->cell.head, north) + .5;
+ col = easting_to_col (&view->cell.head, east) + .5;
+ y = row_to_view (view, row);
+ x = col_to_view (view, col);
+ if (In_view(view, x, y))
+ dot (x,y);
+
+ return 0;
+}
+
+
+int display_line (View *view, double *east, double *north,int *status,int count)
+ {
+ int row, col, x[2], y[2];
+
+ if (count==0) return 1;
+ if ((*(status +1)!=3) && (*(status+1)!=-3)) return 1;
+
+ row = northing_to_row (&view->cell.head, *north) + .5;
+ col = easting_to_col (&view->cell.head, *east) + .5;
+ y[0] = row_to_view (view, row);
+ x[0] = col_to_view (view, col);
+
+ row = northing_to_row (&view->cell.head, *(north+1)) + .5;
+ col = easting_to_col (&view->cell.head, *(east+1)) + .5;
+ y[1] = row_to_view (view, row);
+ x[1] = col_to_view (view, col);
+ if (*status == 2 )
+ R_standard_color (GREEN);
+
+ else R_standard_color (RED);
+ D_move_abs(x[0],y[0]);
+ D_cont_abs(x[1],y[1]);
+ /* R_polyline_abs (x,y,2); */
+ /*plot_line(*east,*north,*(east+1),*(north+1)); */
+ R_flush();
+ }
+
+
Property changes on: trunk/grassaddons/i.points.auto/points.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/target.c
===================================================================
--- trunk/grassaddons/i.points.auto/target.c (rev 0)
+++ trunk/grassaddons/i.points.auto/target.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,71 @@
+#include
+#include
+#include "globals.h"
+
+/* read the target for the group and cast it into the alternate GRASS env */
+
+static int which_env;
+
+int get_target (void)
+{
+ char location[40];
+ char mapset[40];
+ char buf[1024];
+ int stat;
+
+ if (!I_get_target(group.name, location, mapset))
+ {
+ sprintf(buf, "Target information for group [%s] missing\n", group.name);
+ goto error;
+ }
+
+ sprintf (buf, "%s/%s", G_gisdbase(), location);
+ if (access(buf,0) != 0)
+ {
+ sprintf (buf,"Target location [%s] not found\n", location);
+ goto error;
+ }
+ G__create_alt_env();
+ G__setenv ("LOCATION_NAME", location);
+ stat = G__mapset_permissions(mapset);
+ if (stat > 0)
+ {
+ G__setenv ("MAPSET", mapset);
+ G__create_alt_search_path();
+ G__switch_env();
+ G__switch_search_path();
+ which_env = 0;
+ return 1;
+ }
+ sprintf (buf, "Mapset [%s] in target location [%s] - ",
+ mapset, location);
+ strcat (buf, stat == 0 ? "permission denied\n" : "not found\n");
+error:
+ strcat (buf, "Please run i.target for group ");
+ strcat (buf, group.name);
+ G_fatal_error (buf);
+}
+
+int select_current_env (void)
+{
+ if (which_env != 0)
+ {
+ G__switch_env();
+ G__switch_search_path();
+ which_env = 0;
+ }
+
+ return 0;
+}
+
+int select_target_env (void)
+{
+ if (which_env != 1)
+ {
+ G__switch_env();
+ G__switch_search_path();
+ which_env = 1;
+ }
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/target.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/title.c
===================================================================
--- trunk/grassaddons/i.points.auto/title.c (rev 0)
+++ trunk/grassaddons/i.points.auto/title.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,56 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+int
+display_title (View *view)
+{
+ View *title;
+ char left[100], center[100];
+ int size;
+ double magnification();
+
+ *left = 0;
+ *center = 0;
+
+ if (view->cell.configured)
+ {
+ sprintf (center, "%s (mag %.1f)",
+ view->cell.name, magnification (view));
+ }
+
+ if (view == VIEW_MAP1)
+ {
+ sprintf (left, "%s", G_location());
+ title = VIEW_TITLE1;
+ }
+ else if (view == VIEW_MAP1_ZOOM)
+ {
+ title = VIEW_TITLE1_ZOOM;
+ }
+
+ if (view == VIEW_MAP2)
+ {
+ sprintf (left, "%s", G_location());
+ title = VIEW_TITLE2;
+ }
+ else if (view == VIEW_MAP2_ZOOM)
+ {
+ title = VIEW_TITLE2_ZOOM;
+ }
+
+ Erase_view (title);
+ R_standard_color (ORANGE); /*WHITE*/
+ size = title->nrows - 4;
+ R_text_size (size, size);
+ Text (left, title->top, title->bottom, title->left, title->right, 2);
+ if (*center)
+ {
+ R_standard_color (YELLOW);
+ Text (center, title->top, title->bottom,
+ (title->left + title->right - Text_width (center)) / 2,
+ title->right, 2);
+ }
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/title.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/view.c
===================================================================
--- trunk/grassaddons/i.points.auto/view.c (rev 0)
+++ trunk/grassaddons/i.points.auto/view.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,57 @@
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+int Configure_view (
+ View *view,
+ char *name,
+ char *mapset,
+ double ns_res,
+ double ew_res /* original map resolution */
+)
+{
+ Erase_view(view);
+ view->cell.configured = 0;
+
+/* copy the cell name into the view */
+ strcpy (view->cell.name, name);
+ strcpy (view->cell.mapset, mapset);
+
+/* determine the map edges */
+ view->cell.left = view->left + (view->ncols - view->cell.head.cols)/2;
+ view->cell.right = view->cell.left + view->cell.head.cols - 1;
+ view->cell.top = view->top + (view->nrows - view->cell.head.rows)/2;
+ view->cell.bottom = view->cell.top + view->cell.head.rows - 1;
+
+/* remember original resolutions */
+ view->cell.ns_res = ns_res;
+ view->cell.ew_res = ew_res;
+
+ view->cell.configured = 1;
+
+ return 0;
+}
+
+int
+In_view (View *view, int x, int y)
+{
+ return (x >= view->left && x <= view->right && y >= view->top && y <= view->bottom);
+}
+
+int
+Erase_view (View *view)
+{
+ R_standard_color (BLUE);
+ R_box_abs (view->left, view->top, view->right, view->bottom);
+
+ return 0;
+}
+
+double
+magnification (View *view)
+{
+ if (!view->cell.configured)
+ return ((double) 0.0);
+ return (view->cell.ew_res / view->cell.head.ew_res);
+}
Property changes on: trunk/grassaddons/i.points.auto/view.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/where.c
===================================================================
--- trunk/grassaddons/i.points.auto/where.c (rev 0)
+++ trunk/grassaddons/i.points.auto/where.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,66 @@
+#include "globals.h"
+#include "local_proto.h"
+
+static int where_12 (View *,int,int);
+static int where_21 (View *,int,int);
+static int where_am_i (View *,int,int,Window *,double *,double *,Window *);
+
+int where (int x, int y)
+{
+ if (VIEW_MAP1->cell.configured && In_view (VIEW_MAP1, x, y))
+ where_12 (VIEW_MAP1, x, y);
+ else if (VIEW_MAP1_ZOOM->cell.configured && In_view (VIEW_MAP1_ZOOM, x, y))
+ where_12 (VIEW_MAP1_ZOOM, x, y);
+ else if (VIEW_MAP2->cell.configured && In_view (VIEW_MAP2, x, y))
+ where_21 (VIEW_MAP2, x, y);
+ else if (VIEW_MAP2_ZOOM->cell.configured && In_view (VIEW_MAP2_ZOOM, x, y))
+ where_21 (VIEW_MAP2_ZOOM, x, y);
+ return 0 ; /* return but don't quit */
+}
+
+static int where_12 (View *view,int x, int y)
+{
+ where_am_i (view, x, y, MENU_WINDOW, group.E12, group.N12, INFO_WINDOW);
+
+ return 0;
+}
+
+static int where_21 (View *view,int x, int y)
+{
+ where_am_i (view, x, y, INFO_WINDOW, group.E21, group.N21, MENU_WINDOW);
+
+ return 0;
+}
+
+static int where_am_i (View *view,int x, int y,Window *w1,
+ double *E,double *N,Window *w2)
+{
+ double e1,n1,e2,n2;
+ int row,col;
+
+ char buf[100];
+
+/* convert x,y to east,north at center of cell */
+ col = view_to_col (view, x);
+ e1 = col_to_easting (&view->cell.head, col, 0.5);
+ row = view_to_row (view, y);
+ n1 = row_to_northing (&view->cell.head, row, 0.5);
+
+ Curses_clear_window (w1);
+ sprintf (buf, "East: %10.2f", e1);
+ Curses_write_window (w1, 3, 3, buf);
+ sprintf (buf, "North: %10.2f", n1);
+ Curses_write_window (w1, 4, 3, buf);
+
+/* if transformation equation is useable, determine point via equation */
+ if (group.equation_stat <= 0) return 1;
+
+ I_georef (e1, n1, &e2, &n2, E, N);
+ Curses_clear_window (w2);
+ sprintf (buf, "East: %10.2f", e2);
+ Curses_write_window (w2, 3, 3, buf);
+ sprintf (buf, "North: %10.2f", n2);
+ Curses_write_window (w2, 4, 3, buf);
+
+ return 0;
+}
Property changes on: trunk/grassaddons/i.points.auto/where.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/zoom.c
===================================================================
--- trunk/grassaddons/i.points.auto/zoom.c (rev 0)
+++ trunk/grassaddons/i.points.auto/zoom.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,53 @@
+#include "globals.h"
+#include "local_proto.h"
+
+static int cancel();
+static int use_zoom_box = 1;
+static int use_zoom_pnt = 0;
+
+
+
+int zoom()
+{
+ static int use = 1;
+ int cancel();
+ /*static int which_zoom();*/
+
+ static Objects objects[]=
+ {
+ MENU("CANCEL",cancel,&use),
+ INFO("Current ZOOM Type.",&use),
+ OPTION("BOX", 2, &use_zoom_box),
+ OPTION("POINT", 2, &use_zoom_pnt),
+ OTHER(which_zoom, &use),
+ {0}
+ };
+
+ Input_pointer (objects);
+ return 0; /* return, but don't QUIT */
+}
+
+static int
+which_zoom(int x,int y,int button)
+{
+
+ /* Button one to set point, Button 2 & 3 return location */
+ if (button != 1)
+ return where (x,y);
+
+
+ if (use_zoom_box == 1)
+ zoom_box(x,y);
+ else zoom_pnt(x,y);
+
+ return 0;
+}
+
+
+
+
+static int
+cancel (void)
+{
+ return -1;
+}
Property changes on: trunk/grassaddons/i.points.auto/zoom.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/zoom_box.c
===================================================================
--- trunk/grassaddons/i.points.auto/zoom_box.c (rev 0)
+++ trunk/grassaddons/i.points.auto/zoom_box.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,193 @@
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+
+static int zoom2(int,int);
+static int cancel(void);
+
+static int x1, y1, x2, y2;
+static View *pick_view, *zoom_view, *main_view;
+static int target_flag;
+
+
+
+int zoom_box (int x,int y) /* called by Input_pointer */
+{
+ static int use = 1;
+ int zoom2();
+ int cancel();
+
+ static Objects objects[] =
+ {
+ MENU("CANCEL",cancel,&use),
+ INFO(" Define the region ",&use),
+ OTHER(zoom2,&use),
+ {0}
+ };
+
+/*
+ * user has marked first corner
+ * this determines which view is being zoomed
+ */
+ x1 = x;
+ y1 = y;
+
+ if (In_view (pick_view = VIEW_MAP1, x1, y1))
+ {
+ main_view = VIEW_MAP1;
+ zoom_view = VIEW_MAP1_ZOOM;
+ target_flag = 0;
+ printf("info VIEW_MAP1_ZOOM: nrows=%d ncols=%d",zoom_view->nrows,zoom_view->ncols);
+ }
+ else if (In_view (pick_view = VIEW_MAP2, x1, y1))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP2;
+ zoom_view = VIEW_MAP2_ZOOM;
+ target_flag = 1;
+ }
+ else if (In_view (pick_view = VIEW_MAP1_ZOOM, x1, y1))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP1;
+ zoom_view = VIEW_MAP1_ZOOM;
+ target_flag = 0;
+ }
+ else if (In_view (pick_view = VIEW_MAP2_ZOOM, x1, y1))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP2;
+ zoom_view = VIEW_MAP2_ZOOM;
+ target_flag = 1;
+ }
+ else
+ return 0; /* ignore the mouse event */
+ if (!pick_view->cell.configured) return 0; /* just to be sure */
+
+ return Input_box (objects, x, y);
+}
+
+
+
+
+static int zoom2(int x,int y)
+{
+ int top, bottom, left, right;
+ int row,col;
+ struct Cell_head cellhd;
+
+ x2 = x;
+ y2 = y;
+/*
+ * user has completed the zoom window.
+ * must be in same view as first corner
+ */
+
+ if (x1 == x2 || y1 == y2) return 0; /* ignore event */
+ if (!In_view (pick_view,x2,y2)) return 0;
+
+/*
+ * ok, erase menu messages
+ */
+
+ Menu_msg("");
+
+/*
+ * assign window coordinates to top,bottom,left,right
+ */
+ if (x1 < x2)
+ {
+ left = x1;
+ right = x2;
+ }
+ else
+ {
+ left = x2;
+ right = x1;
+ }
+ if (y1 < y2)
+ {
+ top = y1;
+ bottom = y2;
+ }
+ else
+ {
+ top = y2;
+ bottom = y1;
+ }
+
+/*
+ * Determine the zoom window (ie, cellhd)
+ * must copy the current view cellhd first, to preserve header info
+ * (such as projection, zone, and other items.)
+ * compute zoom window northings,eastings, rows, cols, and resolution
+ */
+
+ G_copy (&cellhd, &pick_view->cell.head, sizeof(cellhd));
+
+/*
+ * convert top to northing at top edge of cell
+ * left to easting at left edge
+ */
+ col = view_to_col(pick_view,left);
+ row = view_to_row(pick_view,top);
+ cellhd.north = row_to_northing (&pick_view->cell.head,row,0.0);
+ cellhd.west = col_to_easting (&pick_view->cell.head,col,0.0);
+
+/*
+ * convert bottom to northing at bottom edge of cell
+ * right to easting at right edge
+ */
+ col = view_to_col(pick_view,right);
+ row = view_to_row(pick_view,bottom);
+ cellhd.south = row_to_northing (&pick_view->cell.head,row,1.0);
+ cellhd.east = col_to_easting (&pick_view->cell.head,col,1.0);
+
+
+ cellhd.rows = bottom-top+1;
+ cellhd.cols = right-left+1;
+ cellhd.ns_res = (cellhd.north-cellhd.south)/cellhd.rows;
+ cellhd.ew_res = (cellhd.east-cellhd.west)/cellhd.cols;
+
+/*
+ * Outline the zoom window on the main map
+ * Turn previous one to grey.
+ */
+ if (zoom_view->cell.configured)
+ {
+ R_standard_color (GREY);
+ Outline_cellhd (main_view, &zoom_view->cell.head);
+ }
+ R_standard_color (RED);
+ Outline_cellhd (main_view, &cellhd);
+
+
+/*
+ * zoom
+ */
+ if (target_flag)
+ select_target_env();
+ G_adjust_window_to_box (&cellhd, &zoom_view->cell.head, zoom_view->nrows,
+ zoom_view->ncols);
+ Configure_view (zoom_view, pick_view->cell.name, pick_view->cell.mapset,
+ pick_view->cell.ns_res, pick_view->cell.ew_res);
+
+
+
+ drawcell (zoom_view);
+ select_current_env();
+ display_points(1);
+ return 1; /* pop back */
+
+}
+
+static int
+
+cancel (void)
+{
+ return -1;
+}
Property changes on: trunk/grassaddons/i.points.auto/zoom_box.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/grassaddons/i.points.auto/zoom_pnt.c
===================================================================
--- trunk/grassaddons/i.points.auto/zoom_pnt.c (rev 0)
+++ trunk/grassaddons/i.points.auto/zoom_pnt.c 2007-10-21 08:38:25 UTC (rev 1152)
@@ -0,0 +1,179 @@
+#include
+#include
+#include
+#include
+#include "globals.h"
+#include "local_proto.h"
+
+static int cancel(void);
+
+static View *pick_view, *zoom_view, *main_view;
+static int target_flag;
+
+int zoom_pnt (int x,int y) /* called by Input_pointer */
+{
+ int top, bottom, left, right;
+ int n,row,col;
+ int nrows, ncols;
+ struct Cell_head cellhd;
+ int mag;
+ double magnification();
+ double north, south, east, west;
+
+ if (In_view (pick_view = VIEW_MAP1, x, y))
+ {
+ main_view = VIEW_MAP1;
+ zoom_view = VIEW_MAP1_ZOOM;
+ target_flag = 0;
+ }
+ else if (In_view (pick_view = VIEW_MAP2, x, y))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP2;
+ zoom_view = VIEW_MAP2_ZOOM;
+ target_flag = 1;
+ }
+ else if (In_view (pick_view = VIEW_MAP1_ZOOM, x, y))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP1;
+ zoom_view = VIEW_MAP1_ZOOM;
+ target_flag = 0;
+ }
+ else if (In_view (pick_view = VIEW_MAP2_ZOOM, x, y))
+ {
+ if (!pick_view->cell.configured)
+ return 0; /* ignore the mouse event */
+ main_view = VIEW_MAP2;
+ zoom_view = VIEW_MAP2_ZOOM;
+ target_flag = 1;
+ }
+ else
+ return 0; /* ignore the mouse event */
+ if (!pick_view->cell.configured) return 0; /* just to be sure */
+/*
+ * make sure point is within edges of image as well
+ */
+ if (x <= pick_view->cell.left) return 0;
+ if (x >= pick_view->cell.right) return 0;
+ if (y <= pick_view->cell.top) return 0;
+ if (y >= pick_view->cell.bottom) return 0;
+
+
+/*
+ * ok, erase menu messages
+ */
+ Menu_msg("");
+
+/* determine magnification of zoom */
+ if (zoom_view->cell.configured)
+ {
+ if (zoom_view == pick_view)
+ mag = floor(magnification (zoom_view) + 1.0) + .1;
+ else
+ mag = ceil(magnification (zoom_view)) + .1;
+ }
+ else
+ {
+ mag = floor(magnification (main_view) + 1.0) + .1;
+ }
+ if(!ask_magnification (&mag))
+ return 1;
+/*
+ * Determine the the zoom window (ie, cellhd)
+ */
+
+ G_copy (&cellhd, &main_view->cell.head, sizeof(cellhd));
+ cellhd.ns_res = main_view->cell.ns_res / mag;
+ cellhd.ew_res = main_view->cell.ew_res / mag;
+ cellhd.cols = (cellhd.east - cellhd.west) / cellhd.ew_res;
+ cellhd.rows = (cellhd.north - cellhd.south) / cellhd.ns_res;
+
+
+/* convert x,y to col,row */
+
+ col = view_to_col(pick_view,x);
+ east = col_to_easting (&pick_view->cell.head, col, 0.5);
+ col = easting_to_col (&cellhd, east);
+
+ row = view_to_row(pick_view,y);
+ north = row_to_northing (&pick_view->cell.head, row, 0.5);
+ row = northing_to_row (&cellhd, north);
+
+ ncols = zoom_view->ncols ;
+ nrows = zoom_view->nrows ;
+
+
+ n = cellhd.cols - col;
+ if (n > col)
+ n = col;
+ if (n+n+1 >= ncols)
+ {
+ n = ncols/2;
+ if (n+n+1 >= ncols) n--;
+ }
+ left = col - n;
+ right = col + n;
+
+ n = cellhd.rows - row;
+ if (n > row)
+ n = row;
+ if (n+n+1 >= nrows)
+ {
+ n = nrows/2;
+ if (n+n+1 >= nrows) n--;
+ }
+ top = row - n;
+ bottom = row + n;
+
+
+ north = row_to_northing (&cellhd, top,0.0);
+ west = col_to_easting (&cellhd,left,0.0);
+ south = row_to_northing (&cellhd,bottom,1.0);
+ east = col_to_easting (&cellhd,right,1.0);
+
+
+ cellhd.north = north;
+ cellhd.south = south;
+ cellhd.east = east ;
+ cellhd.west = west ;
+
+ cellhd.rows = (cellhd.north-cellhd.south)/cellhd.ns_res;
+ cellhd.cols = (cellhd.east-cellhd.west)/cellhd.ew_res ;
+
+/*
+ * Outline the zoom window on the main map
+ * Turn previous one to grey.
+ */
+ if (zoom_view->cell.configured)
+ {
+ R_standard_color (GREY);
+ Outline_cellhd (main_view, &zoom_view->cell.head);
+ }
+ R_standard_color (RED);
+ Outline_cellhd (main_view, &cellhd);
+
+
+/*
+ * zoom
+ */
+ if (target_flag)
+ select_target_env();
+ G_copy (&zoom_view->cell.head, &cellhd, sizeof (cellhd));
+ Configure_view (zoom_view, pick_view->cell.name, pick_view->cell.mapset,
+ pick_view->cell.ns_res, pick_view->cell.ew_res);
+ drawcell (zoom_view);
+ select_current_env();
+ display_points(1);
+
+ return 1; /* pop back */
+}
+
+
+static int
+cancel (void)
+{
+ return -1;
+}
Property changes on: trunk/grassaddons/i.points.auto/zoom_pnt.c
___________________________________________________________________
Name: svn:eol-style
+ native
From neteler at grass.itc.it Sun Oct 21 10:42:42 2007
From: neteler at grass.itc.it (neteler@grass.itc.it)
Date: Thu Oct 25 01:43:48 2007
Subject: [grass-addons] r1153 - in trunk/grassaddons: . i.homography
Message-ID: <200710210842.l9L8gg4b031483@grass.itc.it>
Author: neteler
Date: 2007-10-21 10:42:42 +0200 (Sun, 21 Oct 2007)
New Revision: 1153
Added:
trunk/grassaddons/i.homography/
trunk/grassaddons/i.homography/Makefile
trunk/grassaddons/i.homography/TODO
trunk/grassaddons/i.homography/func.h
trunk/grassaddons/i.homography/global.h
trunk/grassaddons/i.homography/lu.c
trunk/grassaddons/i.homography/main.c
trunk/grassaddons/i.homography/matrix.c
trunk/grassaddons/i.homography/open.c
trunk/grassaddons/i.homography/pi.c
Log:
image rectification based on homography
Added: trunk/grassaddons/i.homography/Makefile
===================================================================
--- trunk/grassaddons/i.homography/Makefile (rev 0)
+++ trunk/grassaddons/i.homography/Makefile 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,10 @@
+MODULE_TOPDIR = ../..
+
+PGM = i.homography
+
+LIBES = $(IMAGERYLIB) $(GPROJLIB) $(GISLIB) $(VASKLIB) $(CURSES) $(GMATHLIB)
+DEPENDENCIES= $(IMAGERYDEP) $(GPROJDEP) $(GISDEP) $(VASKDEP) $(GMATHDEP)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd
Added: trunk/grassaddons/i.homography/TODO
===================================================================
--- trunk/grassaddons/i.homography/TODO (rev 0)
+++ trunk/grassaddons/i.homography/TODO 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,12 @@
+Compile with
+ make MODULE_TOPDIR=$HOME/grass63/
+
+TODO
+
+Code based on GRASS 5. To be updated to GRASS 6.
+
+The brent() function in this modules must
+be changed to grass63/lib/gmath/brent.c
+due to copyright problems.
+
+
Added: trunk/grassaddons/i.homography/func.h
===================================================================
--- trunk/grassaddons/i.homography/func.h (rev 0)
+++ trunk/grassaddons/i.homography/func.h 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,191 @@
+/*
+bootstrap.c
+*/
+
+int Bootsamples();
+
+/*
+random.c
+*/
+
+double ran1();
+double gasdev();
+
+/*
+blob.c
+*/
+
+void extract_sites_from_blob();
+void find_blob();
+
+/*
+tree.c
+*/
+
+int build_maximal_tree();
+void write_tree();
+int read_tree();
+int godown();
+void write_Btree();
+int read_Btree();
+double evaluateB();
+int evaluateB_multiclass();
+void classify_image_TREE();
+
+/*
+training.c
+*/
+
+void build_training();
+
+/*
+percent.c
+*/
+
+void percent ();
+
+/*
+open.c
+*/
+
+int open_new_CELL();
+int open_new_DCELL();
+
+/*
+pca.c
+*/
+
+void alloc_pca();
+void write_pca();
+void read_pca();
+
+/*
+dist.c
+*/
+
+double squared_distance();
+double euclidean_distance();
+double scalar_product();
+double euclidean_norm();
+
+/*
+getline.c
+*/
+
+char *GetLine();
+
+/*
+pi.c
+*/
+
+void linear_solve();
+
+/*
+read_list.c
+*/
+
+void read_list_of_type_1_and_load_raster_maps();
+void read_list_of_type_2();
+void read_list_of_type_2_and_load_raster_maps();
+int read_list_of_sites();
+
+/*
+filter.c
+*/
+
+void write_filter();
+void read_filter();
+
+/*
+test.c
+*/
+
+void ksone_normal();
+void kstwo();
+double normal_distribution();
+double cumulative_normal_distribution();
+
+/*
+nn.c
+*/
+
+void classify_image_NN();
+void write_nn();
+void read_nn();
+void compute_NN_from_training();
+void read_matrix();
+
+/*
+integration.c
+*/
+
+double trapzd();
+double trapzd1();
+double trapzd2();
+double qtrap();
+double qtrap1();
+double qtrap2();
+
+/*
+gm.c
+*/
+
+void compute_gm();
+void write_gm();
+void read_gm();
+double ComputeDelta();
+void classify_image_GM();
+
+/*
+sort.c
+*/
+
+void shell();
+void indexx_1();
+void indexx();
+
+/*
+eigen.c
+*/
+
+void tred2();
+int tqli();
+int eigen_of_double_matrix();
+void eigsrt();
+
+/*
+matrix.c
+*/
+
+void product_double_matrix_double_matrix();
+void product_double_matrix_double_vector();
+void product_double_vector_double_matrix();
+void transpose_double_matrix();
+void double_matrix_to_vector();
+void extract_portion_of_double_matrix();
+void transpose_double_matrix_rectangular();
+
+/*
+lu.c
+*/
+
+void ludcmp();
+void lubksb();
+void inverse_of_double_matrix();
+double determinant_of_double_matrix();
+
+/*
+stats.c
+*/
+
+double mean_of_double_array();
+double var_of_double_array();
+double sd_of_double_array();
+double var_of_double_array_given_mean();
+double sd_of_double_array_given_mean();
+void mean_and_var_of_double_matrix_by_row();
+void mean_and_sd_of_double_matrix_by_row();
+void mean_and_var_of_double_matrix_by_col();
+void mean_and_sd_of_double_matrix_by_col();
+double auto_covariance_of_2_double_array();
+void covariance_of_double_matrix();
Added: trunk/grassaddons/i.homography/global.h
===================================================================
--- trunk/grassaddons/i.homography/global.h (rev 0)
+++ trunk/grassaddons/i.homography/global.h 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,212 @@
+/*****
+ list of RASTERLISTTYPE1
+
+ name1 class1
+ name2 class2
+ ... ...
+*****/
+
+/*****
+ list of RASTERLISTTYPE2
+
+ name1 additional_name1 moments1
+ name2 additional_name2 moments2
+ ... ... ...
+*****/
+
+/*****
+ classification CLASSIFICATION1
+
+ given a list RASTERLISTTYPE1, optionally build a filter,
+ build the pca model, transform data in pc space,
+ compute a gaussian mixture
+*****/
+
+/*****
+ classification CLASSIFICATION2
+
+ given a list RASTERLISTTYPE2, use a list of sites as training,
+ build a window round each site, using the moments compute mean
+ or mean and var of the value of the raster maps within the
+ window to form predictor variables, compute a gaussian mixture
+ or a nearest neighbour model
+*****/
+
+
+#include "gis.h"
+#include "func.h"
+#include "site.h"
+
+#define PIG 3.141593
+
+#define TRUE 1
+#define FALSE 0
+
+#define GaussianMixture 1
+#define NearestNeighbour 2
+
+#define TREE 1
+#define BOOSTING 2
+#define BAGGING 3
+
+typedef struct
+/*manegement of list of type 1*/
+{
+ char **mapnames; /*array of raster map names*/
+ char **mapclass; /*class of each raster map*/
+ int nsamples; /*number of raster map*/
+ int rows; /*rows number of each raster map*/
+ int cols; /*cols number of each raster map*/
+ double **samples; /*for each map, the values of the map stored in an array
+ of length rows x cols*/
+} Maps;
+
+typedef struct
+/*manegement of list of type 2*/
+{
+ char **mapnames; /*array of raster map names*/
+ char **varnames; /*additional name for each raster map*/
+ int nvar; /*number of raster maps*/
+ int rows; /*rows number of each raster map*/
+ int cols; /*cols number of each raster map*/
+ int *moments; /*for each map, the number of moments of the distribution
+ to be considered for the classification:
+ 1 = mean
+ 2 = mean and var*/
+ double ***mapvalues; /*for each map, the values of the map stored in a matrix
+ of dimension rows x cols*/
+} Variables;
+
+typedef struct
+/*manegement of lists of site files*/
+{
+ char *name; /*name of site file*/
+ Site **sites; /*sites contained within the site file*/
+ int nsites; /*number of sites*/
+} ListSite;
+
+
+typedef struct
+/*filter structure, usually considered as average of matricial examples
+ (usually small raster maps)*/
+{
+ int rows; /*rows number of the filter*/
+ int cols; /*cols number of the filter*/
+ double **values; /*values of the filter, stored in a matrix
+ of dimension rows x cols*/
+} Filter;
+
+typedef struct
+/*principal components structure. Examples are in matricial form
+ (usually small raster maps) but matricial examples are here
+ considered as array of length rows x cols*/
+{
+ int rows; /*rows number of the raster maps used to build the PC model*/
+ int cols; /*cols number of the raster maps used to build the PC model*/
+ double *mean; /*the mean value of the examples, stored in an
+ array of dimension rows x cols*/
+ double *sd; /*the standard deviation of the examples, stored in an
+ array of dimension rows x cols*/
+ double **covar; /*covariance matrix of the examples, stored in a
+ matrix of dimension (rows x cols)^2*/
+ double *eigval; /*eigenvalues of the covariance matrix*/
+ double **eigmat; /*eigenvectors matrix of the covariance matrix.
+ Each column is the eigenvector corresponding to
+ an eigenvalues*/
+ int correlation; /*boolean:
+ 0 = covariance matrix computed
+ 1 = correlation matrix computed*/
+ int standardize; /*boolean:
+ 0 = examples are not standardized
+ 1 = examples are standardized: E <- (E-mean(E))/sd(E)*/
+} Pca;
+
+typedef struct
+/*gaussian mixture models structure*/
+{
+ int nclasses; /*number of classes*/
+ char **classes; /*array of the class names*/
+ int *nsamples; /*number of examples contained in each class*/
+ int nvars; /*number of predictor variables*/
+ double **mean; /*for each class, the mean value of the examples stored
+ in an array of length nvars*/
+ double ***covar; /*for each class, the covariance matrix of the esamples
+ stored in a matrix of dimension nvars x nvars*/
+ double ***inv_covar; /*for each class, the inverse of the covariance matrix
+ stored in a matrix of dimension nvars x nvars*/
+ double *priors; /* prior probabilities of each class*/
+ double *det; /*for each class, the determinant of the inverse of the
+ covariance matrix*/
+} NormalModel;
+
+typedef struct
+/*Non-intuitive structure: is almost always derived from
+ the ListSite and Variables structures*/
+{
+ int nclasses; /*number of classes*/
+ int *number_of_data_for_class; /*number of elements of each class*/
+ int rows; /*rows number to be considered for building the window
+ around each site*/
+ int cols; /*cols number to be considered for building the window
+ around each site*/
+ int nsites; /*number of sites*/
+ double ****trdata; /*for each raster map, for each class,
+ for each sample within the class,
+ the values of the raster map contained within the
+ window and stored in an array of length rows*cols
+ = window size */
+} Training;
+
+typedef struct
+/*nearest neighbour structure*/
+{
+ int nsites; /*number of examples*/
+ int nvar; /*number of predictor variables*/
+ double **values; /* for each example, the values of the predictors*/
+ char **classes; /* array of the classes of each example*/
+ int *num_classes; /*array of the classes of each example
+ in integer format (for compatibility)*/
+} NN;
+
+typedef struct
+{
+ double **data;
+ char **classes;
+ int npoints;
+ int nvar;
+
+ int nclasses;
+
+
+ int *npoints_for_class;
+ double *priors;
+ char *class;
+
+
+ int terminal;
+
+ int left;
+ int right;
+ int var;
+ double value;
+} Node;
+
+typedef struct
+/*indeces of a matrix (row,col) and blob thay belog to (number)*/
+{
+ int row; /*row index of a point belonging to a blob*/
+ int col; /*row index of a point belonging to a blob*/
+ int number /* blob number the point belong to*/;
+} Blob;
+
+typedef struct
+/*geographical coordinates of the center of a blob and minimum
+ value of the blob itself*/
+{
+ double east; /*east value of the center*/
+ double north; /*north value of the center*/
+ double min; /*minimum value of the blob*/
+ int n; /*number of points whitin the blob*/
+} BlobSites;
+
+
Added: trunk/grassaddons/i.homography/lu.c
===================================================================
--- trunk/grassaddons/i.homography/lu.c (rev 0)
+++ trunk/grassaddons/i.homography/lu.c 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,192 @@
+/*
+ Some of the following routines are borrowed from "Numerical Recipes in C"
+ other are written and tested by Stefano Merler
+
+ for
+
+ LU matrix decomposition, linear equation solution (Ax=b), inversion
+ of matrices and deteminant computation
+*/
+
+#include
+#include
+#include
+
+
+#define CTINY 1.0e-32
+
+void ludcmp(a,n,indx,d)
+ /*
+ LU decomposition of n x n matrix a.
+ */
+ int n,*indx;
+ double **a,*d;
+{
+ int i,imax=0,j,k;
+ double big,dum,sum,temp;
+ double *vv;
+
+ vv=(double *)calloc(n,sizeof(double));
+ *d=1.0;
+ for (i=0;ibig) big=temp;
+ if (big==0.0)
+ { fprintf(stderr,"Singular matrix in routine ludcmp\n");
+ exit(1);
+ }
+ vv[i]=1.0/big;
+ }
+ for (j=0;j=big)
+ {
+ big=dum;
+ imax=i;
+ }
+ }
+ if (j!=imax)
+ {
+ for (k=0;k=0)
+ for (j=ii;j<=i-1;j++) sum -=a[i][j]*b[j];
+ else if (sum!=0.0) ii=i;
+ b[i]=sum;
+ }
+ for (i=n-1;i>=0;i--)
+ {
+ sum=b[i];
+ for (j=i+1;j=v2). Read the file COPYING that comes with GRASS
+* for details.
+*
+*****************************************************************************/
+#include
+#include
+#include
+#include
+#include
+#include "gis.h"
+#include "global.h"
+#include "imagery.h"
+#include "gprojects.h"
+
+/* #define DEBUG 1 */
+
+#define ITMAX 20000
+#define CGOLD 0.3819660
+#define ZEPS 1.0e-10
+
+#define SIGN(a,b) ((b) > 0.0 ? fabs(a) : -fabs(a))
+#define SHFT(a,b,c,d) (a)=(b); (b)=(c); (c)=(d);
+
+void coords();
+void show_env();
+void select_target_env();
+void select_current_env();
+void proj();
+void georef_window ();
+void points_to_line (double e1, double n1, double e2, double n2, double *t, double *u);
+
+static int which_env = -1;
+
+static double offsetx /*= 1660000.0*/;
+static double offsety/* = 5100000.0*/;
+
+FILE *file_test;
+
+
+
+
+int main(int argc, char *argv[])
+{
+ struct Option *opt1;
+ struct Option *opt2;
+ struct Option *opt3;
+ struct Option *opt4;
+ struct Option *opt5;
+ char risp[100];
+ char *input_name;
+ char *output_name;
+ char *output_location;
+ char *output_mapset;
+ char *input_group;
+ char *data_location;
+ int i,j,k;
+ int permissions;
+ char *setname;
+ char tempbuf[1000];
+ double PROJECTIVE[9];
+ double I_PROJECTIVE[9];
+ char *input_mapset;
+ char *input_location;
+ struct Cell_head input_cellhd;
+ struct Cell_head output_cellhd;
+ int outfd,infd;
+ DCELL *output_cell;
+ CELL *rowbuf;
+ int **matrix;
+ double e,n;
+ int x,y;
+ double translated_n;
+ double translated_w;
+ struct Control_Points cp;
+ int r,c,rp;
+ double **A;
+ double *X,*Y;
+ double newE,newN;
+ double error;
+ double t1, u1,t2,u2;
+ double err_test_RMS=0;
+ double x1,y1,x2,y2,homography_x2,homography_y2, diff_x2,diff_y2;
+ double p_optimal;
+ double parziale;
+ int stampa=0;
+
+ double estimate (double parameter) {
+
+ j=0;
+ for(i=0;ikey = "input";
+ opt1->type = TYPE_STRING;
+ opt1->required = YES;
+ opt1->gisprompt = "old,cell,raster" ;
+ opt1->description = "input raster map to be rectified";
+
+ opt2 = G_define_option();
+ opt2->key = "output";
+ opt2->type = TYPE_STRING;
+ opt2->required = YES;
+ opt2->gisprompt = "new,cell,raster" ;
+ opt2->description = "output raster map of the rectified map";
+
+ opt3 = G_define_option();
+ opt3->key = "location";
+ opt3->type = TYPE_STRING;
+ opt3->required = YES;
+ opt3->description = "location of the rectified raster map";
+
+ opt4 = G_define_option();
+ opt4->key = "mapset";
+ opt4->type = TYPE_STRING;
+ opt4->required = YES;
+ opt4->description = "mapset of the rectified raster map";
+
+ opt5 = G_define_option() ;
+ opt5->key = "group";
+ opt5->type = TYPE_STRING;
+ opt5->required = YES;
+ opt5->description= "input group containing points for homography computation";
+
+
+ /***** Start of main *****/
+
+ if (G_parser(argc, argv))
+ exit(-1);
+
+ input_name = opt1->answer;
+ output_name = opt2->answer;
+ output_location = opt3->answer;
+ output_mapset = opt4->answer;
+ input_group = opt5->answer;
+
+ input_mapset=G_find_cell2 (input_name, "");
+ setname = output_location ? output_mapset : G_store(G_mapset());
+ input_location=G_location();
+ data_location=G_gisdbase();
+
+ /*sprintf(tempbuf,"cp %s/%s/%s/colr/%s %s/%s/%s/colr/%s",data_location,
+ input_location, input_mapset,input_name,data_location,
+ output_location,output_mapset,output_name); */
+ G_debug(3,"%s/%s/%s/cell/%s %s/%s/%s/cell/%s",data_location,
+ input_location, input_mapset,input_name,data_location,
+ output_location,output_mapset,output_name);
+
+ /* READ POINTS*/
+ if(!I_find_group(input_group)){
+ fprintf(stderr,"Group %s not in current mapset\n",input_group);
+ exit(0);
+ }
+
+ I_get_control_points(input_group,&cp);
+
+#ifdef DEBUG
+ for(i=0;i yes, everything else --> no \n");
+ scanf("%1c",risp);
+
+ if (risp[0] == 'y')
+ {
+ file_test=fopen ("TEST_SET","r");
+ if(file_test==NULL) G_fatal_error("File 'TEST_SET' not found.");
+ }
+ while (risp[0]!='\n') scanf("%1c",risp);
+
+
+
+ /*COMPUTE PROJECTIVE PARAMETERS*/
+
+ if (cp.count == 0)
+ exit(-1);
+
+/*offsetx = cp.e2[0] - 10000;
+ offsety = cp.n2[0] - 10000;*/
+
+ i=0;
+ while(cp.status[i]!=1 && i < cp.count)
+ i++;
+ if(i >=cp.count && cp.status[i]!=1)
+ i=0;
+ offsetx = cp.e2[i] - cp.e1[i];
+ offsety = cp.n2[i] - cp.n1[i];
+
+ r=0;
+ for(i=0;i=0)
+ fprintf (stdout,"Computing...\n");
+
+ /*OPEN RASTER FILE IN THE TARGET LOCATION*/
+ G_get_window (&output_cellhd);
+ G_set_window (&output_cellhd);
+ outfd = open_new_DCELL(output_name);
+ if (outfd < 0)
+ return 0;
+ output_cell=G_allocate_d_raster_buf();
+
+
+ /*COMPUTE RECTIFICATION*/
+ translated_n = output_cellhd.north - offsety;
+ translated_w = output_cellhd.west - offsetx;
+ for(i=0;i=0)&&(x=0)&&(ywest, w1->north, &e, &n, param);
+ n += offsety;
+ e += offsetx;
+ w2->north = w2->south = n;
+ w2->west = w2->east = e;
+
+ proj (w1->east, w1->north, &e, &n, param);
+ n += offsety;
+ e += offsetx;
+ if (n > w2->north) w2->north = n;
+ if (n < w2->south) w2->south = n;
+ if (e > w2->east ) w2->east = e;
+ if (e < w2->west ) w2->west = e;
+
+ proj (w1->west, w1->south, &e, &n, param);
+ n += offsety;
+ e += offsetx;
+ if (n > w2->north) w2->north = n;
+ if (n < w2->south) w2->south = n;
+ if (e > w2->east ) w2->east = e;
+ if (e < w2->west ) w2->west = e;
+
+ proj (w1->east, w1->south, &e, &n, param);
+ n += offsety;
+ e += offsetx;
+ if (n > w2->north) w2->north = n;
+ if (n < w2->south) w2->south = n;
+ if (e > w2->east ) w2->east = e;
+ if (e < w2->west ) w2->west = e;
+
+ w2->ns_res = (w2->north - w2->south) / w1->rows;
+ w2->ew_res = (w2->east - w2->west ) / w1->cols;
+ w2->cols=w1->cols;
+ w2->rows=w1->rows;
+}
+
+/*SELECT CURRENT ENV*/
+void select_current_env()
+{
+ if (which_env < 0)
+ {
+ G__create_alt_env();
+ which_env = 0;
+ }
+ if (which_env != 0)
+ {
+ G__switch_env();
+ which_env = 0;
+ }
+}
+
+/*SELECT TARGET ENV*/
+void select_target_env()
+{
+ if (which_env < 0)
+ {
+ G__create_alt_env();
+ which_env = 1;
+ }
+ if (which_env != 1)
+ {
+ G__switch_env();
+ which_env = 1;
+ }
+}
+/*PRINT ENV*/
+void show_env()
+{
+ fprintf (stdout,"env(%d) switch to LOCATION %s, MAPSET %s\n", which_env,
+ G__getenv("LOCATION_NAME")==NULL ? "?" : G__getenv("LOCATION_NAME"),
+ G__getenv("MAPSET")==NULL ? "?" : G__getenv("MAPSET"));
+ sleep(2);
+}
+
+void coords(e,n,x,y,win)
+ double e,n;
+ int *x,*y;
+ struct Cell_head *win;
+{
+ *y=(int)(e - win->west) / win->ew_res;
+ *x=(int)(win->north - n) / win->ns_res;
+}
+
+void points_to_line (double e1, double n1, double e2, double n2, double *t, double *u)
+{
+ double a,b,c;
+ a=(n1 - n2);
+ b= (e2 - e1);
+ c= (n2*e1 - n1*e2);
+ *t= a/c;
+ *u=b/c;
+ /* printf( " \n a %f b %f c %f t %f u %f \n\n",a,b,c,*t,*u); */
+}
Added: trunk/grassaddons/i.homography/matrix.c
===================================================================
--- trunk/grassaddons/i.homography/matrix.c (rev 0)
+++ trunk/grassaddons/i.homography/matrix.c 2007-10-21 08:42:42 UTC (rev 1153)
@@ -0,0 +1,162 @@
+/*
+ The following routines are written and tested by Stefano Merler
+
+ for
+
+ management of matrices and arrays
+
+ Supported function for
+ - product matrix matrix or vector matrix
+ - transpose matrix
+ - conversion of matrix to array
+ - extraction of portion of matrix
+*/
+
+#include
+
+void product_double_matrix_double_matrix(x,y,r,cr,c,out)
+ /*
+ product of matrices x * y,
+ r = rows of x
+ cr= cols of x = rows of y
+ c = cols of y
+ out is the r x c matrix.
+ */
+ double **x, **y, **out;
+ int r,cr,c;
+{
+ int i,j,h;
+
+ for(i=0; i
Author: landa
Date: 2007-10-22 11:12:22 +0200 (Mon, 22 Oct 2007)
New Revision: 1154
Modified:
trunk/grassaddons/gui/display_driver/driver.cpp
trunk/grassaddons/gui/display_driver/driver.h
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/gcmd.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/render.py
Log:
Digitization tool: fix query tool
Mapdisplay: zoom fix (calculate center coordinates)
Modified: trunk/grassaddons/gui/display_driver/driver.cpp
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-22 09:12:22 UTC (rev 1154)
@@ -565,6 +565,20 @@
region.map_width = map_width;
region.map_height = map_height;
+#ifdef DEBUG:
+ std::cerr << "region: n=" << north
+ << "; s=" << south
+ << "; e=" << east
+ << "; w=" << west
+ << "; ns_res=" << ns_res
+ << "; ew_res=" << ew_res
+ << "; center_easting=" << center_easting
+ << "; center_northing=" << center_northing
+ << "; map_width=" << map_width
+ << "; map_height=" << map_height
+ << std::endl;
+#endif
+
// calculate real region
region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res;
@@ -916,13 +930,14 @@
\brief Get PseudoDC vertex id of selected line
\param[in] x,y coordinates of click
+ \param[in] thresh threshold value
\return id of center, left and right vertex
\return 0 no line found
\return -1 on error
*/
-std::vector DisplayDriver::GetSelectedVertex(double x, double y)
+std::vector DisplayDriver::GetSelectedVertex(double x, double y, double thresh)
{
int startId;
int line, type;
@@ -940,8 +955,6 @@
startId = 1;
line = selected[0];
- std::cerr << line << std::endl;
-
type = Vect_read_line (mapInfo, points, cats, line);
// find the closest vertex (x, y)
@@ -960,7 +973,10 @@
}
}
}
-
+
+ if (minDist > thresh)
+ return returnId;
+
// desc = &(ids[line]);
// translate id
Modified: trunk/grassaddons/gui/display_driver/driver.h
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.h 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/display_driver/driver.h 2007-10-22 09:12:22 UTC (rev 1154)
@@ -159,7 +159,7 @@
std::vector GetSelected(bool grassId);
int SetSelected(std::vector id);
- std::vector GetSelectedVertex(double x, double y);
+ std::vector GetSelectedVertex(double x, double y, double thresh);
/* general */
void CloseMap();
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-22 09:12:22 UTC (rev 1154)
@@ -99,9 +99,9 @@
self.settings["categoryMode"] = "Next to use"
# query tool
- self.settings["query"] = "length"
- self.settings["queryLength"] = ("shorter than", 0)
- self.settings["queryDangle"] = (0,)
+ self.settings["query"] = ("length", False) # name, select by box
+ self.settings["queryLength"] = ("shorter than", 0) # gt or lt, threshold
+ self.settings["queryDangle"] = ("shorter than", 0)
else:
self.settings = settings
@@ -382,7 +382,7 @@
# reload map (needed for v.edit)
self.driver.ReloadMap()
-
+
return True
def CopyCats(self, cats, ids):
@@ -749,7 +749,7 @@
x, y = coords
- id = self.__display.GetSelectedVertex(x, y)
+ id = self.__display.GetSelectedVertex(x, y, self.GetThreshold())
Debug.msg(4, "CDisplayDriver.GetSelectedVertex(): id=%s" % \
(",".join(["%d" % v for v in id])))
@@ -1074,6 +1074,13 @@
sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
LocUnits = self.parent.MapWindow.Map.ProjInfo()['units']
+
+ self.queryBox = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Select by box"))
+ self.queryBox.SetValue(settings["query"][1])
+
+ sizer.Add(item=self.queryBox, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
+ sizer.Add((0, 5))
+
#
# length
#
@@ -1103,23 +1110,28 @@
self.queryDangle = wx.RadioButton(parent=panel, id=wx.ID_ANY, label=_("dangle"))
self.queryDangle.Bind(wx.EVT_RADIOBUTTON, self.OnChangeQuery)
sizer.Add(item=self.queryDangle, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
- flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5)
+ flexSizer = wx.FlexGridSizer (cols=4, hgap=5, vgap=5)
flexSizer.AddGrowableCol(0)
- txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select dangles shorter than"))
+ txt = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Select dangles"))
+ self.queryDangleSL = wx.Choice (parent=panel, id=wx.ID_ANY,
+ choices = [_("shorter than"), _("longer than")])
+ self.queryDangleSL.SetStringSelection(settings["queryDangle"][0])
self.queryDangleValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(100, -1),
initial=1,
min=0, max=1e6)
- self.queryDangleValue.SetValue(settings["queryDangle"][0])
+ self.queryDangleValue.SetValue(settings["queryDangle"][1])
units = wx.StaticText(parent=panel, id=wx.ID_ANY, label="%s" % LocUnits)
flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
+ flexSizer.Add(self.queryDangleSL, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
flexSizer.Add(self.queryDangleValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)
flexSizer.Add(units, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
sizer.Add(item=flexSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=1)
- if settings["query"] == "length":
+ if settings["query"][0] == "length":
self.queryLength.SetValue(True)
else:
self.queryDangle.SetValue(True)
+
# enable & disable items
self.OnChangeQuery(None)
@@ -1212,11 +1224,13 @@
# length
self.queryLengthSL.Enable(True)
self.queryLengthValue.Enable(True)
+ self.queryDangleSL.Enable(False)
self.queryDangleValue.Enable(False)
else:
# dangle
self.queryLengthSL.Enable(False)
self.queryLengthValue.Enable(False)
+ self.queryDangleSL.Enable(True)
self.queryDangleValue.Enable(True)
def OnOK(self, event):
@@ -1269,12 +1283,13 @@
# query tool
if self.queryLength.GetValue():
- self.parent.digit.settings["query"] = "length"
+ self.parent.digit.settings["query"] = ("length", self.queryBox.IsChecked())
else:
- self.parent.digit.settings["query"] = "dangle"
+ self.parent.digit.settings["query"] = ("dangle", self.queryBox.IsChecked())
self.parent.digit.settings["queryLength"] = (self.queryLengthSL.GetStringSelection(),
int(self.queryLengthValue.GetValue()))
- self.parent.digit.settings["queryDangle"] = (int(self.queryDangleValue.GetValue()),)
+ self.parent.digit.settings["queryDangle"] = (self.queryDangleSL.GetStringSelection(),
+ int(self.queryDangleValue.GetValue()),)
# update driver settings
self.parent.digit.driver.UpdateSettings()
Modified: trunk/grassaddons/gui/gui_modules/gcmd.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-10-22 09:12:22 UTC (rev 1154)
@@ -228,7 +228,7 @@
line = stream.readline()
if not line:
break
- line = line.replace('\n', '')
+ line = line.replace('\n', '').strip()
lineList.append(line)
return lineList
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-22 09:12:22 UTC (rev 1154)
@@ -218,9 +218,10 @@
self.pdcVector = None
# pseudoDC for temporal objects (select box, measurement tool, etc.)
self.pdcTmp = wx.PseudoDC()
+ self.redrawAll = True # redraw all pdc layers, Tmp layer is redrawn always (speed issue)
# will store an off screen empty bitmap for saving to file
- self._Buffer = ''
+ self._buffer = ''
self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x:None)
@@ -376,7 +377,7 @@
Draw PseudoDC to buffered paint DC
"""
- dc = wx.BufferedPaintDC(self, self._Buffer)
+ dc = wx.BufferedPaintDC(self, self._buffer)
# we need to clear the dc BEFORE calling PrepareDC
bg = wx.Brush(self.GetBackgroundColour())
@@ -390,16 +391,35 @@
# and update region
rgn = self.GetUpdateRegion().GetBox()
dc.SetClippingRect(rgn)
- # draw to the dc using the calculated clipping rect
- self.pdc.DrawToDCClipped(dc, rgn)
- # draw vector map layer
- if self.pdcVector:
- self.pdcVector.DrawToDCClipped(dc, rgn)
+ if self.redrawAll: # redraw pdc and pdcVector
+ # draw to the dc using the calculated clipping rect
+ self.pdc.DrawToDCClipped(dc, rgn)
+ # draw vector map layer
+ if self.pdcVector:
+ self.pdcVector.DrawToDCClipped(dc, rgn)
+
+ self._bufferLast = None
+ else: # do not redraw pdc and pdcVector
+ if self._bufferLast is None:
+ # draw to the dc
+ self.pdc.DrawToDC(dc)
+
+ if self.pdcVector:
+ self.pdcVector.DrawToDC(dc)
+
+ # store buffered image
+ # self._bufferLast = wx.BitmapFromImage(self._buffer.ConvertToImage())
+ self._bufferLast = dc.GetAsBitmap((0, 0, self.Map.width, self.Map.height))
+
+ pdcLast = wx.PseudoDC()
+ pdcLast.DrawBitmap(bmp=self._bufferLast, x=0, y=0)
+ pdcLast.DrawToDC(dc)
+
# draw temporal object on the foreground
self.pdcTmp.DrawToDCClipped(dc, rgn)
-
+
def OnSize(self, event):
"""
Scale map image so that it is
@@ -414,7 +434,7 @@
# Make new off screen bitmap: this bitmap will always have the
# current drawing in it, so it can be used to save the image to
# a file, or whatever.
- self._Buffer = wx.EmptyBitmap(self.Map.width, self.Map.height)
+ self._buffer = wx.EmptyBitmap(self.Map.width, self.Map.height)
# get the image to be rendered
self.img = self.GetImage()
@@ -446,11 +466,11 @@
This draws the psuedo DC to a buffer that
can be saved to a file.
"""
- dc = wx.BufferedPaintDC(self, self._Buffer)
+ dc = wx.BufferedPaintDC(self, self._buffer)
self.pdc.DrawToDC(dc)
if self.pdcVector:
self.pdcVector.DrawToDC(dc)
- self._Buffer.SaveFile(FileName, FileType)
+ self._buffer.SaveFile(FileName, FileType)
def GetOverlay(self):
"""
@@ -612,8 +632,8 @@
# drag not only background image
# FIXME: when mapdisplay window is hiden by other window,
- # self._Buffer contains grey holes
- self.dragimg = wx.DragImage(self._Buffer)
+ # self._buffer contains grey holes
+ self.dragimg = wx.DragImage(self._buffer)
self.dragimg.BeginDrag((0, 0), self)
self.dragimg.GetImageRect(moveto)
self.dragimg.Move(moveto)
@@ -649,13 +669,14 @@
def MouseDraw(self, pdc=None):
"""
- Mouse zoom rectangles and lines
+ Mouse rectangles and lines
"""
if not pdc:
return
Debug.msg (5, "BufferedWindow.MouseDraw(): use=%s, box=%s" % \
(self.mouse['use'], self.mouse['box']))
+
if self.mouse['box'] == "box":
boxid = wx.ID_NEW
mousecoords = [self.mouse['begin'][0], self.mouse['begin'][1], \
@@ -814,7 +835,9 @@
self.ClearLines(pdc=self.pdcTmp)
else:
self.mouse['begin'] = self.mouse['end']
-
+ elif self.mouse['use'] == 'zoom':
+ print "#", self.mouse['begin']
+ self.redrawAll = False
elif self.mouse["use"] == "pointer" and self.parent.digittoolbar:
# digitization
digitToolbar = self.parent.digittoolbar
@@ -998,6 +1021,9 @@
self.mouse['end'] = event.GetPositionTuple()[:]
if self.mouse['use'] in ["zoom", "pan"]:
+ if self.mouse['use'] == 'zoom':
+ print "#", self.mouse['end']
+ self.redrawAll = True
# set region in zoom or pan
self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype)
@@ -1079,12 +1105,9 @@
if nselected > 0:
# highlight selected features
- self.UpdateMap(render=False)
+ # self.UpdateMap(render=False)
if digitToolbar.action in ["moveLine", "moveVertex",
"copyCats", "editLine"]:
- # -> move line || move vertex
- self.UpdateMap(render=False)
-
# get pseudoDC id of objects which should be redrawn
if digitToolbar.action == "moveLine":
# -> move line
@@ -1093,6 +1116,8 @@
elif digitToolbar.action == "moveVertex":
# -> move vertex
self.moveIds = digitClass.driver.GetSelectedVertex(pos1)
+ if len(self.moveIds) == 0: # no vertex found
+ digitClass.driver.SetSelected([])
elif digitToolbar.action == "editLine":
# -> edit line
@@ -1106,8 +1131,11 @@
# choose first or last node of line
self.moveIds.reverse()
- else:
+ # -> move line || move vertex
+ self.UpdateMap(render=False)
+ else: # no vector object found
self.UpdateMap(render=False, renderVector=False)
+
elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]:
pointOnLine = digitClass.driver.SelectLineByPoint(pos1,
type="line")
@@ -1330,7 +1358,7 @@
elif digitToolbar.action == "moveVertex":
# move vertex
digitClass.MoveSelectedVertex(pFrom,
- move)
+ move)
else: # edit line
pass
@@ -1503,7 +1531,7 @@
x, y = self.pdcVector.GetIdBounds(self.moveIds[1])[0:2]
self.pdcVector.RemoveId(self.moveIds[1]+1)
self.polycoords.append((x, y))
- self.polycoords.append(self.mouse['end'])
+ self.polycoords.append(self.pdcVector.GetIdBounds(self.moveIds[0])[0:2])
if self.moveIds[2] > 0: # next vertex
x, y = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2]
self.pdcVector.RemoveId(self.moveIds[2]-1)
@@ -1630,6 +1658,8 @@
x2, y2 = end
newreg = {}
+ print "#", begin, end, self.Pixel2Cell(begin), self.Pixel2Cell(end)
+
# threshold - too small squares do not make sense
# can only zoom to windows of > 10x10 screen pixels
if x2 > 10 and y2 > 10 and zoomtype != 0:
@@ -1663,8 +1693,10 @@
self.Map.region['s'] = newreg['s']
self.Map.region['e'] = newreg['e']
self.Map.region['w'] = newreg['w']
- self.Map.region['center_easting'] = newreg['w'] + (newreg['e'] - newreg['w']) / 2
- self.Map.region['center_northing'] = newreg['s'] + (newreg['n'] - newreg['s']) / 2
+ self.Map.region['center_easting'] = self.Map.region['w'] + \
+ (self.Map.region['e'] - self.Map.region['w']) / 2
+ self.Map.region['center_northing'] = self.Map.region['s'] + \
+ (self.Map.region['n'] - self.Map.region['s']) / 2
self.ZoomHistory(newreg['n'], newreg['s'], newreg['e'], newreg['w'])
@@ -1683,8 +1715,15 @@
self.Map.region['s'] = zoom[1]
self.Map.region['e'] = zoom[2]
self.Map.region['w'] = zoom[3]
+ self.Map.region['center_easting'] = self.Map.region['w'] + \
+ (self.Map.region['e'] - self.Map.region['w']) / 2
+ self.Map.region['center_northing'] = self.Map.region['s'] + \
+ (self.Map.region['n'] - self.Map.region['s']) / 2
+
self.UpdateMap()
+ self.parent.StatusbarUpdate()
+
def ZoomHistory(self, n, s, e, w):
"""
Manages a list of last 10 zoom extents
@@ -1719,37 +1758,33 @@
item = self.tree.GetSelection()
try:
- layer = self.tree.layers[item].maplayer
+ layer = self.tree.GetPyData(item)[0]['maplayer']
except:
+ layer = None
+
+ if layer is None:
return
-
+
Debug.msg (3, "BufferedWindow.ZoomToMap(): layer=%s, type=%s" % \
(layer.name, layer.type))
# selected layer must be a valid map
if layer.type in ('raster', 'rgb', 'his', 'shaded', 'arrow'):
- cmdlist = ["g.region", "-ugp", "rast=%s" % layer.name]
+ self.Map.region = self.Map.GetRegion(rast="%s" % layer.name)
elif layer.type in ('vector', 'thememap', 'themechart'):
- cmdlist = ["g.region", "-ugp", "vect=%s" % layer.name]
+ self.Map.region = self.Map.GetRegion(vect="%s" % layer.name)
else:
return
- # get map extents using g.region and update display
- p = gcmd.Command(cmdlist)
+ self.Map.SetRegion()
- if p.returncode == 0:
- output = p.module_stdout.read().split('\n')
- for line in output:
- line = line.strip()
- if '=' in line: key,val = line.split('=')
- zoomreg[key] = float(val)
- self.Map.region['n'] = zoomreg['n']
- self.Map.region['s'] = zoomreg['s']
- self.Map.region['e'] = zoomreg['e']
- self.Map.region['w'] = zoomreg['w']
- self.ZoomHistory(self.Map.region['n'],self.Map.region['s'],self.Map.region['e'],self.Map.region['w'])
- self.UpdateMap()
+ self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
+ self.Map.region['e'], self.Map.region['w'])
+ self.UpdateMap()
+
+ self.parent.StatusbarUpdate()
+
def ZoomToWind(self, event):
"""
Set display geometry to match computational
@@ -1758,9 +1793,14 @@
self.Map.region = self.Map.GetRegion()
self.Map.SetRegion()
- self.ZoomHistory(self.Map.region['n'],self.Map.region['s'],self.Map.region['e'],self.Map.region['w'])
+
+ self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
+ self.Map.region['e'], self.Map.region['w'])
+
self.UpdateMap()
+ self.parent.StatusbarUpdate()
+
def DisplayToWind(self, event):
"""
Set computational region (WIND file) to
@@ -2294,9 +2334,13 @@
def OnToggleStatus(self, event):
"""Toggle status text"""
self.statusText = event.GetString()
+ self.StatusbarUpdate()
+ def StatusbarUpdate(self):
+ """Update statusbar content"""
+
if self.statusText == "Coordinates":
- self.statusbar.SetStatusText("None,None", 0)
+ self.statusbar.SetStatusText("", 0)
self.showRegion.Hide()
elif self.statusText == "Extent":
self.statusbar.SetStatusText("%.2f-%.2f,%.2f-%.2f" %
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-21 08:42:42 UTC (rev 1153)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-22 09:12:22 UTC (rev 1154)
@@ -381,11 +381,13 @@
except:
return False
- def GetRegion(self):
+ def GetRegion(self, rast=None, vect=None):
"""
- Returns dictionary with output from g.region -gp
+ Returns dictionary with output from g.region -ugpc
- Example:
+ Optionaly raster or vector map layer can be given.
+
+ Return e.g.:
{"n":"4928010", "s":"4913700", "w":"589980",...}
"""
@@ -395,10 +397,16 @@
os.unsetenv("GRASS_REGION")
# do not update & shell style output
- cmdRegion = gcmd.Command(["g.region", "-u", "-g", "-p", "-c"])
+ cmdList = ["g.region", "-u", "-g", "-p", "-c"]
+ if rast:
+ cmdList.append('rast=%s' % rast)
+ elif vect:
+ cmdList.append('vect=%s' % vect)
+
+ cmdRegion = gcmd.Command(cmdList)
+
for reg in cmdRegion.ReadStdOutput():
- reg = reg.strip()
key, val = reg.split("=", 1)
try:
region[key] = float(val)
From landa at grass.itc.it Mon Oct 22 13:06:13 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:48 2007
Subject: [grass-addons] r1155 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710221106.l9MB6D6v021049@grass.itc.it>
Author: landa
Date: 2007-10-22 13:06:08 +0200 (Mon, 22 Oct 2007)
New Revision: 1155
Modified:
trunk/grassaddons/gui/gui_modules/mapdisp.py
Log:
Zooming based on center point of display window.
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-22 09:12:22 UTC (rev 1154)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-22 11:06:08 UTC (rev 1155)
@@ -450,6 +450,9 @@
# reposition checkbox in statusbar
self.parent.StatusbarReposition()
+ # update statusbar
+ self.parent.StatusbarUpdate()
+
def OnIdle(self, event):
"""
Only re-render a compsite map image from GRASS during
@@ -763,6 +766,8 @@
self.Zoom(begin, end, zoomtype)
# redraw map
self.UpdateMap()
+ # update statusbar
+ self.parent.StatusbarUpdate()
return
# left mouse button pressed
@@ -836,7 +841,6 @@
else:
self.mouse['begin'] = self.mouse['end']
elif self.mouse['use'] == 'zoom':
- print "#", self.mouse['begin']
self.redrawAll = False
elif self.mouse["use"] == "pointer" and self.parent.digittoolbar:
# digitization
@@ -1022,7 +1026,6 @@
if self.mouse['use'] in ["zoom", "pan"]:
if self.mouse['use'] == 'zoom':
- print "#", self.mouse['end']
self.redrawAll = True
# set region in zoom or pan
self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype)
@@ -1030,6 +1033,9 @@
# redraw map
self.UpdateMap(render=True)
+ # update statusbar
+ self.parent.StatusbarUpdate()
+
elif self.mouse["use"] == "query":
# querying
self.parent.QueryMap(self.mouse['begin'][0],self.mouse['begin'][1])
@@ -1658,8 +1664,6 @@
x2, y2 = end
newreg = {}
- print "#", begin, end, self.Pixel2Cell(begin), self.Pixel2Cell(end)
-
# threshold - too small squares do not make sense
# can only zoom to windows of > 10x10 screen pixels
if x2 > 10 and y2 > 10 and zoomtype != 0:
@@ -1689,17 +1693,30 @@
# if new region has been calculated, set the values
if newreg :
- self.Map.region['n'] = newreg['n']
- self.Map.region['s'] = newreg['s']
- self.Map.region['e'] = newreg['e']
- self.Map.region['w'] = newreg['w']
- self.Map.region['center_easting'] = self.Map.region['w'] + \
- (self.Map.region['e'] - self.Map.region['w']) / 2
- self.Map.region['center_northing'] = self.Map.region['s'] + \
- (self.Map.region['n'] - self.Map.region['s']) / 2
+ self.Map.region['center_easting'] = newreg['w'] + \
+ (newreg['e'] - newreg['w']) / 2
+ self.Map.region['center_northing'] = newreg['s'] + \
+ (newreg['n'] - newreg['s']) / 2
+ self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
+ self.Map.region["nsres"] = (newreg['n'] - newreg['s']) / self.Map.height
+
+ # calculete bounding box from center coordinates
+ if self.Map.region["ewres"] > self.Map.region["nsres"]:
+ res = self.Map.region["ewres"]
+ else:
+ res = self.Map.region["nsres"]
- self.ZoomHistory(newreg['n'], newreg['s'], newreg['e'], newreg['w'])
+ ew = (self.Map.width / 2) * res
+ ns = (self.Map.height / 2) * res
+ self.Map.region['n'] = self.Map.region['center_northing'] + ns
+ self.Map.region['s'] = self.Map.region['center_northing'] - ns
+ self.Map.region['e'] = self.Map.region['center_easting'] + ew
+ self.Map.region['w'] = self.Map.region['center_easting'] - ew
+
+ self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
+ self.Map.region['e'], self.Map.region['w'])
+
def ZoomBack(self):
"""
Zoom to previous extents in zoomhistory list
@@ -1709,19 +1726,34 @@
if len(self.zoomhistory) > 1:
self.zoomhistory.pop()
zoom = self.zoomhistory[len(self.zoomhistory)-1]
-
+ # (n, s, e, w)
if zoom:
- self.Map.region['n'] = zoom[0]
- self.Map.region['s'] = zoom[1]
- self.Map.region['e'] = zoom[2]
- self.Map.region['w'] = zoom[3]
- self.Map.region['center_easting'] = self.Map.region['w'] + \
- (self.Map.region['e'] - self.Map.region['w']) / 2
- self.Map.region['center_northing'] = self.Map.region['s'] + \
- (self.Map.region['n'] - self.Map.region['s']) / 2
+ # zoom to selected region
+ self.Map.region['center_easting'] = zoom[3] + \
+ (zoom[2] - zoom[3]) / 2
+ self.Map.region['center_northing'] = zoom[1] + \
+ (zoom[0] - zoom[1]) / 2
+ self.Map.region["ewres"] = (zoom[2] - zoom[3]) / self.Map.width
+ self.Map.region["nsres"] = (zoom[0] - zoom[1]) / self.Map.height
+
+ # calculete bounding box from center coordinates
+ if self.Map.region["ewres"] > self.Map.region["nsres"]:
+ res = self.Map.region["ewres"]
+ else:
+ res = self.Map.region["nsres"]
+ ew = (self.Map.width / 2) * res
+ ns = (self.Map.height / 2) * res
+
+ self.Map.region['n'] = self.Map.region['center_northing'] + ns
+ self.Map.region['s'] = self.Map.region['center_northing'] - ns
+ self.Map.region['e'] = self.Map.region['center_easting'] + ew
+ self.Map.region['w'] = self.Map.region['center_easting'] - ew
+
+ # update map
self.UpdateMap()
+ # update statusbar
self.parent.StatusbarUpdate()
def ZoomHistory(self, n, s, e, w):
From landa at grass.itc.it Tue Oct 23 10:03:56 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:48 2007
Subject: [grass-addons] r1156 - trunk/grassaddons/gui
Message-ID: <200710230803.l9N83uC1000905@grass.itc.it>
Author: landa
Date: 2007-10-23 10:03:54 +0200 (Tue, 23 Oct 2007)
New Revision: 1156
Modified:
trunk/grassaddons/gui/wxgui.py
Log:
Disable xmlproc (not available on Mac OS)
Modified: trunk/grassaddons/gui/wxgui.py
===================================================================
--- trunk/grassaddons/gui/wxgui.py 2007-10-22 11:06:08 UTC (rev 1155)
+++ trunk/grassaddons/gui/wxgui.py 2007-10-23 08:03:54 UTC (rev 1156)
@@ -30,9 +30,10 @@
import types
import re
# for GRC (workspace file) parsering
-from xml.parsers.xmlproc import xmlproc
-from xml.parsers.xmlproc import xmlval
-from xml.parsers.xmlproc import xmldtd
+# xmlproc not available on Mac OS
+# from xml.parsers.xmlproc import xmlproc
+# from xml.parsers.xmlproc import xmlval
+# from xml.parsers.xmlproc import xmldtd
import xml.sax
import xml.sax.handler
HandlerBase=xml.sax.handler.ContentHandler
@@ -471,22 +472,22 @@
gisbase = os.getenv("GISBASE")
dtdFilename = os.path.join(gisbase, "etc", "wx", "gui_modules", "grass-grc.dtd")
- # parse xml agains dtd
- dtd = xmldtd.load_dtd(dtdFilename)
- parser = xmlproc.XMLProcessor()
- parser.set_application(xmlval.ValidatingApp(dtd, parser))
- parser.dtd = dtd
- parser.ent = dtd
- try:
- # TODO: set_error_handler(self,err)
- parser.parse_resource(filename)
- except:
- dlg = wx.MessageDialog(self, _("Unable to open workspace file <%s>. "
- "It is not valid GRC XML file.") % filename,
- _("Error"), wx.OK | wx.ICON_ERROR)
- dlg.ShowModal()
- dlg.Destroy()
- return False
+ # validate xml agains dtd
+ # dtd = xmldtd.load_dtd(dtdFilename)
+ # parser = xmlproc.XMLProcessor()
+ # parser.set_application(xmlval.ValidatingApp(dtd, parser))
+ # parser.dtd = dtd
+ # parser.ent = dtd
+ # try:
+ # # TODO: set_error_handler(self,err)
+ # parser.parse_resource(filename)
+ # except:
+ # dlg = wx.MessageDialog(self, _("Unable to open workspace file <%s>. "
+ # "It is not valid GRC XML file.") % filename,
+ # _("Error"), wx.OK | wx.ICON_ERROR)
+ # dlg.ShowModal()
+ # dlg.Destroy()
+ # return False
# delete current layer tree content
self.OnWorkspaceNew()
From landa at grass.itc.it Tue Oct 23 12:25:51 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:48 2007
Subject: [grass-addons] r1157 - trunk/grassaddons/gui/gui_modules
Message-ID: <200710231025.l9NAPpu3002528@grass.itc.it>
Author: landa
Date: 2007-10-23 12:25:45 +0200 (Tue, 23 Oct 2007)
New Revision: 1157
Modified:
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/render.py
trunk/grassaddons/gui/gui_modules/toolbars.py
Log:
Basic map scale implemented (TODO: screen resolution must be given by user).
Minor bugfixes in digit tool.
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-23 08:03:54 UTC (rev 1156)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-23 10:25:45 UTC (rev 1157)
@@ -99,7 +99,7 @@
self.settings["categoryMode"] = "Next to use"
# query tool
- self.settings["query"] = ("length", False) # name, select by box
+ self.settings["query"] = ("length", True) # name, select by box
self.settings["queryLength"] = ("shorter than", 0) # gt or lt, threshold
self.settings["queryDangle"] = ("shorter than", 0)
else:
@@ -520,14 +520,38 @@
def SelectLinesByQuery(self, pos1, pos2):
"""Select features by query"""
+ thresh = self.settings['queryLength'][1]
+ if self.settings['query'][0] == "length":
+ if self.settings["queryLength"][0] == "shorter than":
+ thresh = -1 * thresh
+ else:
+ if self.settings["queryDangle"][0] == "shorter than":
+ thresh = -1 * thresh
+ w, n = pos1
+ e, s = pos2
+
+ if self.settings['query'][1] == False: # select globaly
+ vInfo = gcmd.Command(['v.info',
+ 'map=%s' % self.map,
+ '-g'])
+ for item in vInfo.ReadStdOutput():
+ if 'north' in item:
+ n = float(item.split('=')[1])
+ elif 'south' in item:
+ s = float(item.split('=')[1])
+ elif 'east' in item:
+ e = float(item.split('=')[1])
+ elif 'west' in item:
+ w = float(item.split('=')[1])
+
vEdit = (['v.edit',
'--q',
'map=%s' % self.map,
'tool=select',
- 'bbox=%f,%f,%f,%f' % (pos1[0], pos1[1], pos2[0], pos2[1]),
- 'query=%s' % self.settings['query'],
- 'thresh=%f' % self.settings['queryLength'][1]])
+ 'bbox=%f,%f,%f,%f' % (w, n, e, s),
+ 'query=%s' % self.settings['query'][0],
+ 'thresh=%f' % thresh])
if self.settings['query'] == "length" and \
self.settings['queryLength'][0] == "longer than":
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-23 08:03:54 UTC (rev 1156)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-23 10:25:45 UTC (rev 1157)
@@ -430,6 +430,7 @@
# set size of the input image
self.Map.ChangeMapSize(self.GetClientSize())
+ self.Map.AlignExtentFromDisplay() # align extent based on center point and display resolution
# Make new off screen bitmap: this bitmap will always have the
# current drawing in it, so it can be used to save the image to
@@ -602,14 +603,7 @@
# update statusbar
#
self.Map.SetRegion()
- if self.parent.statusText == "Extent":
- self.parent.statusbar.SetStatusText("%.2f-%.2f,%.2f-%.2f" %
- (self.Map.region["w"], self.Map.region["e"],
- self.Map.region["s"], self.Map.region["n"]), 1)
- elif self.parent.statusText == "Geometry":
- self.parent.statusbar.SetStatusText("rows=%d;cols=%d;nsres=%.2f;ewres=%.2f" %
- (self.Map.region["rows"], self.Map.region["cols"],
- self.Map.region["nsres"], self.Map.region["ewres"]), 1)
+ self.parent.StatusbarUpdate()
return True
@@ -1137,8 +1131,8 @@
# choose first or last node of line
self.moveIds.reverse()
- # -> move line || move vertex
- self.UpdateMap(render=False)
+ # -> move line || move vertex
+ self.UpdateMap(render=False)
else: # no vector object found
self.UpdateMap(render=False, renderVector=False)
@@ -1693,27 +1687,15 @@
# if new region has been calculated, set the values
if newreg :
+ # calculate new center point and display resolution
self.Map.region['center_easting'] = newreg['w'] + \
(newreg['e'] - newreg['w']) / 2
self.Map.region['center_northing'] = newreg['s'] + \
(newreg['n'] - newreg['s']) / 2
self.Map.region["ewres"] = (newreg['e'] - newreg['w']) / self.Map.width
self.Map.region["nsres"] = (newreg['n'] - newreg['s']) / self.Map.height
-
- # calculete bounding box from center coordinates
- if self.Map.region["ewres"] > self.Map.region["nsres"]:
- res = self.Map.region["ewres"]
- else:
- res = self.Map.region["nsres"]
+ self.Map.AlignExtentFromDisplay()
- ew = (self.Map.width / 2) * res
- ns = (self.Map.height / 2) * res
-
- self.Map.region['n'] = self.Map.region['center_northing'] + ns
- self.Map.region['s'] = self.Map.region['center_northing'] - ns
- self.Map.region['e'] = self.Map.region['center_easting'] + ew
- self.Map.region['w'] = self.Map.region['center_easting'] - ew
-
self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
self.Map.region['e'], self.Map.region['w'])
@@ -1735,21 +1717,8 @@
(zoom[0] - zoom[1]) / 2
self.Map.region["ewres"] = (zoom[2] - zoom[3]) / self.Map.width
self.Map.region["nsres"] = (zoom[0] - zoom[1]) / self.Map.height
-
- # calculete bounding box from center coordinates
- if self.Map.region["ewres"] > self.Map.region["nsres"]:
- res = self.Map.region["ewres"]
- else:
- res = self.Map.region["nsres"]
+ self.Map.AlignExtentFromDisplay()
- ew = (self.Map.width / 2) * res
- ns = (self.Map.height / 2) * res
-
- self.Map.region['n'] = self.Map.region['center_northing'] + ns
- self.Map.region['s'] = self.Map.region['center_northing'] - ns
- self.Map.region['e'] = self.Map.region['center_easting'] + ew
- self.Map.region['w'] = self.Map.region['center_easting'] - ew
-
# update map
self.UpdateMap()
@@ -1809,6 +1778,7 @@
return
self.Map.SetRegion()
+ self.Map.AlignExtentFromDisplay()
self.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
self.Map.region['e'], self.Map.region['w'])
@@ -1843,7 +1813,7 @@
# We ONLY want to set extents here. Don't mess with resolution. Leave that
# for user to set explicitly with g.region
- new = self.Map.alignResolution()
+ new = self.Map.AlignResolution()
cmdRegion = ["g.region", "--o",
"n=%f" % new['n'],
@@ -1927,7 +1897,7 @@
def SaveRegion(self, wind):
"""Save region settings"""
- new = self.Map.alignResolution()
+ new = self.Map.AlignResolution()
cmdRegion = ["g.region",
"-u",
@@ -2041,36 +2011,35 @@
self.toggleStatus = wx.Choice(self.statusbar, wx.ID_ANY,
choices = ["Coordinates",
"Extent",
- "Geometry"])
+ "Geometry",
+ "Map scale"])
self.statusText = "Coordinates"
self.statusbar.Bind(wx.EVT_CHOICE, self.OnToggleStatus, self.toggleStatus)
# auto-rendering checkbox
- self.autoRender = wx.CheckBox(self.statusbar, wx.ID_ANY, _("Render"))
+ self.autoRender = wx.CheckBox(parent=self.statusbar, id=wx.ID_ANY,
+ label=_("Render"))
self.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleRender, self.autoRender)
self.autoRender.SetValue(False)
self.autoRender.SetToolTip(wx.ToolTip (_("Enable/disable auto-rendering")))
# show region
- self.showRegion = wx.CheckBox(self.statusbar, wx.ID_ANY, _("Show"))
+ self.showRegion = wx.CheckBox(parent=self.statusbar, id=wx.ID_ANY,
+ label=_("Show"))
self.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleShowRegion, self.showRegion)
self.showRegion.SetValue(False)
self.showRegion.Hide()
self.showRegion.SetToolTip(wx.ToolTip (_("Show/hide computational "
"region extent (set with g.region)")))
+ # map scale
+ self.mapScale = wx.TextCtrl(parent=self.statusbar, id=wx.ID_ANY,
+ value="", style=wx.TE_PROCESS_ENTER,
+ size=(150, -1))
+ self.mapScale.Hide()
+ self.statusbar.Bind(wx.EVT_TEXT_ENTER, self.OnChangeMapScale, self.mapScale)
+
self.Map.SetRegion() # set region
- # map_frame_statusbar_fields = [
- # # field 0 -> region
- # "Ext:%.2f(W)-%.2f(E),%.2f(N)-%.2f(S); "
- # "Res:%.2f(NS),%.2f(EW)" %
- # (self.Map.region["w"], self.Map.region["e"],
- # self.Map.region["n"], self.Map.region["s"],
- # self.Map.region["nsres"], self.Map.region["ewres"]),
- # # field 1 -> coordinates
- # "%s,%s" % (None, None)]
- # for i in range(len(map_frame_statusbar_fields)):
- # self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i)
- self.statusbar.SetStatusText("None,None", 0)
- self.StatusbarReposition() # reposition checkbox
+ self.StatusbarReposition() # reposition statusbar
+
#
# Init map display
#
@@ -2082,14 +2051,6 @@
self.MapWindow.SetCursor(self.cursors["default"])
#
- # Init zoom history
- #
- self.MapWindow.ZoomHistory(self.Map.region['n'],
- self.Map.region['s'],
- self.Map.region['e'],
- self.Map.region['w'])
-
- #
# Decoration overlays
#
self.ovlchk = self.MapWindow.ovlchk
@@ -2129,6 +2090,14 @@
#
self.digit = Digit(mapwindow=self.MapWindow)
+ #
+ # Init zoom history
+ #
+ self.MapWindow.ZoomHistory(self.Map.region['n'],
+ self.Map.region['s'],
+ self.Map.region['e'],
+ self.Map.region['w'])
+
def AddToolbar(self, name):
"""
Add defined toolbar to the window
@@ -2368,36 +2337,112 @@
self.statusText = event.GetString()
self.StatusbarUpdate()
+ def OnChangeMapScale(self, event):
+ """Map scale changed by user"""
+ scale = event.GetString()
+
+ try:
+ if scale[:2] != '1:':
+ raise ValueError
+ value = int(scale[2:])
+ except ValueError:
+ self.mapScale.SetValue('1:' + str(int(self.mapScaleValue)))
+ return
+
+ dEW = value * (self.Map.region['cols'] / self.ppm[0])
+ dNS = value * (self.Map.region['rows'] / self.ppm[1])
+ self.Map.region['n'] = self.Map.region['center_northing'] + dNS / 2
+ self.Map.region['s'] = self.Map.region['center_northing'] - dNS / 2
+ self.Map.region['w'] = self.Map.region['center_easting'] - dEW / 2
+ self.Map.region['e'] = self.Map.region['center_easting'] + dEW / 2
+
+ # add to zoom history
+ self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'],
+ self.Map.region['e'], self.Map.region['w'])
+
+ # redraw a map
+ self.MapWindow.UpdateMap()
+
def StatusbarUpdate(self):
"""Update statusbar content"""
+ self.showRegion.Hide()
+ self.mapScale.Hide()
+ self.mapScaleValue = self.ppm = None
+
if self.statusText == "Coordinates":
self.statusbar.SetStatusText("", 0)
- self.showRegion.Hide()
+
elif self.statusText == "Extent":
self.statusbar.SetStatusText("%.2f-%.2f,%.2f-%.2f" %
(self.Map.region["w"], self.Map.region["e"],
- self.Map.region["n"], self.Map.region["s"]), 0)
+ self.Map.region["s"], self.Map.region["n"]), 0)
self.showRegion.Show()
+
elif self.statusText == "Geometry":
self.statusbar.SetStatusText("rows=%d;cols=%d;nsres=%.2f;ewres=%.2f" %
(self.Map.region["rows"], self.Map.region["cols"],
self.Map.region["nsres"], self.Map.region["ewres"]), 0)
- self.showRegion.Hide()
+ elif self.statusText == "Map scale":
+ # TODO: need to be fixed...
+ ### screen X region problem
+ ### user should specify ppm
+ dc = wx.ScreenDC()
+ dpSizePx = wx.DisplaySize() # display size in pixels
+ dpSizeMM = wx.DisplaySizeMM() # display size in mm (system)
+ dpSizeIn = (dpSizeMM[0] / 25.4, dpSizeMM[1] / 25.4) # inches
+ sysPpi = dc.GetPPI()
+ comPpi = (dpSizePx[0] / dpSizeIn[0],
+ dpSizePx[1] / dpSizeIn[1])
+
+ ppi = comPpi # pixel per inch
+ self.ppm = ((ppi[0] / 2.54) * 100, # pixel per meter
+ (ppi[1] / 2.54) * 100)
+
+ Debug.msg(4, "MapFrame.StatusbarUpdate(mapscale): size: px=%d,%d mm=%f,%f "
+ "in=%f,%f ppi: sys=%d,%d com=%d,%d; ppm=%f,%f" % \
+ (dpSizePx[0], dpSizePx[1], dpSizeMM[0], dpSizeMM[1],
+ dpSizeIn[0], dpSizeIn[1],
+ sysPpi[0], sysPpi[1], comPpi[0], comPpi[1],
+ self.ppm[0], self.ppm[1]))
+
+ region = self.Map.region
+
+ heightCm = region['rows'] / self.ppm[1] * 100
+ widthCm = region['cols'] / self.ppm[0] * 100
+
+ Debug.msg(4, "MapFrame.StatusbarUpdate(mapscale): width_cm=%f, height_cm=%f" %
+ (widthCm, heightCm))
+
+ xscale = (region['e'] - region['w']) / (region['cols'] / self.ppm[0])
+ yscale = (region['n'] - region['s']) / (region['rows'] / self.ppm[1])
+ scale = (xscale + yscale) / 2
+ Debug.msg(3, "MapFrame.StatusbarUpdate(mapscale): xscale=%f, yscale=%f -> scale=%f" % \
+ (xscale, yscale, scale))
+
+ self.statusbar.SetStatusText("")
+ self.mapScale.SetValue("1:%ld" % scale)
+ self.mapScaleValue = scale
+ self.mapScale.Show()
+
else:
self.statusbar.SetStatusText("", 1)
def StatusbarReposition(self):
"""Reposition checkbox in statusbar"""
# reposition checkbox
- widgets = {0: self.showRegion,
- 1: self.toggleStatus,
- 2: self.autoRender}
- for idx, win in widgets.iteritems():
+ widgets = [(0, self.showRegion),
+ (0, self.mapScale),
+ (1, self.toggleStatus),
+ (2, self.autoRender)]
+ for idx, win in widgets:
rect = self.statusbar.GetFieldRect(idx)
- if idx == 0: # show region
+ if idx == 0: # show region / mapscale
wWin, hWin = win.GetBestSize()
- x, y = rect.x + rect.width - wWin, rect.y-1
+ if win == self.showRegion:
+ x, y = rect.x + rect.width - wWin, rect.y-1
+ else:
+ x, y = rect.x + 3, rect.y-1
w, h = wWin, rect.height+2
else: # choice || auto-rendering
x, y = rect.x, rect.y-1
Modified: trunk/grassaddons/gui/gui_modules/render.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/render.py 2007-10-23 08:03:54 UTC (rev 1156)
+++ trunk/grassaddons/gui/gui_modules/render.py 2007-10-23 10:25:45 UTC (rev 1157)
@@ -328,24 +328,20 @@
return self.region
- def alignResolution(self):
+ def AlignResolution(self):
"""
Sets display extents to even multiple of
- current resolution in WIND file from SW corner.
+ current resolution defined in WIND file from SW corner.
This must be done manually as using the -a flag
can produce incorrect extents.
-
- Used for saving current display settings to WIND file
"""
# new values to use for saving to region file
new = {}
-# windreg = {}
n = s = e = w = 0.0
nwres = ewres = 0.0
# Get current values for region and display
-# windreg = self.GetRegion()
nsres = self.GetRegion()['nsres']
ewres = self.GetRegion()['ewres']
@@ -363,8 +359,31 @@
new['w'] = ewres * round(w/ewres)
new['n'] = new['s'] + (new['rows'] * nsres)
new['e'] = new['w'] + (new['cols'] * ewres)
+
return new
+ def AlignExtentFromDisplay(self):
+ """Sets display extents (n,s,e,w) to even multiple of
+ current display resolution from center point"""
+
+ # calculate new bounding box based on center of display
+ if self.region["ewres"] > self.region["nsres"]:
+ res = self.region["ewres"]
+ else:
+ res = self.region["nsres"]
+
+ Debug.msg(3, "Map.AlignExtentFromDisplay(): width=%d, height=%d, res=%f, center=%f,%f" % \
+ (self.width, self.height, res, self.region['center_easting'],
+ self.region['center_northing']))
+
+ ew = (self.width / 2) * res
+ ns = (self.height / 2) * res
+
+ self.region['n'] = self.region['center_northing'] + ns
+ self.region['s'] = self.region['center_northing'] - ns
+ self.region['e'] = self.region['center_easting'] + ew
+ self.region['w'] = self.region['center_easting'] - ew
+
def ChangeMapSize(self, (width, height)):
"""Change size of rendered map.
@@ -437,7 +456,7 @@
# adjust region settigns to match monitor
self.region = self.__adjustRegion()
- # newextents = self.alignResolution()
+ # newextents = self.AlignResolution()
# self.region['n'] = newextents['n']
# self.region['s'] = newextents['s']
# self.region['e'] = newextents['e']
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-23 08:03:54 UTC (rev 1156)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-23 10:25:45 UTC (rev 1157)
@@ -512,7 +512,7 @@
def OnQuery(self, event):
"""Query selected lines/boundaries"""
- Debug.msg(2, "Digittoolbar.OnQuery(): %s" % self.parent.digit.settings["query"])
+ Debug.msg(2, "Digittoolbar.OnQuery(): %s" % self.parent.digit.settings["query"][0])
self.action="queryLine"
self.parent.MapWindow.mouse['box'] = 'box'
From landa at grass.itc.it Wed Oct 24 22:51:27 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Thu Oct 25 01:43:49 2007
Subject: [grass-addons] r1158 - in trunk/grassaddons/gui: display_driver
gui_modules
Message-ID: <200710242051.l9OKpRhG003368@grass.itc.it>
Author: landa
Date: 2007-10-24 22:51:22 +0200 (Wed, 24 Oct 2007)
New Revision: 1158
Modified:
trunk/grassaddons/gui/display_driver/driver.cpp
trunk/grassaddons/gui/gui_modules/digit.py
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/toolbars.py
Log:
Digitization tool: bugfix in display driver, break tool introduced (v.edit need to be fixed) x split
Modified: trunk/grassaddons/gui/display_driver/driver.cpp
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-23 10:25:45 UTC (rev 1157)
+++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-24 20:51:22 UTC (rev 1158)
@@ -307,7 +307,7 @@
wxPoint *point;
wxPen *pen;
- if (!IsSelected(line) && !drawSegments && !settings.vertex.enabled)
+ if (!IsSelected(line) && !settings.vertex.enabled)
return -1;
// determine color
@@ -322,7 +322,6 @@
}
else {
dcId = 1;
- dc->SetId(dcId);
}
}
@@ -332,7 +331,7 @@
for (int i = 1; i < pointsScreen->GetCount() - 1; i++, dcId += 2) {
point = (wxPoint*) pointsScreen->Item(i)->GetData();
- if (drawSegments) {
+ if (IsSelected(line) && drawSegments) {
dc->SetId(dcId);
dc->SetPen(*pen);
wxRect rect (*point, *point);
@@ -565,7 +564,7 @@
region.map_width = map_width;
region.map_height = map_height;
-#ifdef DEBUG:
+#ifdef DEBUG
std::cerr << "region: n=" << north
<< "; s=" << south
<< "; e=" << east
Modified: trunk/grassaddons/gui/gui_modules/digit.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/digit.py 2007-10-23 10:25:45 UTC (rev 1157)
+++ trunk/grassaddons/gui/gui_modules/digit.py 2007-10-24 20:51:22 UTC (rev 1158)
@@ -450,6 +450,11 @@
return self.__ModifyLines('merge')
+ def BreakLine(self):
+ """Break selected lines"""
+
+ return self.__ModifyLines('break')
+
def SnapLine(self):
"""Snap selected lines"""
@@ -520,11 +525,12 @@
def SelectLinesByQuery(self, pos1, pos2):
"""Select features by query"""
- thresh = self.settings['queryLength'][1]
if self.settings['query'][0] == "length":
+ thresh = self.settings['queryLength'][1]
if self.settings["queryLength"][0] == "shorter than":
thresh = -1 * thresh
else:
+ thresh = self.settings['queryDangle'][1]
if self.settings["queryDangle"][0] == "shorter than":
thresh = -1 * thresh
@@ -1313,7 +1319,7 @@
self.parent.digit.settings["queryLength"] = (self.queryLengthSL.GetStringSelection(),
int(self.queryLengthValue.GetValue()))
self.parent.digit.settings["queryDangle"] = (self.queryDangleSL.GetStringSelection(),
- int(self.queryDangleValue.GetValue()),)
+ int(self.queryDangleValue.GetValue()))
# update driver settings
self.parent.digit.driver.UpdateSettings()
Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-23 10:25:45 UTC (rev 1157)
+++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-10-24 20:51:22 UTC (rev 1158)
@@ -113,7 +113,6 @@
except Exception, e:
print "Command Thread: ",e
- pass
time.sleep(0.1)
@@ -1058,14 +1057,13 @@
if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex",
"copyCats", "editLine", "flipLine",
"mergeLine", "snapLine",
- "queryLine"]:
+ "queryLine", "breakLine"]:
nselected = 0
# -> delete line || move line || move vertex
if digitToolbar.action in ["moveVertex", "editLine"]:
if len(digitClass.driver.GetSelected()) == 0:
- # -> move vertex (select by point)
- # return vertex coordinates (tuple)
nselected = digitClass.driver.SelectLineByPoint(pos1, type="line")
+ # return point on the line
elif digitToolbar.action == "copyCats":
if not hasattr(self, "copyCatsIds"):
@@ -1104,8 +1102,6 @@
nselected = digitClass.driver.SelectLinesByBox(pos1, pos2)
if nselected > 0:
- # highlight selected features
- # self.UpdateMap(render=False)
if digitToolbar.action in ["moveLine", "moveVertex",
"copyCats", "editLine"]:
# get pseudoDC id of objects which should be redrawn
@@ -1133,6 +1129,8 @@
# -> move line || move vertex
self.UpdateMap(render=False)
+ if digitToolbar.action != "copyCats":
+ redrawAll = False
else: # no vector object found
self.UpdateMap(render=False, renderVector=False)
@@ -1169,7 +1167,9 @@
'map=%s' % digitClass.settings['backgroundMap'],
'cats=%s' % ",".join(["%d" % v for v in self.copyIds]),
'-i',
- 'color=yellow']
+ 'color=yellow',
+ 'fcolor=yellow',
+ 'type=point,line,boundary,centroid']
self.layerTmp = self.Map.AddLayer(type='vector',
command=dVectTmp)
self.UpdateMap(render=True, renderVector=False)
@@ -1359,9 +1359,9 @@
# move vertex
digitClass.MoveSelectedVertex(pFrom,
move)
- else: # edit line
- pass
+ redrawAll = True
+
del self.moveBegin
del self.moveCoords
del self.moveIds
@@ -1389,6 +1389,9 @@
x, y = self.pdcVector.GetIdBounds(id)[0:2]
coords.append(self.Pixel2Cell((x, y)))
digitClass.EditLine(line, coords)
+
+ redrawAll = True
+
del self.moveBegin
del self.moveCoords
del self.moveIds
@@ -1396,6 +1399,8 @@
digitClass.FlipLine()
elif digitToolbar.action == "mergeLine":
digitClass.MergeLine()
+ elif digitToolbar.action == "breakLine":
+ digitClass.BreakLine()
elif digitToolbar.action == "snapLine":
digitClass.SnapLine()
elif digitToolbar.action == "connectLine":
@@ -1462,12 +1467,14 @@
"addVertex", "removeVertex", "moveVertex",
"copyCats", "flipLine", "mergeLine",
"snapLine", "connectLine", "copyLine",
- "queryLine"]:
+ "queryLine", "breakLine"]:
# varios tools -> unselected selected features
digitClass.driver.SetSelected([])
if digitToolbar.action in ["moveLine", "moveVertex", "editLine"] and \
hasattr(self, "moveBegin"):
- # move feature -> delete 'move' variables
+
+ redrawAll = True
+
del self.moveBegin
del self.moveCoords
del self.moveIds
@@ -1522,7 +1529,7 @@
# (vertex, left vertex, left line,
# right vertex, right line)
- # self.pdcVector.RemoveId(self.moveIds[0])
+ ## self.pdcVector.RemoveId(self.moveIds[0])
# do not draw static lines
self.polycoords = []
if digitToolbar.action == "moveVertex":
@@ -1537,9 +1544,9 @@
self.pdcVector.RemoveId(self.moveIds[2]-1)
self.polycoords.append((x, y))
else: # edit line
- # self.pdcVector.TranslateId(self.moveIds[-1], dx, dy)
- # self.pdcVector.RemoveId(self.moveIds[-1]) # last vertex
- # self.pdcVector.RemoveId(self.moveIds[-1] - 1) # line
+ ## self.pdcVector.TranslateId(self.moveIds[-1], dx, dy)
+ ## self.pdcVector.RemoveId(self.moveIds[-1]) # last vertex
+ ## self.pdcVector.RemoveId(self.moveIds[-1] - 1) # line
try:
if self.moveIds[-1] > 0: # previous vertex
x, y = self.pdcVector.GetIdBounds(self.moveIds[-1])[0:2]
@@ -2232,7 +2239,7 @@
# reset mouse['box'] if needed
if self.digittoolbar.action in ['addLine']:
- if digittoolbar.type in ['point', 'centroid']:
+ if self.digittoolbar.type in ['point', 'centroid']:
self.MapWindow.mouse['box'] = 'point'
else: # line, boundary
self.MapWindow.mouse['box'] = 'line'
Modified: trunk/grassaddons/gui/gui_modules/toolbars.py
===================================================================
--- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-23 10:25:45 UTC (rev 1157)
+++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-10-24 20:51:22 UTC (rev 1158)
@@ -370,6 +370,10 @@
except:
pass
+ # close settings dialog if still open
+ if self.settingsDialog:
+ self.settingsDialog.OnCancel(None)
+
# disable the toolbar
self.parent.RemoveToolbar ("digit")
@@ -440,7 +444,8 @@
if not self.settingsDialog:
self.settingsDialog = DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"),
- style=wx.DEFAULT_DIALOG_STYLE).Show()
+ style=wx.DEFAULT_DIALOG_STYLE)
+ self.settingsDialog.Show()
def OnAdditionalToolMenu(self, event):
"""Menu for additional tools"""
@@ -451,19 +456,23 @@
toolMenu.AppendItem(copy)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnCopy, copy)
- flip = wx.MenuItem(toolMenu, wx.ID_ANY, 'Flip selected lines/boudaries')
+ flip = wx.MenuItem(toolMenu, wx.ID_ANY, 'Flip selected lines')
toolMenu.AppendItem(flip)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnFlip, flip)
- merge = wx.MenuItem(toolMenu, wx.ID_ANY, 'Merge selected lines/boundaries')
+ merge = wx.MenuItem(toolMenu, wx.ID_ANY, 'Merge selected lines')
toolMenu.AppendItem(merge)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnMerge, merge)
- snap = wx.MenuItem(toolMenu, wx.ID_ANY, 'Snap selected lines/boundaries')
+ breakL = wx.MenuItem(toolMenu, wx.ID_ANY, 'Break selected lines at intersection')
+ toolMenu.AppendItem(breakL)
+ self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnBreak, breakL)
+
+ snap = wx.MenuItem(toolMenu, wx.ID_ANY, 'Snap selected lines (only to nodes)')
toolMenu.AppendItem(snap)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnSnap, snap)
- connect = wx.MenuItem(toolMenu, wx.ID_ANY, 'Connect selected two lines/boundaries')
+ connect = wx.MenuItem(toolMenu, wx.ID_ANY, 'Connect two selected lines')
toolMenu.AppendItem(connect)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnConnect, connect)
@@ -471,7 +480,7 @@
toolMenu.AppendItem(query)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnQuery, query)
- zbulk = wx.MenuItem(toolMenu, wx.ID_ANY, 'Z bulk-labeling 3D lines')
+ zbulk = wx.MenuItem(toolMenu, wx.ID_ANY, 'Z bulk-labeling of 3D lines')
toolMenu.AppendItem(zbulk)
self.parent.MapWindow.Bind(wx.EVT_MENU, self.OnZBulk, zbulk)
@@ -498,6 +507,12 @@
self.action="mergeLine"
self.parent.MapWindow.mouse['box'] = 'box'
+ def OnBreak(self, event):
+ """Break selected lines/boundaries"""
+ Debug.msg(2, "Digittoolbar.OnBreak():")
+ self.action="breakLine"
+ self.parent.MapWindow.mouse['box'] = 'box'
+
def OnSnap(self, event):
"""Snap selected features"""
Debug.msg(2, "Digittoolbar.OnSnap():")
From landa at grass.itc.it Fri Oct 26 23:04:01 2007
From: landa at grass.itc.it (landa@grass.itc.it)
Date: Fri Oct 26 23:04:04 2007
Subject: [grass-addons] r1159 - in trunk/grassaddons/gui: display_driver
gui_modules
Message-ID: <200710262104.l9QL41Xe011766@grass.itc.it>
Author: landa
Date: 2007-10-26 23:03:56 +0200 (Fri, 26 Oct 2007)
New Revision: 1159
Modified:
trunk/grassaddons/gui/display_driver/driver.cpp
trunk/grassaddons/gui/display_driver/driver.h
trunk/grassaddons/gui/gui_modules/mapdisp.py
trunk/grassaddons/gui/gui_modules/toolbars.py
Log:
Basic changes to enable zooming, panning when new feature is digitized
Modified: trunk/grassaddons/gui/display_driver/driver.cpp
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-24 20:51:22 UTC (rev 1158)
+++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-10-26 21:03:56 UTC (rev 1159)
@@ -731,6 +731,9 @@
/**
\brief Select vector objects by given bounding box
+ If line id is already in the list of selected lines, then it will
+ be excluded from this list.
+
\param[in] x1,y1,x2,y2 corners coordinates of bounding box
\return number of selected features
@@ -767,7 +770,12 @@
for (int i = 0; i < list->n_values; i++) {
line = list->value[i];
- selected.push_back(line);
+ if (!IsSelected(line)) {
+ selected.push_back(line);
+ }
+ else {
+ selected.erase(GetSelectedIter(line));
+ }
}
// remove all duplicate ids
@@ -840,13 +848,29 @@
*/
bool DisplayDriver::IsSelected(int line)
{
- for(std::vector::const_iterator i = selected.begin(), e = selected.end();
+ if (GetSelectedIter(line) != selected.end())
+ return true;
+
+ return false;
+}
+
+/**
+ \brief Is vector object selected?
+
+ \param[in] line id
+
+ \return item iterator
+ \return selected.end() if object is not selected
+*/
+std::vector::iterator DisplayDriver::GetSelectedIter(int line)
+{
+ for(std::vector::iterator i = selected.begin(), e = selected.end();
i != e; ++i) {
if (line == *i)
- return true;
+ return i;
}
- return false;
+ return selected.end();
}
/**
@@ -928,6 +952,8 @@
/**
\brief Get PseudoDC vertex id of selected line
+ Set bounding box for vertices of line.
+
\param[in] x,y coordinates of click
\param[in] thresh threshold value
@@ -957,6 +983,7 @@
type = Vect_read_line (mapInfo, points, cats, line);
// find the closest vertex (x, y)
+ DCid = 1;
for(int idx = 0; idx < points->n_points; idx++) {
dist = Vect_points_distance(x, y, 0.0,
points->x[idx], points->y[idx], points->z[idx], 0);
@@ -971,6 +998,12 @@
Gid = idx;
}
}
+
+ Cell2Pixel(points->x[idx], points->y[idx], points->z[idx],
+ &vx, &vy, &vz);
+ wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
+ dc->SetIdBounds(DCid, rect);
+ DCid+=2;
}
if (minDist > thresh)
@@ -979,25 +1012,16 @@
// desc = &(ids[line]);
// translate id
- // DCid = Gid * 2 + desc->startId;
DCid = Gid * 2 + 1;
// add selected vertex
returnId.push_back(DCid);
- Cell2Pixel(points->x[Gid], points->y[Gid], points->z[Gid],
- &vx, &vy, &vz);
- wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
- dc->SetIdBounds(DCid, rect);
// left vertex
if (DCid == startId) {
returnId.push_back(-1);
}
else {
returnId.push_back(DCid - 2);
- Cell2Pixel(points->x[Gid-1], points->y[Gid-1], points->z[Gid-1],
- &vx, &vy, &vz);
- wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
- dc->SetIdBounds(DCid-2, rect);
}
// right vertex
@@ -1006,10 +1030,6 @@
}
else {
returnId.push_back(DCid + 2);
- Cell2Pixel(points->x[Gid+1], points->y[Gid+1], points->z[Gid+1],
- &vx, &vy, &vz);
- wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy));
- dc->SetIdBounds(DCid + 2, rect);
}
return returnId;
Modified: trunk/grassaddons/gui/display_driver/driver.h
===================================================================
--- trunk/grassaddons/gui/display_driver/driver.h 2007-10-24 20:51:22 UTC (rev 1158)
+++ trunk/grassaddons/gui/display_driver/driver.h 2007-10-26 21:03:56 UTC (rev 1159)
@@ -1,6 +1,6 @@
#include // debug
#include
-#include