From barton at grass.itc.it Mon Sep 3 08:34:08 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Sep 3 08:34:10 2007 Subject: [grass-addons] r1063 - trunk/grassaddons/gui/gui_modules Message-ID: <200709030634.l836Y81W025456@grass.itc.it> Author: barton Date: 2007-09-03 08:34:00 +0200 (Mon, 03 Sep 2007) New Revision: 1063 Modified: trunk/grassaddons/gui/gui_modules/select.py Log: Select now uses g.mlist (would prefer g.list if it can be changed to parse differently) instead of searching directories for elements (i.e., element locations no longer hard-coded). Added select.Select.SetElementList(type) method to refresh selection list. Modified: trunk/grassaddons/gui/gui_modules/select.py =================================================================== --- trunk/grassaddons/gui/gui_modules/select.py 2007-08-31 20:29:45 UTC (rev 1062) +++ trunk/grassaddons/gui/gui_modules/select.py 2007-09-03 06:34:00 UTC (rev 1063) @@ -64,7 +64,6 @@ self.SetSizer(sizer) sizer.Fit(self) - class Select(wx.combo.ComboCtrl): def __init__(self, parent, id, size, type): """ @@ -73,11 +72,15 @@ Elements can be selected with mouse. """ wx.combo.ComboCtrl.__init__(self, parent=parent, id=id, size=size) - tcp = TreeCtrlComboPopup() - self.SetPopupControl(tcp) + self.tcp = TreeCtrlComboPopup() + self.SetPopupControl(self.tcp) self.SetPopupExtents(0,100) - tcp.GetElementList(type) + self.tcp.GetElementList(type) + def SetElementList(self, type): + self.tcp.seltree.DeleteAllItems() + self.tcp.GetElementList(type) + class TreeCtrlComboPopup(wx.combo.ComboPopup): """ Create a tree ComboBox for selecting maps and other GIS elements @@ -152,41 +155,60 @@ with all relevant elements displayed beneath each mapset branch """ #set environmental variables - cmdlist = ['g.gisenv', 'get=GISDBASE'] - gisdbase = cmd.Command(cmdlist).module_stdout.read().strip() - - cmdlist = ['g.gisenv', 'get=LOCATION_NAME'] - location = cmd.Command(cmdlist).module_stdout.read().strip() - cmdlist = ['g.gisenv', 'get=MAPSET'] curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip() - location_path = os.path.join (gisdbase,location) - windfile = os.path.join (location_path,'PERMANENT','WIND') - symbol_path = os.path.join (os.environ['GISBASE'],'etc','symbol') - - #valid location test if needed - if windfile != None: - pass - #mapsets in current location cmdlist = ['g.mapsets', '-p'] mapsets = cmd.Command(cmdlist).module_stdout.read().strip().split(' ') - elementlist = ['cell', - 'grid3d', - 'vector', - 'dig', - 'dig_ascii', - 'icons', - 'paint/labels', - 'site_lists', - 'windows', - 'windows3d', - 'group', - '3d.view'] + # map element types to g.mlist types + elementdict = {'cell':'rast', + 'raster':'rast', + 'rast':'rast', + 'raster files':'rast', + 'grid3':'rast3d', + 'rast3d':'rast3d', + 'raster3D':'rast3d', + 'raster3D files':'rast3d', + 'vector':'vect', + 'vect':'vect', + 'binary vector files':'vect', + 'dig':'oldvect', + 'oldvect':'oldvect', + 'old vector':'oldvect', + 'dig_ascii':'asciivect', + 'asciivect':'asciivect', + 'asciivector':'asciivect', + 'ascii vector files':'asciivect', + 'icons':'icon', + 'icon':'icon', + 'paint icon files':'icon', + 'paint/labels':'labels', + 'labels':'labels', + 'label':'labels', + 'paint label files':'labels', + 'site_lists':'sites', + 'sites':'sites', + 'site list':'sites', + 'site list files':'sites', + 'windows':'region', + 'region':'region', + 'region definition':'region', + 'region definition files':'region', + 'windows3d':'region3d', + 'region3d':'region3d', + 'region3D definition':'region3d', + 'region3D definition files':'region3d', + 'group':'group', + 'imagery group':'group', + 'imagery group files':'group', + '3d.view':'3dview', + '3dview':'3dview', + '3D viewing parameters':'3dview', + '3D view parameters':'3dview'} - if element not in elementlist: + if element not in elementdict: self.AddItem('Not selectable element') return @@ -196,20 +218,22 @@ dir_node = self.AddItem('Mapset: '+dir) self.seltree.SetItemTextColour(dir_node, wx.Colour(50,50,200)) try: - elem_list = os.listdir(os.path.join (location_path, dir, element)) + cmdlist = ['g.mlist', 'type=%s' % elementdict[element], 'mapset=%s' % dir] + elem_list = cmd.Command(cmdlist).module_stdout.read().strip().split('\n') elem_list.sort() for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) + if elem != '': self.AddItem(elem+'@'+dir, parent=dir_node) except: continue else: dir_node = self.AddItem('Mapset: '+dir) self.seltree.SetItemTextColour(dir_node,wx.Colour(50,50,200)) try: - elem_list = os.listdir(os.path.join (location_path, dir, element)) + cmdlist = ['g.mlist', 'type=%s' % elementdict[element], 'mapset=%s' % dir] + elem_list = cmd.Command(cmdlist).module_stdout.read().strip().split('\n') elem_list.sort() for elem in elem_list: - self.AddItem(elem+'@'+dir, parent=dir_node) + if elem != '': self.AddItem(elem+'@'+dir, parent=dir_node) except: continue From barton at grass.itc.it Mon Sep 3 08:35:05 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Sep 3 08:35:07 2007 Subject: [grass-addons] r1064 - trunk/grassaddons/gui/gui_modules Message-ID: <200709030635.l836Z5nt025476@grass.itc.it> Author: barton Date: 2007-09-03 08:34:57 +0200 (Mon, 03 Sep 2007) New Revision: 1064 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Added a bit more code to make this useable with georectifier, for interactive GCP marking. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 06:34:00 UTC (rev 1063) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 06:34:57 UTC (rev 1064) @@ -215,7 +215,7 @@ self.pdc = wx.PseudoDC() # used for digitization tool self.pdcVector = None - + # will store an off screen empty bitmap for saving to file self._Buffer = '' @@ -390,7 +390,7 @@ # draw to the dc using the calculated clipping rect self.pdc.DrawToDCClipped(dc, rgn) - # draw vector map layer + # draw vector map layer if self.pdcVector: self.pdcVector.DrawToDCClipped(dc, rgn) @@ -469,7 +469,7 @@ img = None self.imagedict[img] = 99 # set image PseudoDC ID - + return img @@ -501,9 +501,9 @@ return False # draw background map image to PseudoDC - self.Draw(self.pdc, self.img, drawid=id) - - # render vector map layer + self.Draw(self.pdc, self.img, drawid=id) + + # render vector map layer digitToolbar = self.parent.digittoolbar if digitToolbar and \ digitToolbar.layerSelectedID != None: @@ -921,7 +921,7 @@ else: # -> moveLine || deleteLine (select by box) nselected = driver.SelectLinesByBox(pos1, pos2) - + if nselected > 0: # highlight selected features self.UpdateMap(render=False) @@ -1113,7 +1113,7 @@ self.mouse['begin'][1])) elif digit.action == "removeVertex": # remove vertex - self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], + self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1])) if digit.action != "addLine": @@ -1575,6 +1575,7 @@ # self.maptoolbar = None self.digittoolbar = None + self.grtoolbar = None for toolb in toolbars: self.AddToolbar(toolb) @@ -1658,6 +1659,7 @@ Currently known toolbars are: * map * digit + * georect """ if name == "map": self.maptoolbar = toolbars.MapToolbar(self, self.Map) @@ -1682,6 +1684,12 @@ BottomDockable(False).TopDockable(True). CloseButton(False).Layer(2)) + # change mouse to draw digitized line + self.MapWindow.mouse['box'] = "point" + self.MapWindow.zoomtype = 0 + self.MapWindow.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) + self.MapWindow.polypen = wx.Pen(colour='green', width=2, style=wx.SOLID) + elif name == "georect": self.grtoolbar = toolbars.GRToolbar(self, self.Map) @@ -1693,12 +1701,6 @@ BottomDockable(False).TopDockable(True). CloseButton(False).Layer(2)) - # change mouse to draw digitized line - self.MapWindow.mouse['box'] = "point" - self.MapWindow.zoomtype = 0 - self.MapWindow.pen = wx.Pen(colour='red', width=2, style=wx.SOLID) - self.MapWindow.polypen = wx.Pen(colour='green', width=2, style=wx.SOLID) - self._mgr.Update() def RemoveToolbar (self, name): @@ -1780,7 +1782,7 @@ # change the cursor if self.digittoolbar: # digitization tool activated - self.MapWindow.SetCursor(self.cursors["cross"]) + self.MapWindow.SetCursor(self.cursors["cross"]) else: self.MapWindow.SetCursor(self.cursors["default"]) From barton at grass.itc.it Mon Sep 3 08:35:51 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Mon Sep 3 08:35:53 2007 Subject: [grass-addons] r1065 - trunk/grassaddons/gui/gui_modules Message-ID: <200709030635.l836Zp97025496@grass.itc.it> Author: barton Date: 2007-09-03 08:35:43 +0200 (Mon, 03 Sep 2007) New Revision: 1065 Modified: trunk/grassaddons/gui/gui_modules/georect.py Log: Georectification setup wizard now works well. Will now launch mapdisplay for GCP setting. Modified: trunk/grassaddons/gui/gui_modules/georect.py =================================================================== --- trunk/grassaddons/gui/gui_modules/georect.py 2007-09-03 06:34:57 UTC (rev 1064) +++ trunk/grassaddons/gui/gui_modules/georect.py 2007-09-03 06:35:43 UTC (rev 1065) @@ -27,6 +27,13 @@ import tempfile import shutil +try: + import subprocess # Not needed if GRASS commands could actually be quiet +except: + CompatPath = os.path.join( os.getenv("GISBASE"),"etc","wx") + sys.path.append(CompatPath) + from compat import subprocess + import wx import wx.aui import wx.lib.filebrowsebutton as filebrowse @@ -69,15 +76,15 @@ global xy_location global xy_mapset global xy_group -global xy_dispmap +global xy_map global maptype xy_location = '' xy_mapset = '' xy_group = '' -xy_dispmap = '' -maptype = 'raster' +xy_map = '' +maptype = 'cell' class Georectify(object): """ @@ -119,7 +126,6 @@ self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD)) self.sizer = wx.BoxSizer(wx.VERTICAL) -# self.sizer = rcs.RowColSizer() tmpsizer = wx.BoxSizer(wx.VERTICAL) tmpsizer.Add(self.title, 0, wx.ALIGN_CENTRE|wx.ALL, 5) @@ -130,15 +136,7 @@ self.SetSizer(tmpsizer) self.SetAutoLayout(True) tmpsizer.Fit(self) -# self.SetSizer(self.sizer) -# self.sizer.Fit(tmpsizer) - - def SwitchLocMapset(self, location, mapset): - cmdlst = ['g.mapset','mapset=%s' % mapset,'location=%s' % location,'--q'] - cmd.Command(cmdlist) - - class GeorectWizard(object): """ Start wizard here and finish wizard here @@ -164,8 +162,6 @@ global curr_mapset curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip() - self.maptype = '' - # define wizard pages self.wizard = wiz.Wizard(parent, -1, "Setup for georectification") self.startpage = LocationPage(self.wizard, self) @@ -182,6 +178,8 @@ self.wizard.FitToPage(self.startpage) +# self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) + success = False if self.wizard.RunWizard(self.startpage): @@ -193,11 +191,59 @@ else: wx.MessageBox("Georectifying setup canceled.") -# self.wizard.Destroy() + # start display showing xymap + self.Map = render.Map() # instance of render.Map to be associated with display + self.xy_mapdisp = mapdisp.MapFrame(self.parent, title="Set ground control points (GCPs)", + pos=wx.DefaultPosition, size=wx.DefaultSize, + style=wx.DEFAULT_FRAME_STYLE, toolbars=["georect"], + Map=self.Map) + + #show new display + self.xy_mapdisp.Show() + self.xy_mapdisp.Refresh() + self.xy_mapdisp.Update() + + + # start GCP form + + self.Cleanup() + + def SwitchLocMapset(self, location, mapset): + + cmdlist = ['g.gisenv', 'set=LOCATION_NAME=%s' % location] + cmd.Command(cmdlist) + + cmdlist = ['g.gisenv', 'set=MAPSET=%s' % mapset] + cmd.Command(cmdlist) + def onWizFinished(self): - return success + global grassdatabase + global curr_location + global curr_mapset + global xy_location + global xy_mapset + global xy_group + global xy_map + global maptype + print 'Current global variables' + print 'curr_location=',curr_location + print 'curr_mapset=',curr_mapset + print 'xy_location=',xy_location + print 'xy_mapset=',xy_mapset + print 'xy_group=',xy_group + print 'xy_map=',xy_map + print 'maptype=',maptype + + return True + + def Cleanup(self): + # return to current location and mapset + global curr_location + self.SwitchLocMapset(curr_location, curr_mapset) + self.wizard.Destroy() + class LocationPage(TitledPage): """ Set map type (raster or vector) to georectify and @@ -254,11 +300,21 @@ box.Add(self.cb_mapset, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + self.Bind(wx.EVT_RADIOBOX, self.OnMaptype, self.rb_maptype) self.Bind(wx.EVT_COMBOBOX, self.OnLocation, self.cb_location) self.Bind(wx.EVT_COMBOBOX, self.OnMapset, self.cb_mapset) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged) + self.Bind(wx.EVT_CLOSE, self.parent.Cleanup) + def OnMaptype(self,event): + global maptype + + if event.GetInt() == 0: + maptype = 'cell' + elif event.GetInt() == 1: + maptype = 'vector' + def OnLocation(self, event): global grassdatabase global xy_location @@ -326,6 +382,7 @@ self.Bind(wx.EVT_COMBOBOX, self.OnGroup, self.cb_group) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged) + self.Bind(wx.EVT_CLOSE, self.parent.Cleanup) def OnGroup(self, event): global xy_location @@ -373,181 +430,51 @@ TitledPage.__init__(self, wizard, "Select image/map to display for ground control point (GCP) creation") self.parent = parent + global maptype - global curr_location - global curr_mapset - global xy_location - global xy_mapset - global xy_group + self.parent = parent - self.path = '' - box = wx.BoxSizer(wx.HORIZONTAL) label = wx.StaticText(self, -1, 'Select display image/map:', style=wx.ALIGN_LEFT) box.Add(label, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.selection = select.Select(self, id=wx.ID_ANY, size=(300,-1), - type=self.parent.maptype ) + type=maptype ) box.Add(self.selection, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.Bind(wx.EVT_TEXT, self.OnSelection, self.selection) + self.selection.Bind(wx.EVT_TEXT, self.OnSelection) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGING, self.onPageChanging) self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnPageChanged) + self.Bind(wx.EVT_CLOSE, self.parent.Cleanup) def OnSelection(self,event): - global xy_dispmap - xy_dispmap = event.GetString() - print 'map =',xy_dispmap + global xy_map + xy_map = event.GetString() + def onPageChanging(self,event=None): - global xy_dispmap - if event.GetDirection() and xy_dispmap == '': + global xy_map + + if event.GetDirection() and xy_map == '': wx.MessageBox('You must select a valid image/map in order to continue') event.Veto() return - else: - pass - # return to current location/mapset def OnPageChanged(self,event=None): - if event.GetDirection(): - # switch to xy location - pass + global curr_location + global curr_mapset + global xy_location + global xy_mapset + global maptype - -class GeorectStart(wx.Dialog): - def __init__(self, parent, id=wx.ID_ANY, title=_('Set georectification parameters'), - pos=wx.DefaultPosition, size=(-1,-1), - style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER): - wx.Dialog.__init__(self, parent, id, title, pos, size, style) - - #set environmental variables - cmdlist = ['g.gisenv', 'get=GISDBASE'] - self.grassdatabase = cmd.Command(cmdlist).module_stdout.read().strip() - - cmdlist = ['g.gisenv', 'get=LOCATION_NAME'] - self.curr_location = cmd.Command(cmdlist).module_stdout.read().strip() - - cmdlist = ['g.gisenv', 'get=MAPSET'] - self.curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip() - - self.StartDir = os.path.join(self.grassdatabase,self.curr_location) - self.grassdatabase = '' - self.xy_locationPath = '' - self.xy_location = '' - self.xy_mapset = '' - self.xy_mapsetPath = '' - self.xy_groupPath = '' - self.xy_group = '' - - #select display map (entry) - #start and cancel (buttons) - - sizer = wx.BoxSizer(wx.VERTICAL) - - box = wx.BoxSizer(wx.HORIZONTAL) - self.rb_maptype = wx.RadioBox(self, -1, "Map type to georectify", - wx.DefaultPosition, wx.DefaultSize, - ['raster','vector'], 2, wx.RA_SPECIFY_COLS) - box.Add(self.rb_maptype, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - box = wx.BoxSizer(wx.HORIZONTAL) - self.dbb_mapset = filebrowse.DirBrowseButton( - self, wx.ID_ANY, size=(450, -1), - labelText='Select mapset: ', - buttonText='Browse ...', - toolTip='Select mapset of maps to georeference', - dialogTitle='Mapsets', - startDirectory=self.StartDir, - changeCallback = self.On_dbb_mapset) - box.Add(self.dbb_mapset, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - box = wx.BoxSizer(wx.HORIZONTAL) - self.btn_mkgroup = wx.Button(self, wx.ID_ANY, "Make group ...") - box.Add(self.btn_mkgroup, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - box = wx.BoxSizer(wx.HORIZONTAL) - self.dbb_group = filebrowse.DirBrowseButton( - self, wx.ID_ANY, size=(450, -1), - labelText='Select group: ', - buttonText='Browse ...', - toolTip='Select group of maps to georeference', - dialogTitle='Groups', - startDirectory=self.xy_groupPath, - changeCallback = self.On_dbb_group) - # Need to deactivate until xy_mapsetPath is set - box.Add(self.dbb_group, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - #Select the display map here...???? - #In TclTk, first switch to xy mapset; then select map - box = wx.BoxSizer(wx.HORIZONTAL) - self.btn_selmap = wx.Button(self, wx.ID_ANY, "Select map ...") - - box.Add(self.btn_selmap, 0, wx.ALIGN_CENTRE|wx.ALL, 5) - self.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) - self.sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5) - - btnsizer = wx.StdDialogButtonSizer() - - btn = wx.Button(self, wx.ID_OK) - btn.SetDefault() - btnsizer.AddButton(btn) - - btn = wx.Button(self, wx.ID_CANCEL) - btnsizer.AddButton(btn) - btnsizer.Realize() - - self.sizer.Add(btnsizer, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - - self.SetSizer(sizer) - sizer.Fit(self) - - self.Bind(wx.EVT_BUTTON, self.OnMkgroup, self.btn_mkgroup) - self.Bind(wx.EVT_BUTTON, self.OnSelectMap, self.btn_selmap) - - def On_dbb_mapset(self,event): - self.xy_mapsetPath = event.GetString() - self.xy_locationPath,self.xy_mapset = os.path.split(self.xy_mapsetPath) - self.grassdatabase, self.xy_location = os.path.split(self.xy_locationPath) - self.StartDir = self.xy_mapsetPath - self.xy_groupPath = os.path.join(self.xy_mapsetPath,'group') - self.Refresh() - print 'group start =',self.xy_groupPath - print 'new start dir =',self.StartDir - - def On_dbb_group(self,event): - if self.xy_mapsetPath != '': - self.xy_groupPath,self.xy_group = os.path.split(event.GetString()) - print 'group =',self.xy_group + if event.GetDirection(): + # switch to xy location if coming into the page from preceding + self.parent.SwitchLocMapset(xy_location, xy_mapset) + self.selection.SetElementList(maptype) else: - wx.MessageBox('You must select a valid mapset') + # switch back to current location if leaving the page + self.parent.SwitchLocMapset(curr_location, curr_mapset) - def OnSelectMap(self,event): - dlg = select.SelectDialog(self,title="Select map",type='cell') - dlg.CenterOnScreen() - if dlg.ShowModal() == wx.ID_OK: - self.xy_map = dlg.selection.GetValue() - - dlg.Destroy() - print 'selection =',self.xy_map - - - def OnMkgroup(self,event): - menuform.GUI().ParseCommand('i.group', parentframe=self) - pass - - def SwitchToXY(self): - pass - - def SwitchBack(self): - pass - class GCP(wx.Frame): """ Manages ground control points for georectifying. Calculates RMS statics. From landa at grass.itc.it Mon Sep 3 15:08:20 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Sep 3 15:08:21 2007 Subject: [grass-addons] r1066 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709031308.l83D8KeI029263@grass.itc.it> Author: landa Date: 2007-09-03 15:08:18 +0200 (Mon, 03 Sep 2007) New Revision: 1066 Modified: trunk/grassaddons/gui/display_driver/driver.cc trunk/grassaddons/gui/display_driver/driver.h trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/profile.py trunk/grassaddons/gui/gui_modules/render.py trunk/grassaddons/gui/gui_modules/utils.py trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: Expend statusbar information (coordinates, extent, geometry). Auto-rendering added. Minor updates of digitization tool (still disabled). Fix Pixel2Cell() & panning. Modified: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-03 13:08:18 UTC (rev 1066) @@ -111,9 +111,11 @@ int x, y, z; // screen coordinates bool draw; // draw object ? + // read line type = Vect_read_line (mapInfo, points, cats, line); + + // clear screen points & convert EN -> xy pointsScreen->Clear(); - for (int i = 0; i < points->n_points; i++) { Cell2Pixel(points->x[i], points->y[i], points->z[i], &x, &y, &z); @@ -177,8 +179,8 @@ } } - DrawLineVerteces(line); // draw vertices - DrawLineNodes(line); // draw nodes + //DrawLineVerteces(line); // draw vertices + //DrawLineNodes(line); // draw nodes } else if (type & GV_POINTS) { if (type == GV_POINT && settings.point.enabled) { @@ -386,9 +388,9 @@ void DisplayDriver::Cell2Pixel(double east, double north, double depth, int *x, int *y, int *z) { - *x = int((east - region.west) / region.ew_res); - *y = int((region.north - north) / region.ns_res); - *z = 0; + *x = int((east - region.west_real) / region.res); + *y = int((region.north_real - north) / region.res); + *z = 0; return; } @@ -403,7 +405,9 @@ \return */ void DisplayDriver::SetRegion(double north, double south, double east, double west, - double ns_res, double ew_res) + double ns_res, double ew_res, + double center_easting, double center_northing, + double map_width, double map_height) { region.north = north; region.south = south; @@ -412,6 +416,18 @@ region.ns_res = ns_res; region.ew_res = ew_res; + region.center_easting = center_easting; + region.center_northing = center_northing; + + region.map_width = map_width; + region.map_height = map_height; + + // calculate real region + region.res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res; + + region.west_real = region.center_easting - (region.map_width / 2) * region.res; + region.north_real = region.center_northing + (region.map_height / 2) * region.res; + return; } Modified: trunk/grassaddons/gui/display_driver/driver.h =================================================================== --- trunk/grassaddons/gui/display_driver/driver.h 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/display_driver/driver.h 2007-09-03 13:08:18 UTC (rev 1066) @@ -27,7 +27,7 @@ #include } -#define DEBUG +//#define DEBUG class DisplayDriver { @@ -52,12 +52,22 @@ struct line_cats *cats; struct _region { - double north; + double north; // map units double south; double east; double west; double ns_res; double ew_res; + double center_easting; + double center_northing; + + double map_width; // px + double map_height; + + // real region + double west_real; + double north_real; + double res; } region; struct symbol { @@ -129,7 +139,10 @@ /* set */ void SetRegion(double north, double south, double east, double west, - double ns_res, double ew_res); + double ns_res, double ew_res, + double center_easting, double center_northing, + double map_width, double map_height); + void SetSettings(unsigned long highlight, bool ePoint, unsigned long cPoint, /* enabled, color */ bool eLine, unsigned long cLine, Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -388,11 +388,8 @@ """ Gets coordinates from mouse clicking on display window """ - # screen coordinates - posx, posy = event.GetPositionTuple() - # map coordinates - x, y = self.mapdisp.MapWindow.Pixel2Cell(posx, posy) + x, y = self.mapdisp.MapWindow.Pixel2Cell(event.GetPositionTuple()) #print 'coordinates =',x,y category = "" Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -437,9 +437,12 @@ Return wx.Image """ - + import time + start = time.clock() nlines = self.__display.DrawMap(pdc) - Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d" % nlines) + stop = time.clock() + Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d, sec=%f" % \ + (nlines, stop-start)) return nlines def SelectLinesByBox(self, begin, end, onlyType=None): @@ -513,19 +516,23 @@ self.__display.SetSelected(id) - def SetRegion(self, reg): + def UpdateRegion(self): """Set geographical region Needed for 'cell2pixel' conversion""" - Debug.msg(3, "CDisplayDriver.SetRegion(): %s" % reg) + map = self.mapwindow.Map + reg = map.region self.__display.SetRegion(reg['n'], - reg['s'], - reg['e'], - reg['w'], - reg['nsres'], - reg['ewres']) + reg['s'], + reg['e'], + reg['w'], + reg['nsres'], + reg['ewres'], + reg['center_easting'], + reg['center_northing'], + map.width, map.height) def UpdateSettings(self): """Update display driver settings""" @@ -1192,3 +1199,7 @@ # update driver settings if not usePyDisplayDriver: self.parent.digit.driver.UpdateSettings() + + # redraw map if auto-rendering is enabled + if self.parent.autoRender.GetValue(): + self.parent.ReRender(None) Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -403,7 +403,7 @@ Debug.msg(3, "BufferedWindow.OnSize():") # set size of the input image - self.Map.width, self.Map.height = self.GetClientSize() + self.Map.ChangeMapSize(self.GetClientSize()) # 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 @@ -421,6 +421,9 @@ # re-render image on idle self.resize = True + # reposition checkbox in statusbar + self.parent.StatusbarReposition() + def OnIdle(self, event): """ Only re-render a compsite map image from GRASS during @@ -428,7 +431,7 @@ """ if self.resize: - self.UpdateMap() + self.UpdateMap(render=True) event.Skip() @@ -482,16 +485,18 @@ Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s" % \ (render)) - if render: + if render or self.img == None: # render new map images - self.Map.width, self.Map.height = self.GetClientSize() + self.Map.ChangeMapSize(self.GetClientSize()) self.mapfile = self.Map.Render(force=True) self.img = self.GetImage() # id=99 self.resize = False if not self.img: + self.Draw(self.pdc, pdctype='clear') return False + # clear pseudodc self.pdc.Clear() self.pdc.RemoveAll() @@ -500,20 +505,26 @@ except: return False + # # draw background map image to PseudoDC - self.Draw(self.pdc, self.img, drawid=id) - - # render vector map layer + # + self.Draw(self.pdc, self.img, drawid=id) + + # + # render vector map layer + # digitToolbar = self.parent.digittoolbar if digitToolbar and \ digitToolbar.layerSelectedID != None: # set region - self.parent.digit.driver.SetRegion(self.Map.region) + self.parent.digit.driver.UpdateRegion() # draw map self.pdcVector = wx.PseudoDC() self.parent.digit.driver.DrawMap(self.pdcVector) + # # overlay + # self.ovldict = self.GetOverlay() # list of decoration overlay images if self.ovldict != {}: # draw scale and legend overlays for id in self.ovldict: @@ -531,14 +542,24 @@ self.resize = False + # # update statusbar + # self.Map.SetRegion() - self.parent.statusbar.SetStatusText("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"]), - 0) + if self.parent.statusText == "Extent": + self.parent.statusbar.SetStatusText("%.2f-%.2f,%.2f-%.2f" % + (self.Map.region["w"], self.Map.region["e"], + self.Map.region["n"], self.Map.region["s"]), 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.statusbar.SetStatusText("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"]), + # 0) return True @@ -557,8 +578,6 @@ dc.SetBackground(wx.Brush("White")) bitmap = wx.BitmapFromImage(self.img) - if self.imgVectorMap: - bitmap = wx.BitmapFromImage(self.imgVectorMap) self.dragimg = wx.DragImage(bitmap) self.dragimg.BeginDrag((0, 0), self) @@ -761,8 +780,7 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization digitToolbar = self.parent.digittoolbar - east, north = self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1]) + east, north = self.Pixel2Cell(self.mouse['begin']) try: map = digitToolbar.layers[digitToolbar.layerSelectedID].name @@ -885,7 +903,7 @@ self.Zoom(self.mouse['begin'], self.mouse['end'], self.zoomtype) # redraw map - self.UpdateMap() + self.UpdateMap(render=True) elif self.mouse["use"] == "query": # querying @@ -907,8 +925,8 @@ # digitization tool active digitToolbar = self.parent.digittoolbar self.mouse['end'] = event.GetPositionTuple()[:] - pos1 = self.Pixel2Cell(self.mouse['begin'][0], self.mouse['begin'][1]) - pos2 = self.Pixel2Cell(self.mouse['end'][0], self.mouse['end'][1]) + pos1 = self.Pixel2Cell(self.mouse['begin']) + pos2 = self.Pixel2Cell(self.mouse['end']) if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex"]: nselected = 0 @@ -1048,7 +1066,7 @@ mapcoords = [] # xy -> EN for coord in self.polycoords: - mapcoords.append(self.Pixel2Cell (coord[0], coord[1])) + mapcoords.append(self.Pixel2Cell(coord)) self.parent.digit.AddLine(map=map, type=self.parent.digittoolbar.type, @@ -1096,8 +1114,7 @@ self.parent.digit.MoveSelectedLines(move) else: # move vertex - self.parent.digit.MoveSelectedVertex(self.Pixel2Cell (self.moveCoords[0], - self.moveCoords[1]), + self.parent.digit.MoveSelectedVertex(self.Pixel2Cell(self.moveCoords), move) del self.moveBegin @@ -1105,16 +1122,13 @@ del self.moveIds elif digit.action == "splitLine": # split line - self.parent.digit.SplitLine(self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1])) + self.parent.digit.SplitLine(self.Pixel2Cell(self.mouse['begin'])) elif digit.action == "addVertex": # add vertex - self.parent.digit.AddVertex(self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1])) + self.parent.digit.AddVertex(self.Pixel2Cell(self.mouse['begin'])) elif digit.action == "removeVertex": # remove vertex - self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'][0], - self.mouse['begin'][1])) + self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'])) if digit.action != "addLine": # PyDisplayDriver: self.parent.digit.driver.SetSelected([]) @@ -1236,36 +1250,58 @@ return exit - def Pixel2Cell(self, x, y): + def Pixel2Cell(self, (x, y)): """ - Calculates real word coordinates to image coordinates + Convert image coordinates to real word coordinates Input : int x, int y Output: float x, float y """ - east = self.Map.region['w'] + x * self.Map.region["ewres"] - north = self.Map.region['n'] - y * self.Map.region["nsres"] + if self.Map.region["ewres"] > self.Map.region["nsres"]: + res = self.Map.region["ewres"] + else: + res = self.Map.region["nsres"] + + w = self.Map.region["center_easting"] - (self.Map.width / 2) * res + n = self.Map.region["center_northing"] + (self.Map.height / 2) * res + + east = w + x * res + north = n - y * res + + # extent does not correspond with whole map canvas area... + # east = self.Map.region['w'] + x * self.Map.region["ewres"] + # north = self.Map.region['n'] - y * self.Map.region["nsres"] + return (east, north) - def Cell2Pixel(self, east, north): + def Cell2Pixel(self, (east, north)): """ - Calculates image coordinates to real word coordinates + Convert real word coordinates to image coordinates Input : float east, float north Output: int x, int y """ - x = int((east - self.Map.region['w']) / self.Map.region["ewres"]) - y = int((self.Map.region['n'] - north) / self.Map.region["nsres"]) + if self.Map.region["ewres"] > self.Map.region["nsres"]: + res = self.Map.region["ewres"] + else: + res = self.Map.region["nsres"] + 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) + return (x, y) def Zoom(self, begin, end, zoomtype): """ Calculates new region while (un)zoom/pan-ing """ - x1, y1, x2, y2 = begin[0], begin[1], end[0], end[1] + x1, y1 = begin + x2, y2 = end newreg = {} # threshold - too small squares do not make sense @@ -1276,21 +1312,24 @@ x1, x2 = x2, x1 if y1 > y2: y1, y2 = y2, y1 + # zoom in if zoomtype > 0: - newreg['w'], newreg['n'] = self.Pixel2Cell(x1, y1) - newreg['e'], newreg['s'] = self.Pixel2Cell(x2, y2) + newreg['w'], newreg['n'] = self.Pixel2Cell((x1, y1)) + newreg['e'], newreg['s'] = self.Pixel2Cell((x2, y2)) # zoom out elif zoomtype < 0: - newreg['w'], newreg['n'] = self.Pixel2Cell(-x1 * 2, -y1 * 2) - newreg['e'], newreg['s'] = self.Pixel2Cell(self.Map.width + 2 * (self.Map.width - x2), - self.Map.height + 2 * (self.Map.height - y2)) + newreg['w'], newreg['n'] = self.Pixel2Cell((-x1 * 2, -y1 * 2)) + newreg['e'], newreg['s'] = self.Pixel2Cell((self.Map.width + 2 * (self.Map.width - x2), + self.Map.height + 2 * (self.Map.height - y2))) # pan elif zoomtype == 0: - newreg['w'], newreg['n'] = self.Pixel2Cell(x1 - x2, y1 - y2) - newreg['e'], newreg['s'] = self.Pixel2Cell(self.Map.width + x1 - x2, - self.Map.height + y1 - y2) + dx = x1 - x2 + dy = y1 - y2 + newreg['w'], newreg['n'] = self.Pixel2Cell((dx, dy)) + newreg['e'], newreg['s'] = self.Pixel2Cell((self.Map.width + dx, + self.Map.height + dy)) # if new region has been calculated, set the values if newreg : @@ -1298,6 +1337,8 @@ 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.ZoomHistory(newreg['n'], newreg['s'], newreg['e'], newreg['w']) @@ -1318,14 +1359,27 @@ self.Map.region['w'] = zoom[3] self.UpdateMap() - def ZoomHistory(self, n,s,e,w): + def ZoomHistory(self, n, s, e, w): """ Manages a list of last 10 zoom extents + + Return removed history item if exists """ + removed = None self.zoomhistory.append((n,s,e,w)) + if len(self.zoomhistory) > 10: - self.zoomhistory.pop(0) + removed = self.zoomhistory.pop(0) + if removed: + Debug.msg(4, "BufferedWindow.ZoomHistory(): hist=%s, removed=%s" % + (self.zoomhistory, removed)) + else: + Debug.msg(4, "BufferedWindow.ZoomHistory(): hist=%s" % + (self.zoomhistory)) + + return removed + def ZoomToMap(self, event): """ Set display extents to match selected raster @@ -1511,7 +1565,7 @@ drawing window. """ - def __init__(self, parent=None, id = wx.ID_ANY, title="GRASS GIS Map display", + def __init__(self, parent=None, id=wx.ID_ANY, title="GRASS GIS - Map display", pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_FRAME_STYLE, toolbars=["map"], tree=None, notebook=None, gismgr=None, page=None, @@ -1522,13 +1576,13 @@ Parameters: parent -- parent window, None, wx.Window() - id -- window ID, int, wx.NewId() + id -- window ID, int, wx.ID_ANY title -- window title, string pos -- where to place it, tupple, wx.Position size -- window size, tupple, wx.Size style -- window style - toolbars-- array of default toolbars, which should appear - map, digit + toolbars-- array of default toolbars, which should appear, + currently: ['map', 'digit'] notebook-- control book ID in GIS Manager tree -- associated layer tree gismgr -- GIS Manager panel @@ -1540,13 +1594,15 @@ wx.Frame.__init__(self, parent, id, title, pos, size, style) - # most of the thime, this will be the gis manager - self.gismanager = gismgr # GIS Manager object - self.Map = Map # instance of render.Map - self.tree = tree # GIS Manager layer tree object - self.page = page # Notebook page holding the layer tree - self.layerbook = notebook #GIS Manager layer tree notebook + self.gismanager = gismgr # GIS Manager object + self.Map = Map # instance of render.Map + self.tree = tree # GIS Manager layer tree object + self.page = page # Notebook page holding the layer tree + self.layerbook = notebook # GIS Manager layer tree notebook + + # # available cursors + # self.cursors = { # default: cross # "default" : wx.StockCursor(wx.CURSOR_DEFAULT), @@ -1558,17 +1614,17 @@ } # - # Set the size & cursor + # set the size & system icon # self.SetClientSize(size) self.iconsize = (16, 16) + self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.map.gif'), wx.BITMAP_TYPE_ANY)) # # Fancy gui # # self._mgr = auimgr self._mgr = wx.aui.AuiManager(self) - self.SetIcon(wx.Icon(os.path.join(imagepath,'grass.map.gif'), wx.BITMAP_TYPE_ANY)) # # Add toolbars @@ -1582,39 +1638,60 @@ # # Add statusbar # - self.statusbar = self.CreateStatusBar(number=2, style=0) - self.statusbar.SetStatusWidths([-5, -2]) - self.Map.SetRegion() - map_frame_statusbar_fields = ["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"]), - "%s,%s" %(None, None)] - for i in range(len(map_frame_statusbar_fields)): - self.statusbar.SetStatusText(map_frame_statusbar_fields[i], i) + self.statusbar = self.CreateStatusBar(number=3, style=0) + self.statusbar.SetStatusWidths([-2, -5, -1]) + self.toggleStatus = wx.Choice(self.statusbar, wx.ID_ANY, + choices = ["Coordinates", + "Extent", + "Geometry"]) + 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.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleRender, self.autoRender) + self.autoRender.SetValue(False) + # show region + self.showRegion = wx.CheckBox(self.statusbar, wx.ID_ANY, _("Show")) + self.statusbar.Bind(wx.EVT_CHECKBOX, self.OnToggleShowRegion, self.showRegion) + self.showRegion.SetValue(False) + self.showRegion.Hide() + 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", 1) + self.StatusbarReposition() # reposition checkbox + # # Init map display # - self.InitDisplay() # initialize region values + self.__InitDisplay() # initialize region values - self.totaldist = 0.0 # total length measured - # initialize buffered DC - ## self.MapWindow = DrawWindow(self) - self.MapWindow = BufferedWindow(self, id = wx.ID_ANY, Map=self.Map, tree=self.tree) + # initialize buffered DC & set default cursor + self.MapWindow = BufferedWindow(self, id=wx.ID_ANY, Map=self.Map, tree=self.tree) self.MapWindow.Bind(wx.EVT_MOTION, self.OnMotion) - self.MapWindow.SetCursor(self.cursors["default"]) # default + self.MapWindow.SetCursor(self.cursors["default"]) # - # Init zoomhistory + # Init zoom history # self.MapWindow.ZoomHistory(self.Map.region['n'], self.Map.region['s'], self.Map.region['e'], self.Map.region['w']) - # decoration overlays + # + # Decoration overlays + # self.ovlchk = self.MapWindow.ovlchk self.ovlcoords = self.MapWindow.ovlcoords # previously set decoration options parameters to insert into options dialog @@ -1723,15 +1800,17 @@ self.maptoolbar.combo.SetValue (""); self._mgr.Update() - def InitDisplay(self): + def __InitDisplay(self): """ Initialize map display, set dimensions and map region """ self.width, self.height = self.GetClientSize() - self.Map.geom = self.width, self.height - self.Map.GetRegion() - self.Map.SetRegion() + Debug.msg(2, "MapFrame.__InitDisplay():") + self.Map.ChangeMapSize(self.GetClientSize()) + self.Map.GetRegion() # g.region -upg + self.Map.SetRegion() # adjust region to match display window + def OnFocus(self, event): """ Change choicebook @@ -1750,13 +1829,11 @@ Mouse moved Track mouse motion and update status bar """ - # store current mouse position - posx, posy = event.GetPositionTuple() + # update statusbar if required + e, n = self.MapWindow.Pixel2Cell(event.GetPositionTuple()) + if self.statusText == "Coordinates": + self.statusbar.SetStatusText("%.2f,%.2f" % (e, n), 1) - # upsdate coordinates - x, y = self.MapWindow.Pixel2Cell(posx, posy) - self.statusbar.SetStatusText("%.2f,%.2f" % (x, y), 1) - event.Skip() def ReDraw(self, event): @@ -1764,14 +1841,14 @@ Redraw button clicked """ Debug.msg(3, "BufferedWindow.ReDraw():") - self.MapWindow.UpdateMap() + self.MapWindow.UpdateMap(render=False) def ReRender(self, event): """ Rerender button clicked """ Debug.msg(3, "BufferedWindow.ReRender():") - self.MapWindow.UpdateMap() + self.MapWindow.UpdateMap(render=True) def Pointer(self, event): """Pointer button clicled""" @@ -1855,9 +1932,61 @@ self.Map.alignRegion = False # event.Skip() + def OnToggleRender(self, event): + """Enable/disable auto-rendering""" + if self.autoRender.GetValue(): + self.ReRender(None) + + def OnToggleShowRegion(self, event): + """Show/Hide extent in map canvas""" + if self.showRegion.GetValue(): + # show extent + self.regionCoords = [] + else: + del self.regionCoords + + def OnToggleStatus(self, event): + """Toggle status text""" + self.statusText = event.GetString() + + if self.statusText == "Coordinates": + self.statusbar.SetStatusText("None,None", 1) + 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.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.showRegion.Hide() + else: + self.statusbar.SetStatusText("", 1) + + def StatusbarReposition(self): + """Reposition checkbox in statusbar""" + # reposition checkbox + widgets = {0: self.toggleStatus, + 1: self.showRegion, + 2: self.autoRender} + for idx, win in widgets.iteritems(): + rect = self.statusbar.GetFieldRect(idx) + if idx == 1: # show region + wWin, hWin = win.GetBestSize() + x, y = rect.x + rect.width - wWin, rect.y-1 + w, h = wWin, rect.height+2 + else: # choice || auto-rendering + x, y = rect.x, rect.y-1 + w, h = rect.width, rect.height+2 + + win.SetPosition((x, y)) + win.SetSize((w, h)) + def SaveToFile(self, event): """ - Save to file + Save image to file """ filetype = "PNG file (*.png)|*.png|"\ "TIF file (*.tif)|*.tif|"\ @@ -1954,7 +2083,7 @@ """ #set query snap distance for v.what at mapunit equivalent of 10 pixels qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width) - east,north = self.MapWindow.Pixel2Cell(x, y) + east,north = self.MapWindow.Pixel2Cell((x, y)) if self.tree.GetSelections(): mapname = None @@ -2043,6 +2172,8 @@ map display """ + self.totaldist = 0.0 # total measured distance + # switch GIS Manager to output console to show measure results self.gismanager.notebook.SetSelection(1) Modified: trunk/grassaddons/gui/gui_modules/profile.py =================================================================== --- trunk/grassaddons/gui/gui_modules/profile.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/profile.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -252,7 +252,7 @@ if len(self.mapwin.polycoords) > 0: for point in self.mapwin.polycoords: # convert screen coordinates to map coordinates for transect - east, north = self.mapwin.Pixel2Cell(point[0],point[1]) + east, north = self.mapwin.Pixel2Cell(point) # build string of coordinate points for r.profile if self.coordstr == '': @@ -343,7 +343,7 @@ if len(self.mapwin.polycoords) > 0 and self.rast1 != '': for point in self.mapwin.polycoords: # convert screen coordinates to map coordinates for transect - east, north = self.mapwin.Pixel2Cell(point[0],point[1]) + east, north = self.mapwin.Pixel2Cell(point) # get value of raster cell at coordinate point try: Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -170,58 +170,42 @@ class Map(object): """ - This class serves for rendering of output images. - - Attributes: - env - for some environment variables - verbosity - verbosity level - width - width of the map in pixels - height - height of the map in pixels - windfile - content of WIND file for temporary region - settings - n-s resol: 30; - e-w resol: 30; - ... - region - g.region -gp output - 'n':1000, - 's':0, - 'e':1000, - 'w':0, - ... - layers - list of all available layers - renderRegion - dictionary: - 'color' : 'RRR:GGG:BBB', - 'width' : 3, - 'render': True/False - mapfile - rendered final image filename + The class serves for rendering of output images. """ def __init__(self): - """ - During initalization, necessary variables are set, monitor size is - determined and - """ + """Map constructor""" - self.wind = {} # WIND settings - self.region = {} # region settings + # + # region/extent settigns + # + self.wind = {} # WIND settings (wind file) + self.region = {} # region settings (g.region) self.width = 640.0 # map width self.height = 480.0 # map height - self.layers = [] # stack of available layer + # + # list of layers + # + self.layers = [] # stack of available GRASS layer + self.overlays = [] # stack of available overlays self.ovlookup = {} # lookup dictionary for overlay items and overlays + + # + # environment settings + # self.env = {} # enviroment variables, like MAPSET, LOCATION_NAME, etc. - self.verbosity = 0 + + self.verbosity = 0 # --q + + # + # generated file for rendering the map + # self.mapfile = utils.GetTempfile() -# self.renderRegion = { -# "render" : True, # should the region be displayed? -# "color" :"255:0:0", -# "width" : 3 -# } - # setting some initial env. variables - self.__initEnv() + self.__initGisEnv() # g.gisenv self.__initRegion() os.environ["GRASS_TRANSPARENT"] = "TRUE" os.environ["GRASS_BACKGROUNDCOLOR"] = "ffffff" @@ -235,11 +219,12 @@ def __initRegion(self): """ - Reads current region settings from g.region command + Reads current region settings from g.region command and wind file. + At the end region is set up. """ # - # setting region + # setting region ('g.region -upg') # self.region = self.GetRegion() @@ -247,17 +232,15 @@ # setting WIND # # FIXME: duplicated region WIND == g.region (at least some values) - # FIXME: cannot open WIND file -> raise exception windfile = os.path.join (self.env['GISDBASE'], - self.env['LOCATION_NAME'], - self.env['MAPSET'], - "WIND") - + self.env['LOCATION_NAME'], + self.env['MAPSET'], + "WIND") try: windfile = open (windfile, "r") - except StandardError, e : - sys.stderr.write("Could open file <%s>: %s\n" % \ - (windfile,e)) + except StandardError, e: + sys.stderr.write(_("Could open file <%s>: %s\n") % \ + (windfile,e)) sys.exit(1) for line in windfile.readlines(): @@ -278,39 +261,39 @@ # self.region['ewres'] = self.region['nsres'] = abs(float(self.region['e']) # - float(self.region['w']))/self.width -# I don't think that this method is used anymore (Michael 8/6/2007 -# def __initMonSize(self): -# """ -# Reads current GRASS monitor dimensions from env or -# use the default values [640x480] -# """ -# print 'in initmonsize' -# -# try: -# self.width = int (os.getenv("GRASS_WIDTH")) -# except: -# self.width = 640 -# -# try: -# self.height = int(os.getenv("GRASS_HEIGHT")) -# -# except: -# self.height = 480 - - - def __initEnv(self): + # I don't think that this method is used anymore (Michael 8/6/2007 + # def __initMonSize(self): + # """ + # Reads current GRASS monitor dimensions from env or + # use the default values [640x480] + # """ + # print 'in initmonsize' + # + # try: + # self.width = int (os.getenv("GRASS_WIDTH")) + # except: + # self.width = 640 + # + # try: + # self.height = int(os.getenv("GRASS_HEIGHT")) + # + # except: + # self.height = 480 + + + def __initGisEnv(self): """ - Stores environment variables to self.env variable + Stores GRASS variables (g.gisenv) to self.env variable """ if not os.getenv("GISBASE"): - sys.stderr.write("GISBASE not set, you must be " - "in GRASS GIS to run this program\n") + sys.stderr.write(_("GISBASE not set, you must be " + "in GRASS GIS to run this program\n")) sys.exit(1) - #os.system("d.mon --quiet stop=gism") + gisenvCmd = cmd.Command(["g.gisenv"]) - for line in os.popen("g.gisenv").readlines(): + for line in gisenvCmd.ReadStdOutput(): line = line.strip() key, val = line.split("=") val = val.replace(";","") @@ -325,15 +308,14 @@ resolution. Set computational resolution through g.region. """ - self.width = float(self.width) - self.height = float(self.height) - mapwidth = abs(self.region["e"] - self.region["w"]) - mapheight = abs(self.region['n'] - self.region['s']) + mapwidth = abs(self.region["e"] - self.region["w"]) + mapheight = abs(self.region['n'] - self.region['s']) - self.region["nsres"] = mapheight / self.height - self.region["ewres"] = mapwidth / self.width - self.region['rows'] = round(mapheight/self.region["nsres"]) - self.region['cols'] = round(mapwidth/self.region["ewres"]) + self.region["nsres"] = mapheight / self.height + self.region["ewres"] = mapwidth / self.width + self.region['rows'] = round(mapheight / self.region["nsres"]) + self.region['cols'] = round(mapwidth / self.region["ewres"]) + self.region['cells'] = self.region['rows'] * self.region['cols'] Debug.msg (3, "Map.__adjustRegion(): %s" % self.region) @@ -376,6 +358,22 @@ new['e'] = new['w'] + (new['cols'] * ewres) return new + def ChangeMapSize(self, (width, height)): + """Change size of rendered map. + + Return: + True on success + False on failure + """ + try: + self.width = float(width) + self.height = float(height) + Debug.msg(2, "Map.ChangeMapSize(): width=%.1f, height=%.1f" % \ + (self.width, self.height)) + return True + except: + return False + def GetRegion(self): """ Returns dictionary with output from g.region -gp @@ -389,14 +387,18 @@ tmpreg = os.getenv("GRASS_REGION") os.unsetenv("GRASS_REGION") - for reg in os.popen("g.region -ugp").readlines(): + # do not update & shell style output + cmdRegion = cmd.Command(["g.region", "-u", "-g", "-p", "-c"]) + + for reg in cmdRegion.ReadStdOutput(): reg = reg.strip() - key, val = reg.split("=",1) + key, val = reg.split("=", 1) try: region[key] = float(val) except ValueError: region[key] = val + # restore region if tmpreg: os.environ["GRASS_REGION"] = tmpreg @@ -410,21 +412,23 @@ from desired zoom level. Returns: - string usable for GRASS_REGION variable or None + String usable for GRASS_REGION variable or None If windres set to True, uses resolution from WIND file rather than display (for modules that require set resolution like d.rast.num) """ grass_region = "" + # adjust region settigns to match monitor self.region = self.__adjustRegion() -# newextents = self.alignResolution() -# self.region['n'] = newextents['n'] -# self.region['s'] = newextents['s'] -# self.region['e'] = newextents['e'] -# self.region['w'] = newextents['w'] + # newextents = self.alignResolution() + # self.region['n'] = newextents['n'] + # self.region['s'] = newextents['s'] + # self.region['e'] = newextents['e'] + # self.region['w'] = newextents['w'] + # read values from wind file try: for key in self.wind.keys(): if key == 'north': @@ -462,7 +466,7 @@ else: grass_region += key + ": " + self.wind[key] + "; " - Debug.msg (4, "Map.SetRegion(): %s" % grass_region) + Debug.msg (3, "Map.SetRegion(): %s" % grass_region) return grass_region @@ -475,13 +479,11 @@ """ projinfo = {} - cmdlist = ['g.proj', '-p'] - p = cmd.Command(cmdlist) + p = cmd.Command(['g.proj', '-p']) if p.returncode == 0: - output = p.module_stdout.read().split('\n') - for line in output: + for line in p.ReadStdOutput(): if ':' in line: key,val = line.split(':') key = key.strip() @@ -565,7 +567,6 @@ os.environ["GRASS_WIDTH"] = str(self.width) os.environ["GRASS_HEIGHT"] = str(self.height) - try: # render map layers for layer in self.layers + self.overlays: Modified: trunk/grassaddons/gui/gui_modules/utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/utils.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/utils.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -13,23 +13,31 @@ License (>=v2). Read the file COPYING that comes with GRASS for details. """ + import os -def GetTempfile( pref=None): +import cmd + +def GetTempfile(pref=None): """ Creates GRASS temporary file using defined prefix. + Parameters: + pref: prefer the given path Returns: Path to file name (string) or None """ - tempfile = os.popen("g.tempfile pid=%d" % - os.getpid()).readlines()[0].strip() + tempfileCmd = cmd.Command(["g.tempfile", + "pid=%d" % + os.getpid()]) - if not tempfile: - return None - else: - path,file = os.path.split(tempfile) + tempfile = tempfileCmd.ReadStdOutput()[0].strip() + + try: + path, file = os.path.split(tempfile) if pref: - file = "%s%s" % (pref,file) - return os.path.join(path,file) + file = "%s%s" % (pref, file) + return os.path.join(path, file) + except: + return Node Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-09-03 06:35:43 UTC (rev 1065) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-09-03 13:08:18 UTC (rev 1066) @@ -574,6 +574,10 @@ self.layers.pop(item) + # redraw map if auto-rendering is enabled + if self.mapdisplay.autoRender.GetValue(): + self.mapdisplay.ReRender(None) + def OnLayerChecked(self, event): """Enable/disable given layer item""" item = event.GetItem() @@ -596,6 +600,10 @@ else: self.Map.ChangeLayerActive(self.layers[item].maplayer, checked) + # redraw map if auto-rendering is enabled + if self.mapdisplay.autoRender.GetValue(): + self.mapdisplay.ReRender(None) + def OnCmdChanged(self, event): """Change command string""" ctrl = event.GetEventObject() @@ -634,6 +642,10 @@ if maplayer and self.drag == False: self.Map.ChangeOpacity(maplayer, opacity) + # redraw map if auto-rendering is enabled + if self.mapdisplay.autoRender.GetValue(): + self.mapdisplay.ReRender(None) + def OnChangeSel(self, event): oldlayer = event.GetOldItem() layer = event.GetItem() @@ -892,6 +904,10 @@ if self.mapdisplay.digittoolbar: self.mapdisplay.digittoolbar.UpdateListOfLayers(updateTool=True) + # redraw map if auto-rendering is enabled + if self.mapdisplay.autoRender.GetValue(): + self.mapdisplay.ReRender(None) + def setNotebookPage(self,pg): self.Parent.notebook.SetSelection(pg) From landa at grass.itc.it Mon Sep 3 15:48:02 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Sep 3 15:48:04 2007 Subject: [grass-addons] r1067 - trunk/grassaddons/gui/gui_modules Message-ID: <200709031348.l83Dm2RF029754@grass.itc.it> Author: landa Date: 2007-09-03 15:48:01 +0200 (Mon, 03 Sep 2007) New Revision: 1067 Added: trunk/grassaddons/gui/gui_modules/gcmd.py Removed: trunk/grassaddons/gui/gui_modules/cmd.py Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/georect.py trunk/grassaddons/gui/gui_modules/mapdisp.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/toolbars.py trunk/grassaddons/gui/gui_modules/utils.py trunk/grassaddons/gui/gui_modules/wxgui_utils.py Log: cmd module renamed to gcmd Deleted: trunk/grassaddons/gui/gui_modules/cmd.py =================================================================== --- trunk/grassaddons/gui/gui_modules/cmd.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/cmd.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -1,226 +0,0 @@ -""" -PACKAGE: cmd - -CLASSES: - * EndOfCommand - * Command - -PURPOSE: Command interface - -AUTHORS: The GRASS Development Team - Original author: Jachym Cepicky - Martin Landa - -COPYRIGHT: (C) 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. -""" - -# use Popen class or os.popen3 method -usePopenClass = True - -import os, sys -import wx - -try: - import subprocess -except: - CompatPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "compat") - sys.path.append(CompatPath) - import subprocess - - GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules") - sys.path.append(GuiModulePath) - -import grassenv -from debug import Debug as Debug - -class EndOfCommand(Exception): - """ - End of command indicator - """ - def __str__(self): - return "End of command" - -class Command: - """ - Run command on the background - - Parameters: - cmd - command string (given as list) - stdin - standard input stream - verbose - verbose mode (GRASS commands '--v') - wait - wait for childer execution - dlgMsg - type of error message (None, gui, txt) [only if wait=True] - - Usage: - cmd = Command(cmd=['d.rast', 'elevation.dem'], verbose=True, wait=True) - - if cmd.returncode == None: - print 'RUNNING' - elif cmd.returncode == 0: - print 'SUCCESS' - else: - print 'FAILURE (%d)' % cmd.returncode - - for msg in cmd.module_msg: - if msg[0] == 'GRASS_INFO_PERCENT': - print 'Percent done: %d' % (int(msg[1])) - else: - print 'General message:', msg[1] - """ - def __init__ (self, cmd, stdin=None, verbose=False, wait=True, dlgMsg='gui'): - # input - self.module_stdin = None - self.cmd = cmd - - self.module = None - - # output - self.module_stderr = None - self.module_msg = [] # list of messages (msgtype, content) - - os.environ["GRASS_MESSAGE_FORMAT"] = "gui" - # run command - if not usePopenClass: - Debug.msg(3, "Command.__init__(): [popen3] cmd=%s" % ' '.join(cmd)) - (self.module_stdin, self.module_stdout, self.module_stderr) = \ - os.popen3(' '.join(self.cmd)) - else: - Debug.msg(3, "Command.__init__(): [Popen] cmd=%s" % ' '.join(cmd)) - self.module = subprocess.Popen(self.cmd, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - close_fds=True) - self.module_stdin = self.module.stdin - self.module_stderr = self.module.stderr - self.module_stdout = self.module.stdout - - if stdin: - self.module_stdin.write(stdin) - self.module_stdin.close() - - os.environ["GRASS_MESSAGE_FORMAT"] = "text" - - try: - self.Run(verbose) - except EndOfCommand: - pass - - if self.module: - if wait: - self.module.wait() - self.returncode = self.module.returncode - - # failed? - if dlgMsg and self.returncode != 0: - # print error messages - for msg in self.module_msg: - print >> sys.stderr, msg[1] - - if dlgMsg == "gui": - dlg = wx.MessageDialog(None, ("Execution failed: '%s'") % (' '.join(self.cmd)), - ("Error"), wx.OK | wx.ICON_ERROR) - dlg.ShowModal() - dlg.Destroy() - else: # otherwise 'txt' - print >> sys.stderr, "Execution failed: '%s'" % (' '.join(self.cmd)) - else: - self.returncode = None - - if self.returncode is not None: - Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=%d" % \ - (' '.join(self.cmd), wait, self.returncode)) - else: - Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=?" % \ - (' '.join(self.cmd), wait)) - - def Run(self, verbose=False): - """ - Process messages read from stderr - """ - msgtype = None - content = None - line = None - - while 1: - line = self.module_stderr.readline() - if not line or line.find("GRASS_INFO_END") > -1: - raise EndOfCommand - if line.find(':') > -1: - msgtype, content = line.split(":", 1) - if verbose: - self.module_msg.append((msgtype, content.strip())) - else: # write only fatal errors and warnigs - if msgtype.find("GRASS_INFO_ERROR") > -1 or \ - msgtype.find("GRASS_INFO_WARNING") > -1: - self.module_msg.append((msgtype, content.strip())) - - return - - def ReadStdOutput(self): - """Read standard output and return list of lines - - Note: Remove '\n' from the lines (TODO: '\r\n' ??) - """ - lineList = [] - while True: - line = self.module_stdout.readline() - if not line: - break - line = line.replace('\n', '') - lineList.append(line) - - return lineList - -# testing ... -if __name__ == "__main__": - #print __doc__ - - # d.rast verbosely, wait for process termination - print "Running d.rast..." - - cmd = Command(cmd=["d.rast", "elevation.dem"], verbose=True, wait=True, dlgMsg='txt') - - if cmd.returncode == None: - print "RUNNING" - elif cmd.returncode == 0: - print "SUCCESS" - else: - print "FAILURE (%d)" % cmd.returncode - - for msg in cmd.module_msg: - if msg[0] == "GRASS_INFO_PERCENT": - print "Percent done: %d" % (int(msg[1])) - else: - print "General message:", msg[1] - - # 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"], - stdin="0 593527.6875 4925297.0625 602083.875 4917545.8125", - verbose=False, - wait=True, dlgMsg='txt') - - if cmd.returncode == None: - print "RUNNING" - elif cmd.returncode == 0: - print "SUCCESS" - else: - print "FAILURE (%d)" % cmd.returncode - - # d.vect silently, do not wait for process termination - # returncode will be None - print "Running d.vect tmp..." - - cmd = Command(["d.vect", "tmp"], verbose=False, wait=False, dlgMsg='txt') - - if cmd.returncode == None: - print "RUNNING" - elif cmd.returncode == 0: - print "SUCCESS" - else: - print "FAILURE (%d)" % cmd.returncode Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -37,7 +37,7 @@ import wx import wx.lib.colourselect as csel -import cmd +import gcmd as cmd import dbm from debug import Debug as Debug Copied: trunk/grassaddons/gui/gui_modules/gcmd.py (from rev 1065, trunk/grassaddons/gui/gui_modules/cmd.py) =================================================================== --- trunk/grassaddons/gui/gui_modules/gcmd.py (rev 0) +++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -0,0 +1,225 @@ +""" +PACKAGE: gcmd + +CLASSES: + * EndOfCommand + * Command + +PURPOSE: GRASS command interface + +AUTHORS: The GRASS Development Team + Original author: Jachym Cepicky + Martin Landa + +COPYRIGHT: (C) 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. +""" + +# use Popen class or os.popen3 method +usePopenClass = True + +import os, sys +import wx + +try: + import subprocess +except: + CompatPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "compat") + sys.path.append(CompatPath) + import subprocess + +GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules") +sys.path.append(GuiModulePath) + +from debug import Debug as Debug + +class EndOfCommand(Exception): + """ + End of command indicator + """ + def __str__(self): + return "End of command" + +class Command: + """ + Run command on the background + + Parameters: + cmd - command string (given as list) + stdin - standard input stream + verbose - verbose mode (GRASS commands '--v') + wait - wait for childer execution + dlgMsg - type of error message (None, gui, txt) [only if wait=True] + + Usage: + cmd = Command(cmd=['d.rast', 'elevation.dem'], verbose=True, wait=True) + + if cmd.returncode == None: + print 'RUNNING' + elif cmd.returncode == 0: + print 'SUCCESS' + else: + print 'FAILURE (%d)' % cmd.returncode + + for msg in cmd.module_msg: + if msg[0] == 'GRASS_INFO_PERCENT': + print 'Percent done: %d' % (int(msg[1])) + else: + print 'General message:', msg[1] + """ + def __init__ (self, cmd, stdin=None, verbose=False, wait=True, dlgMsg='gui'): + # input + self.module_stdin = None + self.cmd = cmd + + self.module = None + + # output + self.module_stderr = None + self.module_msg = [] # list of messages (msgtype, content) + + os.environ["GRASS_MESSAGE_FORMAT"] = "gui" + # run command + if not usePopenClass: + Debug.msg(3, "Command.__init__(): [popen3] cmd=%s" % ' '.join(cmd)) + (self.module_stdin, self.module_stdout, self.module_stderr) = \ + os.popen3(' '.join(self.cmd)) + else: + Debug.msg(3, "Command.__init__(): [Popen] cmd=%s" % ' '.join(cmd)) + self.module = subprocess.Popen(self.cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + close_fds=True) + self.module_stdin = self.module.stdin + self.module_stderr = self.module.stderr + self.module_stdout = self.module.stdout + + if stdin: + self.module_stdin.write(stdin) + self.module_stdin.close() + + os.environ["GRASS_MESSAGE_FORMAT"] = "text" + + try: + self.Run(verbose) + except EndOfCommand: + pass + + if self.module: + if wait: + self.module.wait() + self.returncode = self.module.returncode + + # failed? + if dlgMsg and self.returncode != 0: + # print error messages + for msg in self.module_msg: + print >> sys.stderr, msg[1] + + if dlgMsg == "gui": + dlg = wx.MessageDialog(None, ("Execution failed: '%s'") % (' '.join(self.cmd)), + ("Error"), wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + else: # otherwise 'txt' + print >> sys.stderr, "Execution failed: '%s'" % (' '.join(self.cmd)) + else: + self.returncode = None + + if self.returncode is not None: + Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=%d" % \ + (' '.join(self.cmd), wait, self.returncode)) + else: + Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=?" % \ + (' '.join(self.cmd), wait)) + + def Run(self, verbose=False): + """ + Process messages read from stderr + """ + msgtype = None + content = None + line = None + + while 1: + line = self.module_stderr.readline() + if not line or line.find("GRASS_INFO_END") > -1: + raise EndOfCommand + if line.find(':') > -1: + msgtype, content = line.split(":", 1) + if verbose: + self.module_msg.append((msgtype, content.strip())) + else: # write only fatal errors and warnigs + if msgtype.find("GRASS_INFO_ERROR") > -1 or \ + msgtype.find("GRASS_INFO_WARNING") > -1: + self.module_msg.append((msgtype, content.strip())) + + return + + def ReadStdOutput(self): + """Read standard output and return list of lines + + Note: Remove '\n' from the lines (TODO: '\r\n' ??) + """ + lineList = [] + while True: + line = self.module_stdout.readline() + if not line: + break + line = line.replace('\n', '') + lineList.append(line) + + return lineList + +# testing ... +if __name__ == "__main__": + #print __doc__ + + # d.rast verbosely, wait for process termination + print "Running d.rast..." + + cmd = Command(cmd=["d.rast", "elevation.dem"], verbose=True, wait=True, dlgMsg='txt') + + if cmd.returncode == None: + print "RUNNING" + elif cmd.returncode == 0: + print "SUCCESS" + else: + print "FAILURE (%d)" % cmd.returncode + + for msg in cmd.module_msg: + if msg[0] == "GRASS_INFO_PERCENT": + print "Percent done: %d" % (int(msg[1])) + else: + print "General message:", msg[1] + + # 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"], + stdin="0 593527.6875 4925297.0625 602083.875 4917545.8125", + verbose=False, + wait=True, dlgMsg='txt') + + if cmd.returncode == None: + print "RUNNING" + elif cmd.returncode == 0: + print "SUCCESS" + else: + print "FAILURE (%d)" % cmd.returncode + + # d.vect silently, do not wait for process termination + # returncode will be None + print "Running d.vect tmp..." + + cmd = Command(["d.vect", "tmp"], verbose=False, wait=False, dlgMsg='txt') + + if cmd.returncode == None: + print "RUNNING" + elif cmd.returncode == 0: + print "SUCCESS" + else: + print "FAILURE (%d)" % cmd.returncode Modified: trunk/grassaddons/gui/gui_modules/georect.py =================================================================== --- trunk/grassaddons/gui/gui_modules/georect.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/georect.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -60,7 +60,7 @@ import menuform import select import disp_print -import cmd +import gcmd as cmd from debug import Debug as Debug from icon import Icons as Icons @@ -485,4 +485,4 @@ # Button for adding new GCP -# maybe we can use mapdisp classes to create the display??? \ No newline at end of file +# maybe we can use mapdisp classes to create the display??? Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -58,7 +58,7 @@ import menuform import select import disp_print -import cmd +import gcmd as cmd import dbm import defaultfont as defaultfont import histogram as histogram Modified: trunk/grassaddons/gui/gui_modules/profile.py =================================================================== --- trunk/grassaddons/gui/gui_modules/profile.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/profile.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -50,7 +50,7 @@ import menuform import disp_print import select -import cmd +import gcmd as cmd import gui_modules.defaultfont as defaultfont from debug import Debug as Debug from icon import Icons as Icons Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -19,7 +19,7 @@ import os, sys, glob, math import utils -import cmd +import gcmd as cmd from debug import Debug as Debug class MapLayer(object): Modified: trunk/grassaddons/gui/gui_modules/select.py =================================================================== --- trunk/grassaddons/gui/gui_modules/select.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/select.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -24,7 +24,7 @@ GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules") sys.path.append(GuiModulePath) -import cmd +import gcmd as cmd class SelectDialog(wx.Dialog): def __init__(self, parent, id=wx.ID_ANY, title='Select GIS element', Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -23,7 +23,7 @@ gmpath = os.path.join( os.getenv("GISBASE"),"etc","wx","icons") sys.path.append(gmpath) -import cmd +import gcmd as cmd import grassenv from digit import Digit as Digit from digit import DigitSettingsDialog as DigitSettingsDialog Modified: trunk/grassaddons/gui/gui_modules/utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/utils.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/utils.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -16,7 +16,7 @@ import os -import cmd +import gcmd as cmd def GetTempfile(pref=None): """ Modified: trunk/grassaddons/gui/gui_modules/wxgui_utils.py =================================================================== --- trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-09-03 13:08:18 UTC (rev 1066) +++ trunk/grassaddons/gui/gui_modules/wxgui_utils.py 2007-09-03 13:48:01 UTC (rev 1067) @@ -35,7 +35,7 @@ import menuform import mapdisp import render -import cmd +import gcmd as cmd import grassenv import histogram from debug import Debug as Debug From barton at grass.itc.it Tue Sep 4 03:01:48 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 03:01:50 2007 Subject: [grass-addons] r1068 - trunk/grassaddons/gui Message-ID: <200709040101.l8411muX005372@grass.itc.it> Author: barton Date: 2007-09-04 03:01:39 +0200 (Tue, 04 Sep 2007) New Revision: 1068 Modified: trunk/grassaddons/gui/wxgui.py Log: changed cmd.Command to gcmd.Command Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-09-03 13:48:01 UTC (rev 1067) +++ trunk/grassaddons/gui/wxgui.py 2007-09-04 01:01:39 UTC (rev 1068) @@ -64,7 +64,7 @@ import gui_modules.profile as profile import gui_modules.rules as rules import gui_modules.utils as utils -import gui_modules.cmd as cmd +import gui_modules.gcmd as gcmd import gui_modules.georect as georect from icons.icon import Icons as Icons @@ -292,7 +292,6 @@ """ Launch georectifier module """ - print 'launch georect' georect.GeorectWizard(self) def OnMapsets(self, event): @@ -569,7 +568,10 @@ pointdata=pointdata) def NewDisplay(self, event=None): - """Create new map display frame""" + """ + Create new layer tree, which will + create an associated map display frame + """ # 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) From barton at grass.itc.it Tue Sep 4 03:20:06 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 03:20:08 2007 Subject: [grass-addons] r1069 - trunk/grassaddons/gui/gui_modules Message-ID: <200709040120.l841K6i7005440@grass.itc.it> Author: barton Date: 2007-09-04 03:19:58 +0200 (Tue, 04 Sep 2007) New Revision: 1069 Modified: trunk/grassaddons/gui/gui_modules/toolbars.py Log: Cosmetic improvment to georectify toolbar Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 01:01:39 UTC (rev 1068) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 01:19:58 UTC (rev 1069) @@ -210,7 +210,8 @@ self.mapdisplay.OnZoomBack), (self.zoommenu, "zoommenu", Icons["zoommenu"].GetBitmap(), wx.ITEM_NORMAL, Icons["zoommenu"].GetLabel(), Icons["zoommenu"].GetDesc(), - self.mapdisplay.OnZoomMenu) + self.mapdisplay.OnZoomMenu), + ("", "", "", "", "", "", "") ) def OnSelect(self, event): @@ -234,7 +235,7 @@ # selected map to digitize self.layerSelectedID = None self.layers = [] - + # default action (digitize new point, line, etc.) self.action = "addLine" self.type = "point" @@ -336,7 +337,7 @@ self.action = "addLine" self.type = "line" self.parent.MapWindow.mouse['box'] = 'line' - + def OnAddBoundary(self, event): """Add boundary to the vector map layer""" Debug.msg (2, "DigitToolbar.OnAddBoundary()") @@ -360,7 +361,7 @@ self.StopEditing(self.layers[self.layerSelectedID]) except: pass - + # disable the toolbar self.parent.RemoveToolbar ("digit") @@ -385,7 +386,7 @@ Debug.msg(2, "Digittoolbar.OnSplitLine():") self.action = "splitLine" self.parent.MapWindow.mouse['box'] = 'point' - + def OnEditLine(self, event): pass @@ -393,7 +394,7 @@ Debug.msg(2, "Digittoolbar.OnMoveLine():") self.action = "moveLine" self.parent.MapWindow.mouse['box'] = 'box' - + def OnDeleteLine(self, event): Debug.msg(2, "Digittoolbar.OnDeleteLine():") self.action = "deleteLine" @@ -413,7 +414,7 @@ """Show settings dialog""" DigitSettingsDialog(parent=self.parent, title=_("Digitization settings"), style=wx.DEFAULT_DIALOG_STYLE).Show() - + def OnSelectMap (self, event): """ Select vector map layer for editing @@ -451,7 +452,7 @@ self.parent.digit.SetMapName(mapLayer.name) - # deactive layer + # deactive layer self.mapcontent.ChangeLayerActive(mapLayer, False) # change cursor @@ -459,35 +460,35 @@ # create pseudoDC for drawing the map self.parent.pdcVector = wx.PseudoDC() - + return True def StopEditing (self, layerSelected): """ Stop editing of selected vector map layer. """ - + if self.layers[self.layerSelectedID] == layerSelected: self.layerSelectedID = None Debug.msg (4, "DigitToolbar.StopEditing(): layer=%s" % \ (layerSelected.name)) self.combo.SetValue ('Select vector map') - + # re-active layer self.mapcontent.ChangeLayerActive(layerSelected, True) self.parent.digit.SetMapName(None) - + # change cursor self.parent.MapWindow.SetCursor(self.parent.cursors["default"]) # disable pseudodc for vector map layer self.parent.MapWindow.pdcVector = None - + return True return False - + def UpdateListOfLayers (self, updateTool=False): """ Update list of available vector map layers. @@ -498,7 +499,7 @@ Debug.msg (4, "DigitToolbar.UpdateListOfLayers(): updateTool=%d" % \ updateTool) - + layerNameSelected = None if self.layerSelectedID != None: # name of currently selected layer layerNameSelected = self.layers[self.layerSelectedID].name @@ -524,7 +525,7 @@ choices=layerNameList, size=(150, -1), style=wx.CB_READONLY) self.comboid = self.toolbar[0].InsertControl(0, self.combo) - + # additional bindings self.parent.Bind(wx.EVT_COMBOBOX, self.OnSelectMap, self.comboid) From barton at grass.itc.it Tue Sep 4 03:20:37 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 03:20:38 2007 Subject: [grass-addons] r1070 - trunk/grassaddons/gui/gui_modules Message-ID: <200709040120.l841KbQi005470@grass.itc.it> Author: barton Date: 2007-09-04 03:20:29 +0200 (Tue, 04 Sep 2007) New Revision: 1070 Modified: trunk/grassaddons/gui/gui_modules/georect.py Log: Georectify map will now open in new display. Modified: trunk/grassaddons/gui/gui_modules/georect.py =================================================================== --- trunk/grassaddons/gui/gui_modules/georect.py 2007-09-04 01:19:58 UTC (rev 1069) +++ trunk/grassaddons/gui/gui_modules/georect.py 2007-09-04 01:20:29 UTC (rev 1070) @@ -194,11 +194,27 @@ # start display showing xymap self.Map = render.Map() # instance of render.Map to be associated with display + global maptype + global xy_map + + if maptype == 'cell': + rendertype = 'raster' + cmdlist = ['d.rast', 'map=%s' % xy_map] + elif maptype == 'vector': + rendertype = 'vector' + cmdlist = ['d.vect', 'map=%s' % xy_map] + + self.Map.AddLayer(type=rendertype, command=cmdlist,l_active=True, + l_hidden=False, l_opacity=1, l_render=False) + self.xy_mapdisp = mapdisp.MapFrame(self.parent, title="Set ground control points (GCPs)", - pos=wx.DefaultPosition, size=wx.DefaultSize, + pos=wx.DefaultPosition, size=(640,480), style=wx.DEFAULT_FRAME_STYLE, toolbars=["georect"], Map=self.Map) + # draw selected xy map + self.xy_mapdisp.MapWindow.UpdateMap() + #show new display self.xy_mapdisp.Show() self.xy_mapdisp.Refresh() From barton at grass.itc.it Tue Sep 4 07:09:13 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 07:09:14 2007 Subject: [grass-addons] r1071 - trunk/grassaddons/gui/icons Message-ID: <200709040509.l8459DSB008307@grass.itc.it> Author: barton Date: 2007-09-04 07:09:03 +0200 (Tue, 04 Sep 2007) New Revision: 1071 Modified: trunk/grassaddons/gui/icons/icon.py Log: Add entries for georectification icons. Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-09-04 01:20:29 UTC (rev 1070) +++ trunk/grassaddons/gui/icons/icon.py 2007-09-04 05:09:03 UTC (rev 1071) @@ -93,6 +93,11 @@ "profiledraw": 'gui-profiledraw.gif', "profileopt" : 'gui-profileopt.gif', "analyze" : 'gui-rastanalyze.gif', # TODO: fix? + # georectify + 'cleargcp' : 'gui-gcperase.gif', + 'gcpset' : 'gui-gcpset.gif', + 'georect' : 'gui-georect.gif', + 'rms' : 'gui-rms.gif', } # merge icons dictionaries, join paths From barton at grass.itc.it Tue Sep 4 07:18:00 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 07:18:02 2007 Subject: [grass-addons] r1072 - trunk/grassaddons/gui/icons Message-ID: <200709040518.l845I0tu008344@grass.itc.it> Author: barton Date: 2007-09-04 07:17:51 +0200 (Tue, 04 Sep 2007) New Revision: 1072 Modified: trunk/grassaddons/gui/icons/icon.py Log: Finish entries for georectification icons Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-09-04 05:09:03 UTC (rev 1071) +++ trunk/grassaddons/gui/icons/icon.py 2007-09-04 05:17:51 UTC (rev 1072) @@ -267,7 +267,12 @@ "font" : MetaIcon (img=icons_img["font"], label="Select font"), "color" : MetaIcon (img=icons_img["color"], label="Select color"), "options" : MetaIcon (img=icons_img["options"], label="Set histogram options"), - "analyze" : MetaIcon (img=icons_img["analyze"], label="Analyze")} + "analyze" : MetaIcon (img=icons_img["analyze"], label="Analyze"), + # georectify + 'cleargcp' : MetaIcon (img=icons_img["cleargcp"], label="Delete unselected GCPs"), + 'gcpset' : MetaIcon (img=icons_img["gcpset"], label="Set GCP"), + 'georect' : MetaIcon (img=icons_img["georect"], label="Georectify"), + 'rms' : MetaIcon (img=icons_img["rms"], label="Calculate RMS error")} # testing ... if __name__ == "__main__": From barton at grass.itc.it Tue Sep 4 07:41:23 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 07:41:24 2007 Subject: [grass-addons] r1073 - trunk/grassaddons/gui/gui_modules Message-ID: <200709040541.l845fNEK008415@grass.itc.it> Author: barton Date: 2007-09-04 07:41:14 +0200 (Tue, 04 Sep 2007) New Revision: 1073 Modified: trunk/grassaddons/gui/gui_modules/toolbars.py Log: Change icon for georectify toolbar. Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 05:17:51 UTC (rev 1072) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 05:41:14 UTC (rev 1073) @@ -193,8 +193,8 @@ wx.ITEM_NORMAL, Icons["erase"].GetLabel(), Icons["erase"].GetDesc(), self.mapdisplay.OnErase), ("", "", "", "", "", "", ""), - (self.pointer, "pointer", Icons["pointer"].GetBitmap(), - wx.ITEM_RADIO, Icons["pointer"].GetLabel(), Icons["pointer"].GetDesc(), + (self.gcpset, "gcpset", Icons["gcpset"].GetBitmap(), + wx.ITEM_RADIO, Icons["gcpset"].GetLabel(), Icons["gcpset"].GetDesc(), self.mapdisplay.Pointer), (self.pan, "pan", Icons["pan"].GetBitmap(), wx.ITEM_RADIO, Icons["pan"].GetLabel(), Icons["pan"].GetDesc(), From barton at grass.itc.it Tue Sep 4 07:44:13 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 07:44:14 2007 Subject: [grass-addons] r1074 - trunk/grassaddons/gui/gui_modules Message-ID: <200709040544.l845iD1B008438@grass.itc.it> Author: barton Date: 2007-09-04 07:44:04 +0200 (Tue, 04 Sep 2007) New Revision: 1074 Modified: trunk/grassaddons/gui/gui_modules/toolbars.py Log: Bugfix for georectify toolbar Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 05:41:14 UTC (rev 1073) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 05:44:04 UTC (rev 1074) @@ -178,7 +178,7 @@ """Toolbar data""" self.displaymap = self.rendermap = self.erase = \ - self.pointer = self.query = self.pan = self.zoomin = self.zoomout = \ + self.gcpset = self.query = self.pan = self.zoomin = self.zoomout = \ self.zoomback = self.zoommenu = self.analyze = self.dec = self.savefile = self.printmap =None # tool, label, bitmap, kind, shortHelp, longHelp, handler From barton at grass.itc.it Tue Sep 4 07:45:00 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 4 07:45:03 2007 Subject: [grass-addons] r1075 - trunk/grassaddons/gui/gui_modules Message-ID: <200709040545.l845j0gS008461@grass.itc.it> Author: barton Date: 2007-09-04 07:44:52 +0200 (Tue, 04 Sep 2007) New Revision: 1075 Modified: trunk/grassaddons/gui/gui_modules/georect.py Log: Layout for GCP management panel and grid control Modified: trunk/grassaddons/gui/gui_modules/georect.py =================================================================== --- trunk/grassaddons/gui/gui_modules/georect.py 2007-09-04 05:44:04 UTC (rev 1074) +++ trunk/grassaddons/gui/gui_modules/georect.py 2007-09-04 05:44:52 UTC (rev 1075) @@ -38,7 +38,8 @@ import wx.aui import wx.lib.filebrowsebutton as filebrowse import wx.wizard as wiz -import wx.lib.rcsizer as rcs +import wx.grid as gridlib + from threading import Thread try: @@ -99,6 +100,7 @@ dlg = GeorectStart(self.parent) dlg.CenterOnScreen() + dlg.ShowModal() # If OK button pressed in decoration control dialog @@ -220,8 +222,11 @@ self.xy_mapdisp.Refresh() self.xy_mapdisp.Update() - # start GCP form + self.gcpmgr = GCP(self.parent) + self.gcpmgr.Show() + self.gcpmgr.Refresh() + self.gcpmgr.Update() self.Cleanup() @@ -497,8 +502,178 @@ Calls i.rectify or v.transform to georectify map. """ def __init__(self,parent,id=-1,title="Create & manage ground control points"): - wx.Frame.__init__(self, parent, id , title, size=(50,600)) + wx.Frame.__init__(self, parent, id , title, size=(500,400)) - # Button for adding new GCP + toolbar = self.__createToolBar() -# maybe we can use mapdisp classes to create the display??? + p = wx.Panel(self, -1, style=0) + + self.sizer = wx.BoxSizer(wx.VERTICAL) + + box = wx.BoxSizer(wx.HORIZONTAL) + self.rb_grmethod = wx.RadioBox(p, -1, "Select rectification method for rasters ", + wx.DefaultPosition, wx.DefaultSize, + ['1st order','2nd order', '3rd order'], 3, wx.RA_SPECIFY_COLS) + box.Add(self.rb_grmethod, 0, wx.ALIGN_CENTER|wx.ALL, 5) + self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + + self.grid = GCPGrid(p) + self.sizer.Add(self.grid, 1, wx.GROW|wx.ALL, 5) + + box = wx.BoxSizer(wx.HORIZONTAL) + self.btn_newGCP = wx.Button(p, -1, "Add GCP") + self.btn_newGCP.SetDefault() + box.Add(self.btn_newGCP, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + self.btn_deleteGCP = wx.Button(p, -1, "Delete selected GCP") + box.Add(self.btn_deleteGCP, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) + self.sizer.Add(box) + + p.SetSizer(self.sizer) + + self.Bind(wx.EVT_RADIOBOX, self.OnGRMethod, self.rb_grmethod) + self.Bind(wx.EVT_BUTTON, self.OnButton, self.btn_newGCP) + self.btn_newGCP.Bind(wx.EVT_SET_FOCUS, self.OnButtonFocus) + + def OnButton(self, evt): + print "button selected" + def OnButtonFocus(self, evt): + print "button focus" + + def __createToolBar(self): + """Creates toolbar""" + + toolbar = self.CreateToolBar() + for each in self.toolbarData(): + self.addToolbarButton(toolbar, *each) + toolbar.Realize() + + def addToolbarButton(self, toolbar, label, icon, help, handler): + """Adds button to the given toolbar""" + + if not label: + toolbar.AddSeparator() + return + tool = toolbar.AddLabelTool(id=wx.ID_ANY, label=label, bitmap=icon, shortHelp=help) + self.Bind(wx.EVT_TOOL, handler, tool) + + def toolbarData(self): + + return ( + ('savegcp', Icons["savefile"].GetBitmap(), Icons["savefile"].GetLabel(), self.SaveGCP), + ('cleargcp', Icons["cleargcp"].GetBitmap(), Icons["cleargcp"].GetLabel(), self.ClearGCP), + ('rms', Icons["rms"].GetBitmap(), Icons["rms"].GetLabel(), self.OnRMS), + ('georect', Icons["georect"].GetBitmap(), Icons["georect"].GetLabel(), self.OnGeorect), + ('quit', Icons["quit"].GetBitmap(), Icons["quit"].GetLabel(), self.OnQuit) + ) + + def SaveGCP(self, event): + pass + + def ClearGCP(self, event): + pass + + def OnRMS(self, event): + pass + + def OnGeorect(self, event): + pass + + def OnQuit(self, event): + pass + + def OnGRMethod(self, event): + pass + + +class GCPGrid(gridlib.Grid): + def __init__(self, parent): + gridlib.Grid.__init__(self, parent, -1) + table = GCPDateTable() + # The second parameter means that the grid is to take ownership of the + # table and will destroy it when done. Otherwise you would need to keep + # a reference to it and call it's Destroy method later. + self.SetTable(table, True) + self.SetRowLabelSize(10) + self.SetMargins(0,0) + self.AutoSizeColumns(True) + gridlib.EVT_GRID_CELL_LEFT_DCLICK(self, self.OnLeftDClick) + # I do this because I don't like the default behaviour of not starting the + # cell editor on double clicks, but only a second click. + def OnLeftDClick(self, evt): + if self.CanEnableCellControl(): + self.EnableCellEditControl() + +class GCPDateTable(gridlib.PyGridTableBase): + def __init__(self): + gridlib.PyGridTableBase.__init__(self) + self.colLabels = ['Use', 'X Coord', 'Y Coord', 'East', 'North', + 'Forward Error', 'Backward Error'] + self.dataTypes = [gridlib.GRID_VALUE_BOOL, + gridlib.GRID_VALUE_FLOAT + ':7,2', + gridlib.GRID_VALUE_FLOAT + ':7,2', + gridlib.GRID_VALUE_FLOAT + ':7,2', + gridlib.GRID_VALUE_FLOAT + ':7,2', + gridlib.GRID_VALUE_FLOAT + ':7,2', + gridlib.GRID_VALUE_FLOAT + ':7,2', + ] + self.data = [ + [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00], + [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00], + [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00] + ] + #-------------------------------------------------- + # required methods for the wxPyGridTableBase interface + def GetNumberRows(self): + return len(self.data) + 1 + def GetNumberCols(self): + return len(self.data[0]) + def IsEmptyCell(self, row, col): + try: + return not self.data[row][col] + except IndexError: + return True + # Get/Set values in the table. The Python version of these + # methods can handle any data-type, (as long as the Editor and + # Renderer understands the type too,) not just strings as in the + # C++ version. + def GetValue(self, row, col): + try: + return self.data[row][col] + except IndexError: + return '' + def SetValue(self, row, col, value): + try: + self.data[row][col] = value + except IndexError: + # add a new row + self.data.append([''] * self.GetNumberCols()) + self.SetValue(row, col, value) + # tell the grid we've added a row + msg = gridlib.GridTableMessage(self, # The table + gridlib.GRIDTABLE_NOTIFY_ROWS_APPENDED, # what we did to it + 1 # how many + ) + self.GetView().ProcessTableMessage(msg) + #-------------------------------------------------- + # Some optional methods + # Called when the grid needs to display labels + def GetColLabelValue(self, col): + return self.colLabels[col] + # Called to determine the kind of editor/renderer to use by + # default, doesn't necessarily have to be the same type used + # natively by the editor/renderer if they know how to convert. + def GetTypeName(self, row, col): + return self.dataTypes[col] + # Called to determine how the data can be fetched and stored by the + # editor and renderer. This allows you to enforce some type-safety + # in the grid. + def CanGetValueAs(self, row, col, typeName): + colType = self.dataTypes[col].split(':')[0] + if typeName == colType: + return True + else: + return False + def CanSetValueAs(self, row, col, typeName): + return self.CanGetValueAs(row, col, typeName) + + From landa at grass.itc.it Tue Sep 4 13:39:28 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Tue Sep 4 13:39:30 2007 Subject: [grass-addons] r1076 - trunk/grassaddons/gui/gui_modules Message-ID: <200709041139.l84BdSvZ012652@grass.itc.it> Author: landa Date: 2007-09-04 13:39:28 +0200 (Tue, 04 Sep 2007) New Revision: 1076 Modified: trunk/grassaddons/gui/gui_modules/gcmd.py Log: Store messages/warnings/errors to the list. Modified: trunk/grassaddons/gui/gui_modules/gcmd.py =================================================================== --- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-09-04 05:44:52 UTC (rev 1075) +++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-09-04 11:39:28 UTC (rev 1076) @@ -9,7 +9,7 @@ AUTHORS: The GRASS Development Team Original author: Jachym Cepicky - Martin Landa + Various updates: Martin Landa COPYRIGHT: (C) 2007 by the GRASS Development Team This program is free software under the GNU General Public @@ -21,18 +21,19 @@ usePopenClass = True import os, sys -import wx +import wx # GUI dialogs... -try: - import subprocess -except: - CompatPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "compat") - sys.path.append(CompatPath) - import subprocess +if usePopenClass: + try: + import subprocess + except: + CompatPath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "compat") + sys.path.append(CompatPath) + import subprocess +# debugging ... GuiModulePath = os.path.join(os.getenv("GISBASE"), "etc", "wx", "gui_modules") sys.path.append(GuiModulePath) - from debug import Debug as Debug class EndOfCommand(Exception): @@ -44,12 +45,12 @@ class Command: """ - Run command on the background + Run (GRASS) command on the background Parameters: cmd - command string (given as list) stdin - standard input stream - verbose - verbose mode (GRASS commands '--v') + verbose - verbose mode (GRASS commands '--v') (default: False) wait - wait for childer execution dlgMsg - type of error message (None, gui, txt) [only if wait=True] @@ -63,48 +64,67 @@ else: print 'FAILURE (%d)' % cmd.returncode - for msg in cmd.module_msg: - if msg[0] == 'GRASS_INFO_PERCENT': - print 'Percent done: %d' % (int(msg[1])) - else: - print 'General message:', msg[1] """ - def __init__ (self, cmd, stdin=None, verbose=False, wait=True, dlgMsg='gui'): + def __init__ (self, cmd, stdin=None, + verbose=False, wait=True, dlgMsg='gui'): + # # input + # self.module_stdin = None - self.cmd = cmd + self.cmd = cmd + # + # GRASS module + # self.module = None + # # 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" - # run command - if not usePopenClass: - Debug.msg(3, "Command.__init__(): [popen3] cmd=%s" % ' '.join(cmd)) + + # + # run command ... + # + if not usePopenClass: # do not use Popen class + Debug.msg(4, "Command.__init__(): [popen3] cmd='%s'" % ' '.join(cmd)) + (self.module_stdin, self.module_stdout, self.module_stderr) = \ os.popen3(' '.join(self.cmd)) - else: - Debug.msg(3, "Command.__init__(): [Popen] cmd=%s" % ' '.join(cmd)) + else: # Popen class (default) + Debug.msg(4, "Command.__init__(): [Popen] cmd='%s'" % ' '.join(cmd)) + self.module = subprocess.Popen(self.cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) + # set up streams self.module_stdin = self.module.stdin self.module_stderr = self.module.stderr self.module_stdout = self.module.stdout - if stdin: + if stdin: # read stdin if requested ... self.module_stdin.write(stdin) self.module_stdin.close() - os.environ["GRASS_MESSAGE_FORMAT"] = "text" + os.environ["GRASS_MESSAGE_FORMAT"] = message_format + # + # read stderr + # ... + self.messages = [] + self.errors = [] + self.warnings = [] try: - self.Run(verbose) + self.__ProcessMessages() # -> messages, errors, warnings except EndOfCommand: pass @@ -115,54 +135,53 @@ # failed? if dlgMsg and self.returncode != 0: - # print error messages - for msg in self.module_msg: - print >> sys.stderr, msg[1] - - if dlgMsg == "gui": - dlg = wx.MessageDialog(None, ("Execution failed: '%s'") % (' '.join(self.cmd)), + if dlgMsg == 'gui': # GUI dialog + dlg = wx.MessageDialog(None, + ("Execution failed: '%s'") % (' '.join(self.cmd)), ("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:" + for err in self.errors: + print >> sys.stderr, " %s" % err else: - self.returncode = None + self.returncode = None # running ? if self.returncode is not None: - Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=%d" % \ + Debug.msg (3, "Command(): cmd='%s', wait=%d, returncode=%d" % \ (' '.join(self.cmd), wait, self.returncode)) else: - Debug.msg (3, "Command(): cmd=%s, wait=%d, returncode=?" % \ + Debug.msg (3, "Command(): cmd='%s', wait=%d, returncode=?" % \ (' '.join(self.cmd), wait)) - def Run(self, verbose=False): + def __ProcessMessages(self): """ - Process messages read from stderr + Read messages/warnings/errors from stderr """ msgtype = None content = None line = None - while 1: + while True: line = self.module_stderr.readline() - if not line or line.find("GRASS_INFO_END") > -1: + if not line: raise EndOfCommand if line.find(':') > -1: msgtype, content = line.split(":", 1) - if verbose: - self.module_msg.append((msgtype, content.strip())) - else: # write only fatal errors and warnigs - if msgtype.find("GRASS_INFO_ERROR") > -1 or \ - msgtype.find("GRASS_INFO_WARNING") > -1: - self.module_msg.append((msgtype, content.strip())) + 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) - return - def ReadStdOutput(self): - """Read standard output and return list of lines + """Read standard output and return list - Note: Remove '\n' from the lines (TODO: '\r\n' ??) + Note: Remove '\n' from output (TODO: '\r\n' ??) """ lineList = [] while True: @@ -176,8 +195,10 @@ # testing ... if __name__ == "__main__": - #print __doc__ + SEP = "-----------------------------------------------------------------------------" + print SEP + # d.rast verbosely, wait for process termination print "Running d.rast..." @@ -190,11 +211,7 @@ else: print "FAILURE (%d)" % cmd.returncode - for msg in cmd.module_msg: - if msg[0] == "GRASS_INFO_PERCENT": - print "Percent done: %d" % (int(msg[1])) - else: - print "General message:", msg[1] + print SEP # v.net.path silently, wait for process termination print "Running v.net.path for 0 593527.6875 4925297.0625 602083.875 4917545.8125..." @@ -211,6 +228,8 @@ else: print "FAILURE (%d)" % cmd.returncode + print SEP + # d.vect silently, do not wait for process termination # returncode will be None print "Running d.vect tmp..." From landa at grass.itc.it Tue Sep 4 13:45:47 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Tue Sep 4 13:45:49 2007 Subject: [grass-addons] r1077 - trunk/grassaddons/gui/gui_modules Message-ID: <200709041145.l84BjlE6012695@grass.itc.it> Author: landa Date: 2007-09-04 13:45:47 +0200 (Tue, 04 Sep 2007) New Revision: 1077 Modified: trunk/grassaddons/gui/gui_modules/gcmd.py Log: Fix getenv. Modified: trunk/grassaddons/gui/gui_modules/gcmd.py =================================================================== --- trunk/grassaddons/gui/gui_modules/gcmd.py 2007-09-04 11:39:28 UTC (rev 1076) +++ trunk/grassaddons/gui/gui_modules/gcmd.py 2007-09-04 11:45:47 UTC (rev 1077) @@ -115,8 +115,11 @@ self.module_stdin.write(stdin) self.module_stdin.close() - os.environ["GRASS_MESSAGE_FORMAT"] = message_format - + if message_format: + os.environ["GRASS_MESSAGE_FORMAT"] = message_format + else: + os.unsetenv("GRASS_MESSAGE_FORMAT") + # # read stderr # ... From landa at grass.itc.it Tue Sep 4 15:36:54 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Tue Sep 4 15:36:55 2007 Subject: [grass-addons] r1078 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709041336.l84Das1T014352@grass.itc.it> Author: landa Date: 2007-09-04 15:36:53 +0200 (Tue, 04 Sep 2007) New Revision: 1078 Modified: trunk/grassaddons/gui/display_driver/Makefile trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/render.py Log: Show computation region extent implemented (available from statusbar["Extent"]). Modified: trunk/grassaddons/gui/display_driver/Makefile =================================================================== --- trunk/grassaddons/gui/display_driver/Makefile 2007-09-04 11:45:47 UTC (rev 1077) +++ trunk/grassaddons/gui/display_driver/Makefile 2007-09-04 13:36:53 UTC (rev 1078) @@ -1,4 +1,4 @@ -PYTHONVERSION=2.4 +PYTHONVERSION=2.5 MODULE_TOPDIR = ../../.. Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-04 11:45:47 UTC (rev 1077) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-04 13:36:53 UTC (rev 1078) @@ -485,30 +485,34 @@ Debug.msg (2, "BufferedWindow.UpdateMap(): render=%s" % \ (render)) + # + # render background image if needed + # if render or self.img == None: - # render new map images self.Map.ChangeMapSize(self.GetClientSize()) self.mapfile = self.Map.Render(force=True) self.img = self.GetImage() # id=99 self.resize = False - if not self.img: - self.Draw(self.pdc, pdctype='clear') - return False - + # # clear pseudodc + # self.pdc.Clear() self.pdc.RemoveAll() - try: - id = self.imagedict[self.img] - except: - return False # # draw background map image to PseudoDC # - self.Draw(self.pdc, self.img, drawid=id) + if not self.img: + self.Draw(self.pdc, pdctype='clear') + else: + try: + id = self.imagedict[self.img] + except: + return False + + self.Draw(self.pdc, self.img, drawid=id) # # render vector map layer @@ -523,7 +527,7 @@ self.parent.digit.driver.DrawMap(self.pdcVector) # - # overlay + # render overlay # self.ovldict = self.GetOverlay() # list of decoration overlay images if self.ovldict != {}: # draw scale and legend overlays @@ -543,6 +547,22 @@ self.resize = False # + # render region border + # + if hasattr(self, "regionCoords"): + reg = self.Map.GetWindow() + self.polypen = wx.Pen(colour='red', width=2, style=wx.SOLID) + c2p = self.Cell2Pixel + self.regionCoords = [] + self.regionCoords.append(c2p((reg['west'],reg['north']))) + self.regionCoords.append(c2p((reg['east'],reg['north']))) + self.regionCoords.append(c2p((reg['east'],reg['south']))) + self.regionCoords.append(c2p((reg['west'],reg['south']))) + self.regionCoords.append(c2p((reg['west'],reg['north']))) + # draw region extent + self.DrawLines(polycoords=self.regionCoords) + + # # update statusbar # self.Map.SetRegion() @@ -576,18 +596,22 @@ dc = wx.BufferedDC(wx.ClientDC(self)) dc.SetBackground(wx.Brush("White")) + dc.Clear() + if not self.img: + return False + bitmap = wx.BitmapFromImage(self.img) - self.dragimg = wx.DragImage(bitmap) self.dragimg.BeginDrag((0, 0), self) self.dragimg.GetImageRect(moveto) self.dragimg.Move(moveto) - - dc.Clear() + self.dragimg.DoDrawImage(dc, moveto) self.dragimg.EndDrag() + return True + def DragItem(self, id, event): """ Drag an overlay decoration item @@ -1258,6 +1282,12 @@ Output: float x, float y """ + try: + x = int(x) + y = int(y) + except: + return None + if self.Map.region["ewres"] > self.Map.region["nsres"]: res = self.Map.region["ewres"] else: @@ -1283,6 +1313,12 @@ Output: int x, int y """ + try: + east = float(east) + north = float(north) + except: + return None + if self.Map.region["ewres"] > self.Map.region["nsres"]: res = self.Map.region["ewres"] else: @@ -1650,12 +1686,14 @@ self.autoRender = wx.CheckBox(self.statusbar, wx.ID_ANY, _("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.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)"))) self.Map.SetRegion() # set region # map_frame_statusbar_fields = [ # # field 0 -> region @@ -1941,10 +1979,15 @@ """Show/Hide extent in map canvas""" if self.showRegion.GetValue(): # show extent - self.regionCoords = [] + self.MapWindow.regionCoords = [] else: - del self.regionCoords + del self.MapWindow.regionCoords + # redraw map if auto-rendering is enabled + if self.autoRender.GetValue(): + self.ReRender(None) + + def OnToggleStatus(self, event): """Toggle status text""" self.statusText = event.GetString() Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-09-04 11:45:47 UTC (rev 1077) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-09-04 13:36:53 UTC (rev 1078) @@ -205,8 +205,8 @@ self.mapfile = utils.GetTempfile() # setting some initial env. variables - self.__initGisEnv() # g.gisenv - self.__initRegion() + self.InitGisEnv() # g.gisenv + self.InitRegion() os.environ["GRASS_TRANSPARENT"] = "TRUE" os.environ["GRASS_BACKGROUNDCOLOR"] = "ffffff" os.environ["GRASS_HEIGHT"] = str(self.height) @@ -217,10 +217,14 @@ os.environ["GRASS_COMPRESSION"] = "0" os.environ["GRASS_VERBOSE"] = str(self.verbosity) - def __initRegion(self): + def InitRegion(self): """ - Reads current region settings from g.region command and wind file. - At the end region is set up. + Initialize current region settings. + + Set up 'self.region' using g.region command and + self.wind according to the wind file. + + At the end adjust self.region based on map window size. """ # @@ -229,29 +233,10 @@ self.region = self.GetRegion() # - # setting WIND + # read WIND file # - # FIXME: duplicated region WIND == g.region (at least some values) - windfile = os.path.join (self.env['GISDBASE'], - self.env['LOCATION_NAME'], - self.env['MAPSET'], - "WIND") - try: - windfile = open (windfile, "r") - except StandardError, e: - sys.stderr.write(_("Could open file <%s>: %s\n") % \ - (windfile,e)) - sys.exit(1) + self.GetWindow() - for line in windfile.readlines(): - line = line.strip() - key, value = line.split(":",1) - key = key.strip() - value = value.strip() - self.wind[key] = value - - windfile.close() - # # setting resolution # @@ -281,7 +266,7 @@ # self.height = 480 - def __initGisEnv(self): + def InitGisEnv(self): """ Stores GRASS variables (g.gisenv) to self.env variable """ @@ -300,6 +285,31 @@ val = val.replace("'","") self.env[key] = val + def GetWindow(self): + """Read WIND file and set up self.wind dictionary""" + # FIXME: duplicated region WIND == g.region (at least some values) + windfile = os.path.join (self.env['GISDBASE'], + self.env['LOCATION_NAME'], + self.env['MAPSET'], + "WIND") + try: + windfile = open (windfile, "r") + except StandardError, e: + sys.stderr.write(_("Could open file <%s>: %s\n") % \ + (windfile,e)) + sys.exit(1) + + for line in windfile.readlines(): + line = line.strip() + key, value = line.split(":",1) + key = key.strip() + value = value.strip() + self.wind[key] = value + + windfile.close() + + return self.wind + def __adjustRegion(self): """ Adjusts display resolution to match monitor size in pixels. From landa at grass.itc.it Wed Sep 5 16:47:50 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Sep 5 16:47:53 2007 Subject: [grass-addons] r1079 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709051447.l85Elocr002340@grass.itc.it> Author: landa Date: 2007-09-05 16:47:50 +0200 (Wed, 05 Sep 2007) New Revision: 1079 Modified: trunk/grassaddons/gui/display_driver/driver.cc trunk/grassaddons/gui/display_driver/driver.h trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py trunk/grassaddons/gui/gui_modules/toolbars.py Log: Basic display driver optimalization (digitization tool). Modified: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-05 14:47:50 UTC (rev 1079) @@ -3,9 +3,8 @@ \brief Experimental C++ wxWidgets display driver - This driver is designed for wxPython GRASS GUI. - Displays vector map layers when Digitization tool is - activated. + This driver is designed for wxPython GRASS GUI (digitization tool). + Draw vector map layer to PseudoDC. \author Martin Landa @@ -23,17 +22,19 @@ Allocate given structures. - \param + \param[in,out] PseudoDC device where to draw vector objects \return */ -DisplayDriver::DisplayDriver() +DisplayDriver::DisplayDriver(void *device) { - G_gisinit(""); /* need by other GRASS functions */ + G_gisinit(""); /* GRASS functions */ mapInfo = NULL; dcId = 1; + dc = (wxPseudoDC *) device; + points = Vect_new_line_struct(); pointsScreen = new wxList(); cats = Vect_new_cats_struct(); @@ -60,47 +61,65 @@ } /** - \brief Display content of the map in device + \brief Set device for drawing - \param[in,out] device wxDC object where to draw vector features -\ - \return number of displayed features + \param[in,out] PseudoDC device where to draw vector objects + + \return +*/ +void DisplayDriver::SetDevice(void *device) +{ + dc = (wxPseudoDC *) device; + + return; +} + +/** + \brief Draw content of the vector map to device + + \return number of lines which were drawn \return -1 on error */ -int DisplayDriver::DrawMap(void *device) +int DisplayDriver::DrawMap() { - if (!mapInfo) + if (!mapInfo || !dc) return -1; - dc = (wxPseudoDC *) device; + int nlines; + struct ilist *listLines; + + // initialize dcId = 1; - ids.clear(); + listLines = Vect_new_list(); - int nlines; + /* nlines = Vect_get_num_lines(mapInfo); */ - nlines = Vect_get_num_lines(mapInfo); + // draw lines inside of current display region + nlines = Vect_select_lines_by_box(mapInfo,&(region.box), + GV_POINTS | GV_LINES, // fixme + listLines); - for (int line = 1; line <= nlines; line++) { - DrawLine(line); + for (int i = 0; i < listLines->n_values; i++) { + DrawLine(listLines->value[i]); } #ifdef DEBUG PrintIds(); #endif - dc = NULL; + Vect_destroy_list(listLines); - return nlines; + return listLines->n_values; } /** - \brief Display selected vector feature + \brief Draw selected vector objects to the device - \param[in] id of the vector feature + \param[in] line id \return 1 on success - \return -1 on failure (vector feature is dead, etc.) + \return -1 on failure (vector object is dead, etc.) */ int DisplayDriver::DrawLine(int line) { @@ -125,140 +144,142 @@ // add ids // -> node1, line1, vertex1, line2, ..., node2 struct lineDesc desc = {points->n_points, dcId}; + ids[line] = desc; + // update id for next line dcId += points->n_points * 2 - 1; - ids[line] = desc; - // draw vector feature - if (type & GV_LINES) { - switch (type) { - case GV_LINE: - dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID)); - draw = settings.line.enabled; - break; - case GV_BOUNDARY: - int left, right; - Vect_get_line_areas(mapInfo, line, - &left, &right); - if (left == 0 && right == 0) { - dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryNo.enabled; + // determine color of vector object + if (IsSelected(line)) { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + draw = true; + } + else { + if (type & GV_LINES) { + switch (type) { + case GV_LINE: + dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID)); + draw = settings.line.enabled; + break; + case GV_BOUNDARY: + int left, right; + Vect_get_line_areas(mapInfo, line, + &left, &right); + if (left == 0 && right == 0) { + dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryNo.enabled; + } + else if (left > 0 && right > 0) { + dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryTwo.enabled; + } + else { + dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryOne.enabled; + } + break; + default: + draw = false; + break; } - else if (left > 0 && right > 0) { - dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryTwo.enabled; + } + else if (type & GV_POINTS) { + if (type == GV_POINT && settings.point.enabled) { + dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID)); + draw = true; } - else { - dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryOne.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)); + } + else if (cret == 0) { + draw = settings.centroidOut.enabled; + dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID)); + } + else { + draw = settings.centroidDup.enabled; + dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID)); + } } - break; - default: - draw = false; - break; } + } - // highlight feature? - if (draw && IsSelected(line)) { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + // draw object + if (draw) { + if (type & GV_POINTS) { + DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData()); } - - long int startId = ids[line].startId + 1; - - for (int i = 0; i < pointsScreen->GetCount() - 1; startId += 2) { - wxPoint *point_beg = (wxPoint *) pointsScreen->Item(i)->GetData(); - wxPoint *point_end = (wxPoint *) pointsScreen->Item(++i)->GetData(); + else { + long int startId = ids[line].startId + 1; - wxRect rect (*point_beg, *point_end); - dc->SetIdBounds(startId, rect); - - // draw line if needed - if (draw) { + for (int i = 0; i < pointsScreen->GetCount() - 1; startId += 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->DrawLine(point_beg->x, point_beg->y, point_end->x, point_end->y); } + DrawLineVerteces(line); // draw vertices + DrawLineNodes(line); // draw nodes } - - //DrawLineVerteces(line); // draw vertices - //DrawLineNodes(line); // draw nodes } - else if (type & GV_POINTS) { - if (type == GV_POINT && settings.point.enabled) { - dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID)); - draw = true; - } - 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)); - } - else if (cret == 0) { - draw = settings.centroidOut.enabled; - dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID)); - } - else { - draw = settings.centroidDup.enabled; - dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID)); - } - } - if (draw) { - // highlight feature? - if (IsSelected(line)) { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); - } - - DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData()); - } - } - return 1; } /** - \brief Display verteces of the line + \brief Draw line verteces to the device - Except of first and last vertex, see DisplayNodes(). + Except of first and last vertex, see DrawLineNodes(). - \param + \param line id - \return number of displayed verteces + \return number of verteces which were drawn + \return -1 if drawing vertices is disabled */ int DisplayDriver::DrawLineVerteces(int line) { long int id; wxPoint *point; + if (!settings.vertex.enabled) + return -1; + + // determine color + if (!IsSelected(line)) { + dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID)); + } + else { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + } + // set id id = ids[line].startId + 2; for (int i = 1; i < pointsScreen->GetCount() - 1; i++, id += 2) { point = (wxPoint*) pointsScreen->Item(i)->GetData(); - wxRect rect (*point, *point); - dc->SetIdBounds(id, rect); + //wxRect rect (*point, *point); + //dc->SetIdBounds(id, rect); + dc->SetId(id); + DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData()); } - // draw vertices if needed - if (settings.vertex.enabled) { - if (!IsSelected(line)) - dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID)); - - id = ids[line].startId + 2; - for (int i = 1; i < pointsScreen->GetCount() - 1; i++, id += 2) { - dc->SetId(id); - DrawCross(line, (const wxPoint*) pointsScreen->Item(i)->GetData()); - } - } - return pointsScreen->GetCount() - 2; } /** - \brief Display nodes of the line + \brief Draw line nodes to the device - \param + \param line id \return 1 + \return -1 if no nodes were drawn */ int DisplayDriver::DrawLineNodes(int line) { @@ -269,31 +290,39 @@ int nodes [2]; bool draw; + // draw nodes?? + if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled) + return -1; + + // get nodes Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1])); for (int i = 0; i < sizeof(nodes) / sizeof(int); i++) { node = nodes[i]; + // get coordinates Vect_get_node_coor(mapInfo, node, &east, &north, &depth); + // convert EN->xy Cell2Pixel(east, north, depth, &x, &y, &z); - - if (Vect_get_node_n_lines(mapInfo, node) == 1) { - dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID)); - draw = settings.nodeOne.enabled; + // determine color + if (IsSelected(line)) { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + draw = true; } else { - dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID)); - draw = settings.nodeTwo.enabled; + if (Vect_get_node_n_lines(mapInfo, node) == 1) { + dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID)); + draw = settings.nodeOne.enabled; + } + else { + dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID)); + draw = settings.nodeTwo.enabled; + } } - // highlight feature? - if (draw && IsSelected(line)) { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); - } - // node1, line1, vertex1, line2, vertex2, ..., node2 if (i == 0) // first node id = dcId - points->n_points * 2 + 1; @@ -301,8 +330,8 @@ id = dcId - 1; wxPoint point(x, y); - wxRect rect (point, point); - dc->SetIdBounds(id, rect); + // wxRect rect (point, point); + // dc->SetIdBounds(id, rect); // draw node if needed if (draw) { @@ -346,10 +375,10 @@ if (!mapInfo) mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info)); -// define open level (level 2: topology) + // define open level (level 2: topology) Vect_set_open_level(2); -// open existing map + // open existing map Vect_open_old(mapInfo, (char*) mapname, (char *) mapset); return; @@ -360,6 +389,8 @@ Close and open again. Needed for modification using v.edit. + TODO: Get rid of that... + \param \return @@ -380,7 +411,9 @@ \brief Conversion from geographic coordinates (east, north) to screen (x, y) - \param[in] east,north,elev geographical coordinates + TODO: 3D stuff... + + \param[in] east,north,depth geographical coordinates \param[out] x, y, z screen coordinates \return @@ -388,9 +421,9 @@ void DisplayDriver::Cell2Pixel(double east, double north, double depth, int *x, int *y, int *z) { - *x = int((east - region.west_real) / region.res); - *y = int((region.north_real - north) / region.res); - *z = 0; + *x = int((east - region.map_west) / region.map_res); + *y = int((region.map_north - north) / region.map_res); + *z = 0; return; } @@ -398,7 +431,7 @@ /** \brief Set geographical region - Needed for Cell2Pixel(). + Region must be upgraded because of Cell2Pixel(). \param[in] north,south,east,west,ns_res,ew_res region settings @@ -409,10 +442,10 @@ double center_easting, double center_northing, double map_width, double map_height) { - region.north = north; - region.south = south; - region.east = east; - region.west = west; + region.box.N = north; + region.box.S = south; + region.box.E = east; + region.box.W = west; region.ns_res = ns_res; region.ew_res = ew_res; @@ -423,18 +456,18 @@ region.map_height = map_height; // calculate real region - region.res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res; + region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res; - region.west_real = region.center_easting - (region.map_width / 2) * region.res; - region.north_real = region.center_northing + (region.map_height / 2) * region.res; + region.map_west = region.center_easting - (region.map_width / 2.) * region.map_res; + region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res; return; } /** - \brief Draw cross symbol of given size in device content + \brief Draw cross symbol of given size to device content - Used for points, node, vertices + Used for points, nodes, vertices \param[in] point coordinates of center \param[in] size size of the cross symbol @@ -540,12 +573,8 @@ } /** - \brief Select vector features by given bounding box + \brief Select vector objects by given bounding box - rect = ((x1, y1), (x2, y2)) - Number of selected features can be decreased by 'onlyType' - ('NULL' for all types) - \param[in] x1,y1,x2,y2 corners coordinates of bounding box \return number of selected features @@ -599,24 +628,25 @@ \brief Select vector feature by given point in given threshold - Only one vector feature can be selected. + Only one vector object can be selected. \param[in] x,y point of searching \param[in] thresh threshold value where to search - \param[in] onlyType select vector feature of given - type + \param[in] onlyType select vector object of given type - \return 1 if vector feature found - \return 0 if no vector feature found + \return 1 vector object found + \return 0 no vector object found */ int DisplayDriver::SelectLinesByPoint(double x, double y, double thresh, int onlyType) { int line; - + line = Vect_find_line(mapInfo, x, y, 0.0, - -1, thresh, 0, 0); + GV_POINTS | GV_LINES, thresh, 0, 0); + std::cout << x << " " << y << " " << thresh << "->" << line << std::endl; + if (line > 0) { selected.push_back(line); return 1; @@ -626,12 +656,12 @@ } /** - \brief Is vector feature selected? + \brief Is vector object selected? - \param[in] line vector feature id + \param[in] line id - \return if vector feature is selected return true - \return if not return false + \return true if vector object is selected + \return false if vector object is not selected */ bool DisplayDriver::IsSelected(int line) { @@ -647,7 +677,7 @@ /** \brief Unselect selected features by user - Clear list of ids of selected vector features + Clear list of ids of selected vector objects \param @@ -661,13 +691,12 @@ } /** - \brief Return grass ids of selected vector features + \brief Get ids of selected objects - \param[in] grassId If true method returns GRASS ids of - vector features, if false returns ids of objects - drawn in PseudoDC + \param[in] grassId if true return GRASS line ids + if false return PseudoDC ids - \return list of ids of selected vector features + \return list of ids of selected vector objects */ std::vector DisplayDriver::GetSelected(bool grassId) { @@ -691,9 +720,9 @@ } /** - \brief Set ids of selected vector features + \brief Set selected vector objects - \param[in] list of ids to be set + \param[in] list of GRASS ids to be set \return 1 */ @@ -707,20 +736,26 @@ /** \brief Get PseudoDC vertex id of selected line - \param[in] x,y coordinates of vertex on line + \param[in] x,y coordinates of click - \return PseudoDC ids (vertex, left vertex, right vertex, left line, right line) - \return (0) no line found - \return (-1) on error + \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) { - struct lineDesc *desc; - int line, type, minIdx, lline, rline; // left, right line + struct lineDesc *desc; // line desription + + int line, type; + int Gid, DCid; + int vx, vy, vz; // vertex screen coordinates + double dist, minDist; - - std::vector returnId; // TODO: long int + std::vector returnId; + + // only one object can be selected if (selected.size() != 1) return returnId; @@ -728,18 +763,19 @@ type = Vect_read_line (mapInfo, points, cats, line); + // find the closest vertex (x, y) 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); if (idx == 0) { minDist = dist; - minIdx = idx; + Gid = idx; } else { if (minDist > dist) { minDist = dist; - minIdx = idx; + Gid = idx; } } } @@ -747,31 +783,38 @@ desc = &(ids[line]); // translate id - minIdx = minIdx * 2 + desc->startId; + DCid = Gid * 2 + desc->startId; // add selected vertex - returnId.push_back(minIdx); - // left vertex & line - if (minIdx == desc->startId) { + returnId.push_back(DCid); + Cell2Pixel(points->x[Gid], points->y[Gid], points->z[Gid], + &vx, &vy, &vz); + wxRect rect (vx, vy, 0, 0); + dc->SetIdBounds(DCid, rect); + + // left vertex + if (DCid == desc->startId) { returnId.push_back(-1); - lline = -1; } else { - returnId.push_back(minIdx - 2); - lline = minIdx - 1; + returnId.push_back(DCid - 2); + Cell2Pixel(points->x[Gid-2], points->y[Gid-2], points->z[Gid-2], + &vx, &vy, &vz); + wxRect rect (x, y, 0, 0); + dc->SetIdBounds(DCid-2, rect); } + // right vertex - if (minIdx == (desc->npoints - 1) * 2 + desc->startId) { + if (DCid == (desc->npoints - 1) * 2 + desc->startId) { returnId.push_back(-1); - rline = -1; } else { - returnId.push_back(minIdx + 2); - rline = minIdx + 1; + returnId.push_back(DCid + 2); + Cell2Pixel(points->x[Gid+2], points->y[Gid+2], points->z[Gid+2], + &vx, &vy, &vz); + wxRect rect (x, y, 0, 0); + dc->SetIdBounds(DCid + 2, rect); } - - returnId.push_back(lline); - returnId.push_back(rline); return returnId; } Modified: trunk/grassaddons/gui/display_driver/driver.h =================================================================== --- trunk/grassaddons/gui/display_driver/driver.h 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/display_driver/driver.h 2007-09-05 14:47:50 UTC (rev 1079) @@ -52,22 +52,19 @@ struct line_cats *cats; struct _region { - double north; // map units - double south; - double east; - double west; + // GRASS region section + BOUND_BOX box; // W,E,N,S,T,B double ns_res; double ew_res; double center_easting; double center_northing; + // map window section double map_width; // px double map_height; - - // real region - double west_real; - double north_real; - double res; + double map_west; + double map_north; + double map_res; } region; struct symbol { @@ -115,12 +112,12 @@ public: /* constructor */ - DisplayDriver(); + DisplayDriver(void *device); /* destructor */ ~DisplayDriver(); /* display */ - int DrawMap(void *device); + int DrawMap(); /* select */ int SelectLinesByBox(double x1, double y1, double x2, double y2); @@ -136,6 +133,7 @@ void CloseMap(); void OpenMap(const char *mapname, const char *mapset); void ReloadMap(); + void SetDevice(void *device); /* set */ void SetRegion(double north, double south, double east, double west, Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-05 14:47:50 UTC (rev 1079) @@ -614,7 +614,8 @@ if self.layer > 0 and \ self.layer not in self.mapInfo.layers.keys(): dlg = wx.MessageDialog(None, - _("Layer %d is not available in vector map <%s>") % \ + _("Attribute table not found.\n" + "Layer %d is not available in vector map <%s>") % \ (layer, self.map), _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-05 14:47:50 UTC (rev 1079) @@ -412,13 +412,17 @@ # initialize wx display driver try: - self.__display = DisplayDriver() + self.__display = DisplayDriver(mapwindow.pdcVector) except: self.__display = None settings = self.parent.settings self.UpdateSettings() + def SetDevice(self, pdc): + """Set device for driver""" + self.__display.SetDevice(pdc) + def Reset(self, map): """Close map and open new one""" if map: @@ -432,14 +436,14 @@ self.__display.ReloadMap() - def DrawMap(self, pdc): + def DrawMap(self): """Draw vector map layer content Return wx.Image """ import time start = time.clock() - nlines = self.__display.DrawMap(pdc) + nlines = self.__display.DrawMap() stop = time.clock() Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d, sec=%f" % \ (nlines, stop-start)) @@ -471,9 +475,9 @@ -1); Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): selected=%d" % \ - nselected) + nselected) - return (nselected,) # tuple + return nselected def GetSelected(self, grassId=True): """Return ids of selected vector features Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-05 14:47:50 UTC (rev 1079) @@ -523,8 +523,9 @@ # set region self.parent.digit.driver.UpdateRegion() # draw map - self.pdcVector = wx.PseudoDC() - self.parent.digit.driver.DrawMap(self.pdcVector) + self.pdcVector.Clear() + self.pdcVector.RemoveAll() + self.parent.digit.driver.DrawMap() # # render overlay @@ -597,12 +598,16 @@ dc = wx.BufferedDC(wx.ClientDC(self)) dc.SetBackground(wx.Brush("White")) dc.Clear() + + #if not self.img: + # return False + + # bitmap = wx.BitmapFromImage(self.img) - if not self.img: - return False - - bitmap = wx.BitmapFromImage(self.img) - self.dragimg = wx.DragImage(bitmap) + # 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.dragimg.BeginDrag((0, 0), self) self.dragimg.GetImageRect(moveto) self.dragimg.Move(moveto) @@ -1692,7 +1697,7 @@ 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 " + self.showRegion.SetToolTip(wx.ToolTip (_("Show/hide computational " "region extent (set with g.region)"))) self.Map.SetRegion() # set region # map_frame_statusbar_fields = [ Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-04 13:36:53 UTC (rev 1078) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-05 14:47:50 UTC (rev 1079) @@ -459,7 +459,8 @@ self.parent.MapWindow.SetCursor(self.parent.cursors["cross"]) # create pseudoDC for drawing the map - self.parent.pdcVector = wx.PseudoDC() + self.parent.MapWindow.pdcVector = wx.PseudoDC() + self.parent.digit.driver.SetDevice(self.parent.MapWindow.pdcVector) return True @@ -484,6 +485,7 @@ # disable pseudodc for vector map layer self.parent.MapWindow.pdcVector = None + self.parent.digit.driver.SetDevice(None) return True From ullah at grass.itc.it Sat Sep 8 01:16:17 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Sep 8 01:16:19 2007 Subject: [grass-addons] r1080 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709072316.l87NGHK9005025@grass.itc.it> Author: ullah Date: 2007-09-08 01:16:11 +0200 (Sat, 08 Sep 2007) New Revision: 1080 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: MAJOR CHANGE TO THE ERSOION ALGORITHM!!! All older versions had a serious flaw in the routine that simulated the actual location of the erosion and depostion. This version corrects this flaw with a new alogrithm that solves many issues that were encountered with the old system. Landscape evolution is much more accurate and realistic with this version. Also, change the way some stats and other things are calculated internally. Deleted and/or changed some flags having to do with summary stat maps. Also, Smoothdz is no longer kept, and is instead replaced with the optional "netchange" map wich reflects more accurately the new erosion deposition location algorithm. PLEASE REPLACE ALL OLDER VERSIONS WITH THIS ONE! Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-05 14:47:50 UTC (rev 1079) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-07 23:16:11 UTC (rev 1080) @@ -76,11 +76,6 @@ #% guisection: Input #%end #%flag -#% key: n -#% description: -n Do not output maps of net erosion/deposition -#% guisection: Input -#%end -#%flag #% key: l #% description: -l Do not output maps of soil depths #% guisection: Input @@ -213,31 +208,26 @@ #%end #%flag +#% key: n +#% description: -n Output maps of net erosion/deposition for ever year +#% guisection: Statistics +#%end +#%flag #% key: c -#% description: -c Output cumulative erosion/depostition map from data for all iterations +#% description: -c Output cumulative erosion/deposition map from data for all iterations #% guisection: Statistics #%end #%flag #% key: m -#% description: -m Output mean erosion/depostition map from data for all iterations +#% description: -m Output mean erosion/depostition map from data for all iterations (must check -n as well) #% guisection: Statistics #%end #%flag #% key: t -#% description: -t Output standard deviation of erosion/depostition map from data for all iterations +#% description: -t Output standard deviation of erosion/depostition map from data for all iterations (must check -n as well) #% guisection: Statistics #%end #%flag -#% key: x -#% description: -x Output maximum erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag -#% key: i -#% description: -i Output minimum erosion/depostition map from data for all iterations -#% guisection: Statistics -#%end -#%flag #% key: s #% description: -s Output mean soil depths map from data for all iterations #% guisection: Statistics @@ -350,9 +340,9 @@ echo "qsxdx=$qsxdx" qsydy=$prefx"qsy_dy"$num echo "qsydy=$qsydy" -m=$prefx"m"$num +m=$prefx"mexp"$num echo "m=$m" -n=$prefx"n"$num +n=$prefx"nexp"$num echo "n=$n" erdep=$prefx"erosdep"$num echo "erdep=$erdep" @@ -361,11 +351,12 @@ echo "" smoothdz=$prefx"smoothdz"$num +netchange=$prefix"netchange"$num new_soil=$prefx$outsoil$num new_dem=$prefx$outdem$num initsoil=$prefx"initsoil" -echo "The new net erosion/deposition map for this iteration will be called $smoothdz" +echo "The new net erosion/deposition map for this iteration will be called $netchange" echo "The new dem for this iteration will be called $new_dem" echo "The new soil depth map for this iteration will be called $new_soil" @@ -612,7 +603,6 @@ echo "*************************" echo "" - r.slope.aspect --q $qsx dx=$qsxdx r.slope.aspect --q $qsy dy=$qsydy @@ -635,7 +625,7 @@ echo "" echo "*************************" -echo "step 7 of 8: running band-pass filter" +echo "step 7 of 8: running despeckling filter" echo "*************************" echo "" @@ -666,21 +656,49 @@ +echo "" +echo "*************************" +echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" +echo "*************************" +echo "" -# create temporary file to code colors for $smoothdz -TMP1=`g.tempfile pid=$$` +#put the net dz back where it is upposed to go and then subtract it from dem to make new dem +if [ $number -eq 1 ] ; then +temp_dem=$prfx"temp_dem" -if [ $? -ne 0 ] || [ -z "$TMP1" ]; then - echo "ERROR: unable to create temporary file for colors" 1>&2 - exit 1 +r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($elev + $smoothdz))))))))), (if(isnull(x), $elev, x)))" + + +r.patch --quiet input=$temp_dem,$elev output=$new_dem + +g.remove --quiet rast=$temp_dem + else - echo "creating temporary file to code colors" +r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($elev + $smoothdz))))))))), (if(isnull(x), $elev, x)))" + fi +#make $netchange if asked +if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 0 -o "$GIS_FLAG_t" -eq 0 ]; then + +r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, x)))" + +#set colors to $elev +r.colors --quiet map=$new_dem rast=$elev + +# create temporary file to code colors for $netchange + +# create temporary file to list all the smoothdz files for statistics +TMP1=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file to list all the netchange files for statistics" 1>&2 + exit 1 +fi + echo "100% 0 0 100" > $TMP1 echo "3 blue" >> $TMP1 echo "1 indigo" >> $TMP1 @@ -690,37 +708,13 @@ echo "-1 orange" >> $TMP1 echo "-3 red" >> $TMP1 echo "0% 150 0 50" >> $TMP1 -echo "end" >> $TMP1 -cat $TMP1 | r.colors --q map=$smoothdz color=rules +r.colors --quiet map=$netchange rules=$TMP1 -echo "" -echo "*************************" -echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" -echo "*************************" -echo "" - - -if [ $number -eq 1 ] ; then - -temp_dem=$prfx"temp_dem" - -r.mapcalc "$temp_dem=$smoothdz + $elev" - -r.patch --quiet input=$temp_dem,$elev output=$new_dem - -g.remove --quiet rast=$temp_dem - -else - -r.mapcalc "$new_dem=$smoothdz + $elev" - fi -r.colors --quiet map=$new_dem rast=$elev - if [ $GIS_FLAG_b -eq 1 ]; then echo "" @@ -802,8 +796,10 @@ echo "" -echo "Raster map $smoothdz shows filtered net erosion/deposition" +echo "If made, raster map $netchange shows filtered net erosion/deposition" echo "" +echo "If made, raster map $soildepth shows soildpeths" +echo "" echo "Raster map $new_dem shows new landscape (new elevations) after net erosion/depostion" echo "*************************" echo "" @@ -869,9 +865,9 @@ echo "qsxdx=$qsxdx" qsydy=$prefx"qsy_dy"$step echo "qsydy=$qsydy" -m=$prefx"m"$step +m=$prefx"mexp"$step echo "m=$m" -n=$prefx"n"$step +n=$prefx"nexp"$step echo "n=$n" erdep=$prefx"erosdep"$step echo "erdep=$erdep" @@ -883,10 +879,11 @@ echo "" smoothdz=$prefx"smoothdz"$step +netchange=$prefx"netchange"$step new_soil=$prefx$outsoil$step new_dem=$prefx$outdem$step -echo "The new net ersoion/deposition map for this iteration will be called $smoothdz" +echo "The new net ersoion/deposition map for this iteration will be called $netchange" echo "The new dem for this iteration will be called $new_dem" echo "The new soil depth map for this iteration will be called $new_soil" @@ -1108,7 +1105,7 @@ echo "" echo "*************************" -echo "step 7 of 8: running band-pass filter" +echo "step 7 of 8: running despeckling filter" echo "*************************" echo "" @@ -1136,17 +1133,28 @@ #now we must correct for the incredible edge shrinking effect by patching the last smoothdz underneath the new smoothdz r.patch input=$temp2smoothdz,$lastsmooth output=$smoothdz -#set the colors to our rules -cat $TMP1 | r.colors --q map=$smoothdz color=rules - echo "" echo "*************************" echo "step 8 of 8: calculating terrain evolution and new soil depths/bedrock elevations" echo "*************************" echo "" -r.mapcalc "$new_dem=$smoothdz + $old_dem" + +#put the net dz back where it is upposed to go and then subtract it from dem to make new dem +r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, x)))" + +#make $netchange if asked +if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 0 -o "$GIS_FLAG_t" -eq 0 ]; then + +r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, x)))" + +#set the colors to our rules +r.colors --quiet map=$netchange rules=$TMP1 + +fi + +#set new dem colors to match $elev r.colors --q map=$new_dem rast=$elev if [ $GIS_FLAG_b -eq 1 ]; then @@ -1216,66 +1224,70 @@ echo "" -echo "Raster map $smoothdz shows filtered net erosion/deposition" +echo "If made, raster map $netchange shows filtered net erosion/deposition" echo "" +echo "If made, raster map $new_soil shows soildpeths" +echo "" echo "Raster map $new_dem shows new landscape (new elevations) after net erosion/depostion" echo "*************************" echo "########################################################" echo "" -#remove the temp files to avoid confusion... -\rm -f $TMP1 $TMP1.sort + done -# now we have met the loop critereon set by us above, so we have broken out. We must now reset the region settings +# now we have met the loop critereon set by us above, so we have broken out. +if [ "$GIS_FLAG_c" -eq 1 ]; then -if [ "$GIS_FLAG_c" -eq 1 -o "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 -o "$GIS_FLAG_x" -eq 1 -o "$GIS_FLAG_i" -eq 1 ]; then +r.mapcalc "$prefx"cum_erdep"=$new_dem-$elev" + +#set the colors to our rules +r.colors --quiet map=$prefx"cum_erdep" rules=$TMP1 + +fi + +if [ "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 ]; then + # create temporary file to list all the smoothdz files for statistics TMP2=`g.tempfile pid=$$` if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then - echo "ERROR: unable to create temporary file to list all the smoothdz files for statistics" 1>&2 + echo "ERROR: unable to create temporary file to list all the netchange files for statistics" 1>&2 exit 1 fi -g.mlist type=rast sep=, pattern=$prefx"smoothdz*" > $TMP2 +g.mlist type=rast sep=, pattern=$prefx"netchange*" > $TMP2 liststring=`cat $TMP2` -echo "Any selected statistics will be performed using the following smoothdz files: $liststring" +echo "Any selected statistics will be performed using the following netchange files: $liststring" -if [ "$GIS_FLAG_c" -eq 1 ]; then +if [ "$GIS_FLAG_m" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"cum_erdep" method=sum -fi +r.series --q input=$liststring output=$prefx"ave_erdep" method=average -if [ "$GIS_FLAG_m" -eq 1 ]; then +#set the colors to our rules +r.colors --quiet map=$prefx"ave_erdep" rules=$TMP1 -r.series --q input=$liststring output=$prefx"ave_erdep" method=average fi if [ "$GIS_FLAG_t" -eq 1 ]; then r.series --q input=$liststring output=$prefx"sdev_erdep" method=stddev -fi -if [ "$GIS_FLAG_x" -eq 1 ]; then +#set the colors to our rules +r.colors --quiet map=$prefx"sdev_erdep" rules=$TMP1 -r.series --q input=$liststring output=$prefx"max_erdep" method=maximum fi -if [ "$GIS_FLAG_i" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"min_erdep" method=minimum -fi - \rm -f $TMP2 $TMP2.sort fi -if [ "$GIS_FLAG_s" -eq 1 -o "$GIS_FLAG_v" -eq 1 -o "$GIS_FLAG_a" -eq 1 -o "$GIS_FLAG_u" -eq 1 -o "$GIS_FLAG_x" -eq 1 ]; then +if [ "$GIS_FLAG_s" -eq 1 -o "$GIS_FLAG_v" -eq 1 -o "$GIS_FLAG_a" -eq 1 -o "$GIS_FLAG_u" -eq 1 ]; then # create temporary file to list all the soil depth files for statistics TMP3=`g.tempfile pid=$$` @@ -1318,6 +1330,25 @@ echo "************************" + +if [ "$GIS_FLAG_n" -eq 1 ]; then + +echo "" + +else + +echo "" +g.mremove -f --q rast=$prfx"netchange*" + +fi + + +if [ "$GIS_FLAG_l" -eq 1 ]; then + + g.mremove --q rast=$prefx$outsoil"*" +fi + + if [ "$GIS_FLAG_k" -eq 1 ]; then echo "" @@ -1335,6 +1366,7 @@ g.mremove -f --q rast=$prefx"slope*" g.mremove -f --q rast=$prefx"aspect*" g.mremove -f --q rast=$prefx"sflowtopo*" +g.mremove -f --q rast=$prefx"flowaspect*" g.mremove -f --q rast=$prefx"qsx*" g.mremove -f --q rast=$prefx"qsy*" g.mremove -f --q rast=$prefx"qsx_dx*" @@ -1346,23 +1378,20 @@ g.mremove -f --q rast=$prefx"rate*" g.mremove -f --q rast=$prefx"tempsmoothdz*" g.mremove -f --q rast=$prefx"temp2smoothdz*" -g.mremove -f --q rast=$prefx"m*" -g.mremove -f --q rast=$prefx"n*" +g.mremove -f --q rast=$prefx"mexp*" +g.mremove -f --q rast=$prefx"nexp*" +g.mremove -f --q rast=$prefx"smoothdz*" echo "" echo "Done" fi -if [ "$GIS_FLAG_n" -eq 1 ]; then - g.mremove --q rast=$prefx"smoothdz*" -fi +#remove color file +\rm -f $TMP1 -if [ "$GIS_FLAG_l" -eq 1 ]; then - g.mremove --q rast=$prefx$outsoil"*" -fi if [ "$GIS_FLAG_z" -eq 1 ]; then echo "" From ullah at grass.itc.it Sat Sep 8 01:51:25 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Sat Sep 8 01:51:26 2007 Subject: [grass-addons] r1081 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709072351.l87NpPAC006689@grass.itc.it> Author: ullah Date: 2007-09-08 01:51:19 +0200 (Sat, 08 Sep 2007) New Revision: 1081 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: A minor change to the color files. PLEASE SEE THE LOG FILE FOR THE LAST VERSION! Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-07 23:16:11 UTC (rev 1080) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-07 23:51:19 UTC (rev 1081) @@ -700,13 +700,13 @@ fi echo "100% 0 0 100" > $TMP1 -echo "3 blue" >> $TMP1 -echo "1 indigo" >> $TMP1 -echo "0.5 green" >> $TMP1 +echo "2 blue" >> $TMP1 +echo "0.5 indigo" >> $TMP1 +echo "0.1 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "-0.5 yellow" >> $TMP1 -echo "-1 orange" >> $TMP1 -echo "-3 red" >> $TMP1 +echo "-0.1 yellow" >> $TMP1 +echo "-0.5 orange" >> $TMP1 +echo "-2 red" >> $TMP1 echo "0% 150 0 50" >> $TMP1 From landa at grass.itc.it Sun Sep 9 11:23:23 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 9 11:23:24 2007 Subject: [grass-addons] r1082 - trunk/grassaddons/grassflyer/flyer1/en Message-ID: <200709090923.l899NNjZ030383@grass.itc.it> Author: landa Date: 2007-09-09 11:23:20 +0200 (Sun, 09 Sep 2007) New Revision: 1082 Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex Log: Typo (souce -> source) Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-07 23:51:19 UTC (rev 1081) +++ trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-09 09:23:20 UTC (rev 1082) @@ -80,7 +80,7 @@ \section{Open Source Philosophy} -The Open Source philosophy provides the user the ability to see the source code and structure of the program which offers a great transparency. Users can extend the program for their own needs. Immediate souce code peer review increases the quality. With the help of the extension manager new modules can be created without GRASS package source code. +The Open Source philosophy provides the user the ability to see the source code and structure of the program which offers a great transparency. Users can extend the program for their own needs. Immediate source code peer review increases the quality. With the help of the extension manager new modules can be created without GRASS package source code. \section{Technical Data Sheet} From landa at grass.itc.it Sun Sep 9 11:26:56 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 9 11:26:58 2007 Subject: [grass-addons] r1083 - trunk/grassaddons/grassflyer/flyer1/en Message-ID: <200709090926.l899QuV3030406@grass.itc.it> Author: landa Date: 2007-09-09 11:26:52 +0200 (Sun, 09 Sep 2007) New Revision: 1083 Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex Log: Initial CZ translation (not final -- need corrections). Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-09 09:23:20 UTC (rev 1082) +++ trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-09 09:26:52 UTC (rev 1083) @@ -13,6 +13,7 @@ %If you need a foldmark, delete nofoldmark \documentclass[notumble,a4paper,10pt,nofoldmark]{leaflet} \usepackage{helvet,courier,xcolor} +\usepackage[utf8]{inputenc} % Set Helvetica as the default font \renewcommand*\familydefault\sfdefault @@ -41,17 +42,17 @@ \hypersetup{% colorlinks=true,% urlcolor=darkblue,% Redefine this color to change URIs color - pdfauthor={The GRASS Community},% - pdftitle={GRASS GIS: Efficiency through Freedom \& Transparency},% - pdfsubject={GRASS Promotion Flyer},% + pdfauthor={GRASS Community},% + pdftitle={GRASS GIS: U?innost Svodody \& Transparentnosti},% + pdfsubject={GRASS propaga?n? let?k GRASS},% breaklinks=true,% plainpages=false% } % Title page stuff \title{\textbf{\huge GRASS GIS}\\% -\textsl{Efficiency through Freedom \& Transparency}} -\author{The GRASS Community} +\textsl{U?innost Svodody \& Transparentnosti}} +\author{Komunita GRASSu} \date{\includegraphics[width=\textwidth]{grasslogo_vector}\\[2ex] \large\GRASSurl} @@ -62,90 +63,90 @@ \newpage -\section{What is GRASS} +\section{Co je GRASS} -GRASS (Geographic Resources Analysis Support System) is a free and Open Source Software for performing spatial analysis. It consists of more than 350 modules for processing vector (2D/3D), raster and voxel data. Many interfaces to other programs in related domains like geostatistics, databases, mapserver and even other GIS software exist. It is the largest Open Source GIS. It can serve as a Desktop GIS and as the backbone of a complete GIS Infrastructure. +GRASS (Geographic Resources Analysis Support System) je svobodn?/Open Source software ur?en? pro prostorov? anal?zy. Obsahuje v?ce ne? 350 modul? pro zpracov?n? 2D/3D vektorov?ch a rastrov?ch dat. Nab?z? ?adu rozhran? k dal??m program?m v dan? oblasti jako je geostatistika, datab?ze, mapov? slu?by a dokonce i k dal??m GIS aplikac?m. Je nejrozs?hlej??m Open Source GISem. M??e slou?it jako Desktop GIS ?i jako p?te? kompletn? GIS infrastrukturu. -\section{Where is GRASS used} +\section{Kde je GRASS pou??v?n} -GRASS is used in scientific applications, commercial settings and by public authorities all over the world. GRASS has shown strong potential for solving geospatial problems in numerous situations world-wide. +GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? spr?v? po cel?m sv?t?. GRASS pokytuje v mnoha p?ipadech velk? potenci?l pro ?e?en? geoprostorov?ch ?loh. -\section{History} +\section{Historie} -GRASS was originally developed in the beginning of the 1980's by the US Army Construction Engineering Research Laboratories (USA-CERL) and was published as public domain software. When the USA-CERL withdrew from GRASS development, an international developer team took over this work. Since 1999, GRASS has been published as free software under the terms of the GNU General Public Licence. +GRASS byl p?vodn? vyv?jen od po??tku 80-t?ch let agenturou US Army Construction Engineering Research Laboratories (USA-CERL) a byl poskytnut jako public domain software. V okam?iku kdy USA-CERL upustil od v?voje, vzniknul mezin?rodn? t?m v?voj??? kter? d?l software vyv?j?. Od roku 1999 je GRASS uvoln?n jako free software pod licenc? GNU General Public Licence. \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{visibility} -\captionof{figure}{Viewshed analysis performed with GRASS} +\captionof{figure}{Anal?za viditelnost provedena v GRASSu} \end{myfig} -\section{Open Source Philosophy} +\section{Filozofie Open Source} -The Open Source philosophy provides the user the ability to see the source code and structure of the program which offers a great transparency. Users can extend the program for their own needs. Immediate source code peer review increases the quality. With the help of the extension manager new modules can be created without GRASS package source code. +Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do zdrovov?ch k?du a struktury programu, obrovskou m?ru transparentnosti. U?ivatel m??e roz???it program dle sv?ch pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez nutnosti zdrovov?ho k?du GRASSu. -\section{Technical Data Sheet} +\section{Technick? data} -\subsection{License} +\subsection{Licence} -GNU General Public License (Free Software Foundation) +V?eobecn? ve?ejn? licence GNU (GNU General Public License, Free Software Foundation) -\subsection{Supported platforms} +\subsection{Podporovan? platformy} -GRASS runs on nearly all platforms. It supports GNU/Linux, Posix compliant Unix Systems, MS-Windows and MacOS X. +GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? syst?my podporuj?c? Posix, MS-Windows a MacOS X. \subsection{Design} \begin{itemize} -\item Modular -\item Consists of more than 350 modules +\item Modul?rn? +\item Obsahuje v?ce ne? 350 modul? \end{itemize} -\subsection{Programming Languages} +\subsection{Programovac? jazyky} \begin{itemize} \item ANSI C -\item GRASS- SWIG interface -\item Python for WebGIS applications -\item Java Version: JGRASS +\item Rozhran? GRASS- SWIG +\item Python pro WebGIS aplikace +\item Verze pro Javu: JGRASS \end{itemize} -\subsection{Data Management Capabilities} +\subsection{Mo?nosti spr?vy dat} \begin{itemize} -\item Raster / Vector / Voxel data processing -\item 2D / 3D Raster / Vector modelling -\item Image manipulation -\item Vector topology / Network analysis -\item Geostatistics (Interface to R) +\item Zpracov?n? rasterov?ch / vektorov?ch / voxel dat +\item Modelov?n? 2D / 3D rastrov?ch / vektorov?ch dat +\item Zpracov?n? obrazov?ch dat +\item Vektorov? topologie / S??ov? anal?zy +\item Geostatistika (rozhran? pro R) \end{itemize} \begin{myfig}[1ex] \includegraphics[width=0.7\textwidth]{trento3d} -\captionof{figure}{A flyby of the city of Trento, Italy} +\captionof{figure}{3D pohled na Trento, It?lie} \end{myfig} -\section{Supported File Formats} +\section{Podporovan? datov? form?ty} -GRASS supports nearly all common GIS file formats through the use of the GDAL/OGR library. In addition it supports the Open GIS Consortium's Simple Features. +GRASS podporuje t?m?? v?echny dob?e zn?m? GIS datov? form?ty d?ky knihovn? GDAL/OGR. Nav?c podporuje Open GIS Consortium's Simple Features. -\subsection{Vector File formats} +\subsection{Vektorov? datov? form?ty} ASCII, ARC/INFO ungenerate, ARC/INFO E00, Arc\-View SHAPE, BIL, DLG (U.S.), DXF, DXF3D, GMT, GPS-ASCII USGS-DEM, IDRISI, MOSS, MapInfo MIF, TIGER, VRML, \dots -\subsection{Raster File Formats} +\subsection{Rastrov? datov? form?ty} ASCII, ARC/GRID, E00, GIF, GMT, TIF, PNG, Vis5D, SURFER (.grd),\dots \begin{myfig} \includegraphics[width=0.7\textwidth]{isodist} -\captionof{figure}{Default GUI configuration showing GRASS network analysis capabilites} +\captionof{figure}{V?choz? konfigurace GUI ukazuj?c? mo?nosti GRASSu pro s??ov? anal?zy} \end{myfig} -\subsection{Image File Formats} +\subsection{Obrazov? datov? form?ty} CEOS (SAR, SRTM, LANDSAT7 etc.), ERDAS LAN / IMG, HDF, LANDSAT TM/MSS, NHAP aerial photos, SAR, SPOT, \dots \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{ndvi} -\captionof{figure}{Image processing capabilities of GRASS} +\captionof{figure}{Mo?nosti GRASS ve zpracov?n? obrazov?ch dat} \end{myfig} -\subsection{Database support} +\subsection{Podpora databaz?} \begin{itemize} \item PostgreSQL / PostGIS @@ -155,41 +156,41 @@ \item DBF \end{itemize} -\subsection{Output} +\subsection{V?stup} \begin{itemize} -\item Modules for creating maps -\item NVIZ for visualization of 2.5D and 3D data (creation of animations \& flybys) +\item Moduly pro tvorbu mapov?ch v?stup? +\item NVIZ pro vizualizaci 2.5D a 3D dat (tvorba animac? \& pohled?) %\item{GMT export} %item{VRML} \item VTK, POVray -\item WebGIS via Mapserver, Python, etc. +\item WebGIS pomoc? Mapserver, Python, a pod. \end{itemize} -\subsection{Interoperability to other GIS- related Software} +\subsection{Interoperabilita v??i dal??m GIS program?m} \begin{itemize} -\item Quantum GIS (Free Geodata Viewer and more) -\item R- Language (Statistics) -\item Gstat (Geostatistics) -\item UMN Mapserver (Webmapping) +\item Quantum GIS (Free Geodata (nejen) prohl??e?) +\item R- Language (statistika) +\item Gstat (geostatistika) +\item UMN Mapserver (webov? slu?by) \end{itemize} -\section{Where to find more information} +\section{Kde naj?t dal?? informace} \begin{itemize} %\begin{flushleft} -\item{Project Website: \\\GRASSurl} +\item{Webov? str?nky projektu: \\\GRASSurl} \item{GRASS Wiki: \\\url{http://grass.gdf.hannover.de/wiki}} -\item{GRASS Promotion Team: \\\url{malte@perlomat.de}} -\item{GRASS mailing lists: \\\url{http://grass.itc.it/community/support.php}} +\item{Propaga?n? t?m GRASSu: \\\url{malte@perlomat.de}} +\item{Elektronick? konference GRASSu: \\\url{http://grass.itc.it/community/support.php}} %\end{flushleft} \end{itemize} \vfill \section{OSGeo} -GRASS is a founding project of the Open Source Geospatial Foundation which has the aim to create high quality open source geospatial software. For further information visit the OSGeo homepage: +GRASS je zakl?daj?c?m projektem Open Source Geospatial Foundation, kter? si klade za c?l tvorbu vysoce kvalitn?ho Open Source GIS software. Pro dal?? informace nav?tivte domovskou str?nku OSGeo: \begin{center} \includegraphics[width=0.8\textwidth]{OSGeo_CMYK}\\ \url{http://www.osgeo.org} From landa at grass.itc.it Sun Sep 9 11:31:31 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 9 11:31:34 2007 Subject: [grass-addons] r1084 - in trunk/grassaddons/grassflyer/flyer1: . cz cz/pix Message-ID: <200709090931.l899VVpW030441@grass.itc.it> Author: landa Date: 2007-09-09 11:29:53 +0200 (Sun, 09 Sep 2007) New Revision: 1084 Added: trunk/grassaddons/grassflyer/flyer1/cz/ trunk/grassaddons/grassflyer/flyer1/cz/Makefile trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt trunk/grassaddons/grassflyer/flyer1/cz/caption.sty trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex trunk/grassaddons/grassflyer/flyer1/cz/leaflet.cls trunk/grassaddons/grassflyer/flyer1/cz/pix/ trunk/grassaddons/grassflyer/flyer1/cz/pix/OSGeo_CMYK.pdf trunk/grassaddons/grassflyer/flyer1/cz/pix/grasslogo_vector.pdf trunk/grassaddons/grassflyer/flyer1/cz/pix/isodist.png trunk/grassaddons/grassflyer/flyer1/cz/pix/ndvi.png trunk/grassaddons/grassflyer/flyer1/cz/pix/trento3d.pdf trunk/grassaddons/grassflyer/flyer1/cz/pix/visibility.png Log: Initial CZ translation (need corrections). Added: trunk/grassaddons/grassflyer/flyer1/cz/Makefile =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/Makefile (rev 0) +++ trunk/grassaddons/grassflyer/flyer1/cz/Makefile 2007-09-09 09:29:53 UTC (rev 1084) @@ -0,0 +1,19 @@ +vectoreps := $(wildcard *.eps) +vectorfinal := $(patsubst %.eps,%.pdf,$(vectoreps)) + +default: grassflyer.pdf + +$(vectorfinal): $(vectoreps) + eps2eps -sOutputFile=- $< | epstopdf -f + +%.pdf: %.tex + pdflatex $< + pdflatex $< + +clean: + rm -f *.aux *.log *.out + +distclean: clean + rm -f *.pdf + +.PHONY: clean distclean default Added: trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt (rev 0) +++ trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt 2007-09-09 09:29:53 UTC (rev 1084) @@ -0,0 +1,8 @@ +PDF Version: + +ISO A4 format: + http://www.geog.fu-berlin.de/~malte/flyer_v1.pdf + +Letter format: + http://www.geog.fu-berlin.de/~malte/grassflyer_letter.pdf + Added: trunk/grassaddons/grassflyer/flyer1/cz/caption.sty =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/caption.sty (rev 0) +++ trunk/grassaddons/grassflyer/flyer1/cz/caption.sty 2007-09-09 09:29:53 UTC (rev 1084) @@ -0,0 +1,688 @@ +%% +%% This is file `caption.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% caption.dtx (with options: `package') +%% +%% Copyright (C) 1994-2004 Axel Sommerfeldt (caption@sommerfeldt.net) +%% +%% -------------------------------------------------------------------------- +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "maintained". +%% +%% This Current Maintainer of this work is Axel Sommerfeldt. +%% +%% This work consists of the files caption.ins, caption.dtx, +%% caption2.dtx, caption.xml, and anleitung.tex and the derived files +%% caption.sty, caption2.sty, and manual.tex. +%% +\NeedsTeXFormat{LaTeX2e}[1994/12/01] +\ProvidesPackage{caption}[2004/07/16 v3.0c Customising captions (AS)] +\providecommand*\@nameundef[1]{% + \expandafter\let\csname #1\endcsname\@undefined} +\providecommand\l@addto@macro[2]{% + \begingroup + \toks@\expandafter{#1#2}% + \edef\@tempa{\endgroup\def\noexpand#1{\the\toks@}}% + \@tempa} +\def\bothIfFirst#1#2{% + \protected@edef\caption@tempa{#1}% + \ifx\caption@tempa\@empty\else + #1#2% + \fi} +\def\bothIfSecond#1#2{% + \protected@edef\caption@tempa{#2}% + \ifx\caption@tempa\@empty\else + #1#2% + \fi} +\def\caption@ifinlist#1#2{% + \let\next\@secondoftwo + \edef\caption@tempa{#1}% + \@for\caption@tempb:={#2}\do{% + \ifx\caption@tempa\caption@tempb + \let\next\@firstoftwo + \fi}% + \next} +\def\caption@setbool#1#2{% + \caption@ifinlist{#2}{1,true,yes,on}{% + \expandafter\let\csname caption@if#1\endcsname\@firstoftwo + }{\caption@ifinlist{#2}{0,false,no,off}{% + \expandafter\let\csname caption@if#1\endcsname\@secondoftwo + }{% + \PackageError{caption}{Undefined boolean value `#2'}{\caption@eh}% + }}} +\def\caption@ifbool#1{\@nameuse{caption@if#1}} +\providecommand\captionsize{}% changed v3.0a+c +\newdimen\captionmargin +\newdimen\captionwidth +\newif\ifcaption@width +\newcommand\caption@setmargin{% + \caption@widthfalse + \setlength\captionmargin} +\newcommand\caption@setwidth{% + \caption@widthtrue + \setlength\captionwidth} +\newdimen\captionindent +\newdimen\captionparindent +\newdimen\captionhangindent +\newif\ifcaption@star +\@ifundefined{abovecaptionskip}{% + \newlength\abovecaptionskip\setlength\abovecaptionskip{10\p@}}{} +\@ifundefined{belowcaptionskip}{% + \newlength\belowcaptionskip\setlength\belowcaptionskip{0\p@}}{} +\newcommand\caption@eh{% + If you do not understand this error, please take a closer look\MessageBreak + at the documentation of the `caption' package.\MessageBreak + \@ehc} +\RequirePackage{keyval}[1997/11/10] +\providecommand*\undefine@key[2]{% + \@nameundef{KV@#1@#2}\@nameundef{KV@#1@#2@default}} +\newcommand\caption@setdefault{\captionsetup{% + format=default,labelformat=default,labelsep=default,justification=default,% + font=default,labelfont=default,textfont=default,% + margin=0pt,indention=0pt,parindent=0pt,hangindent=0pt,singlelinecheck}} +\newcommand*\DeclareCaptionStyle[1]{% + \@ifnextchar[{\caption@declarestyle{#1}}{\caption@declarestyle{#1}[]}} +\def\caption@declarestyle#1[#2]#3{% bugfixed v3.0a + \global\@namedef{caption@sls@#1}{#2}% + \global\@namedef{caption@sty@#1}{#3}} +\@onlypreamble\DeclareCaptionStyle +\@onlypreamble\caption@declarestyle +\newcommand*\caption@setstyle[1]{% + \@ifundefined{caption@sty@#1}% + {\PackageError{caption}{Undefined caption style `#1'}{\caption@eh}}% + {\expandafter\let\expandafter\caption@sls\csname caption@sls@#1\endcsname + \caption@setdefault\caption@esetup{\csname caption@sty@#1\endcsname}}} +\DeclareCaptionStyle{default}[justification=centering]{} +\newcommand\DeclareCaptionFormat[2]{% bugfixed v3.0a + \global\long\expandafter\def\csname caption@fmt@#1\endcsname##1##2##3{#2}} +\@onlypreamble\DeclareCaptionFormat +\newcommand*\caption@setformat[1]{% + \@ifundefined{caption@fmt@#1}% + {\PackageError{caption}{Undefined caption format `#1'}{\caption@eh}}% + {\expandafter\let\expandafter\caption@fmt\csname caption@fmt@#1\endcsname}} +\DeclareCaptionFormat{normal}{#1#2#3\par} +\DeclareCaptionFormat{hang}{% + \@hangfrom{#1#2}% + \advance\captionparindent\hangindent + \advance\captionhangindent\hangindent + \caption@@par + #3\par} +\def\caption@fmt@default{\caption@fmt@normal} +\newcommand*\DeclareCaptionLabelFormat[2]{% bugfixed v3.0a + \global\expandafter\def\csname caption@lfmt@#1\endcsname##1##2{#2}} +\@onlypreamble\DeclareCaptionLabelFormat +\newcommand*\caption@setlabelformat[1]{% + \@ifundefined{caption@lfmt@#1}% + {\PackageError{caption}{Undefined caption label format `#1'}{\caption@eh}}% + {\expandafter\let\expandafter\caption@lfmt\csname caption@lfmt@#1\endcsname}} +\DeclareCaptionLabelFormat{empty}{} +\DeclareCaptionLabelFormat{simple}{\bothIfFirst{#1}{\nobreakspace}#2} +\DeclareCaptionLabelFormat{parens}{\bothIfFirst{#1}{\nobreakspace}(#2)} +\def\caption@lfmt@default{\caption@lfmt@simple} +\newcommand\DeclareCaptionLabelSeparator[2]{% bugfixed v3.0a + \global\long\@namedef{caption@lsep@#1}{#2}} +\@onlypreamble\DeclareCaptionLabelSeparator +\newcommand*\caption@setlabelseparator[1]{% + \@ifundefined{caption@lsep@#1}% + {\PackageError{caption}{Undefined caption label separator `#1'}{\caption@eh}}% + {\expandafter\let\expandafter\caption@lsep\csname caption@lsep@#1\endcsname}} +\DeclareCaptionLabelSeparator{none}{} +\DeclareCaptionLabelSeparator{colon}{: } +\DeclareCaptionLabelSeparator{period}{. } +\DeclareCaptionLabelSeparator{space}{ } +\DeclareCaptionLabelSeparator{quad}{\quad} +\DeclareCaptionLabelSeparator{newline}{\newline} +\DeclareCaptionLabelSeparator{widespace}{\hspace{1em plus .3em}}% obsolete, do not use! +\def\caption@lsep@default{\caption@lsep@colon} +\newcommand*\DeclareCaptionJustification[2]{% bugfixed v3.0a + \global\@namedef{caption@hj@#1}{#2}} +\@onlypreamble\DeclareCaptionJustification +\newcommand*\caption@setjustification[1]{% + \@ifundefined{caption@hj@#1}% + {\PackageError{caption}{Undefined caption justification `#1'}{\caption@eh}}% + {\expandafter\let\expandafter\caption@hj\csname caption@hj@#1\endcsname}} +\newcommand\caption@centerfirst{% + \edef\caption@normaladjust{% + \leftskip\the\leftskip + \rightskip\the\rightskip + \parfillskip\the\parfillskip\relax}% + \leftskip\z@\@plus -1fil% + \rightskip\z@\@plus 1fil% + \parfillskip\z@skip + \noindent\hskip\z@\@plus 2fil% + \@setpar{\@@par\@restorepar\caption@normaladjust}} +\newcommand\caption@centerlast{% + \leftskip\z@\@plus 1fil% + \rightskip\z@\@plus -1fil% + \parfillskip\z@\@plus 2fil\relax} +\DeclareCaptionJustification{justified}{} +\DeclareCaptionJustification{centering}{\centering} +\DeclareCaptionJustification{centerfirst}{\caption@centerfirst} +\DeclareCaptionJustification{centerlast}{\caption@centerlast} +\DeclareCaptionJustification{raggedleft}{\raggedleft} +\DeclareCaptionJustification{raggedright}{\raggedright} +\def\caption@hj@default{\caption@hj@justified} +\DeclareCaptionJustification{Centering}{% + \caption@ragged\Centering\centering} +\DeclareCaptionJustification{RaggedLeft}{% + \caption@ragged\RaggedLeft\raggedleft} +\DeclareCaptionJustification{RaggedRight}{% + \caption@ragged\RaggedRight\raggedright} +\newcommand*\caption@ragged[2]{% + \@ifundefined{caption\string#1}{% + \PackageWarning{caption}{% + Cannot locate the `ragged2e' package, therefore\MessageBreak + substituting \string#2 for \string#1\MessageBreak}% + \global\@namedef{caption\string#1}}{}% + #2} +\AtBeginDocument{\IfFileExists{ragged2e.sty}{% + \RequirePackage{ragged2e}\let\caption@ragged\@firstoftwo}{}} +\newcommand\DeclareCaptionFont[2]{% bugfixed v3.0a + \define@key{caption@fnt}{#1}[]{\g@addto@macro\caption@tempa{#2}}} +\@onlypreamble\DeclareCaptionFont +\newcommand*\caption@setfont[2]{% + \let\caption@tempa\@empty + \begingroup + \setkeys{caption@fnt}{#2}% + \endgroup + \expandafter\let\csname caption#1\endcsname\caption@tempa} +\DeclareCaptionFont{default}{} +\DeclareCaptionFont{scriptsize}{\scriptsize} +\DeclareCaptionFont{footnotesize}{\footnotesize} +\DeclareCaptionFont{small}{\small} +\DeclareCaptionFont{normalsize}{\normalsize} +\DeclareCaptionFont{large}{\large} +\DeclareCaptionFont{Large}{\Large} +\DeclareCaptionFont{up}{\upshape} +\DeclareCaptionFont{it}{\itshape} +\DeclareCaptionFont{sl}{\slshape} +\DeclareCaptionFont{sc}{\scshape} +\DeclareCaptionFont{md}{\mdseries} +\DeclareCaptionFont{bf}{\bfseries} +\DeclareCaptionFont{rm}{\rmfamily} +\DeclareCaptionFont{sf}{\sffamily} +\DeclareCaptionFont{tt}{\ttfamily} +\newcommand*\caption@setposition[1]{% improved v3.0a + \caption@ifinlist{#1}{t,top,above}{% + \let\caption@position\@firstoftwo + }{\caption@ifinlist{#1}{b,bottom,below,default}{% + \let\caption@position\@secondoftwo + }{\caption@ifinlist{#1}{a,auto}{% + \let\caption@position\@undefined + }{% + \PackageError{caption}{Undefined caption position `#1'}{\caption@eh}% + }}}} +\def\captionsetup{\@ifnextchar[\caption@setuptype\caption@setup} +\def\caption@setuptype[#1]#2{% bugfixed v3.0a + \@ifundefined{caption@typ@#1}% + {\@namedef{caption@typ@#1}{#2}}% + {\expandafter\l@addto@macro\csname caption@typ@#1\endcsname{,#2}}} +\def\caption@setup{\setkeys{caption}} +\def\caption@esetup#1{% + \edef\caption@tempa{\noexpand\caption@setup{#1}}% + \caption@tempa} +\def\caption@settype#1{% + \@ifundefined{caption@typ@#1}{}{% + \caption@esetup{\csname caption@typ@#1\endcsname}}}% +\let\caption@setfloattype\caption@settype% new v3.0a +\newcommand*\clearcaptionsetup[1]{\@nameundef{caption@typ@#1}} +\newcommand*\showcaptionsetup[2][]{% + \def\caption@tempa{#1}% + \ifx\caption@tempa\@empty + \def\caption@tempa{Caption\space}% + \else + \def\caption@tempa{#1 Caption\space}% + \fi + \GenericWarning{\caption@tempa}{% + \caption@tempa Info: KV list on `#2'\MessageBreak + Data: (% + \@ifundefined{caption@typ@#2}{% + % Empty -- print nothing. + }{% + \@nameuse{caption@typ@#2}% + }% + )}} +\newcommand\caption@beginhook{} +\newcommand\caption@endhook{} +\newcommand\AtBeginCaption{\l@addto@macro\caption@beginhook} +\newcommand\AtEndCaption{\l@addto@macro\caption@endhook} +\newcommand\DeclareCaptionOption{% + \@ifstar{\caption@declareoption\AtEndOfPackage}{\caption@declareoption\@gobble}} +\newcommand*\caption@declareoption[2]{% + #1{\undefine@key{caption}{#2}}\define@key{caption}{#2}} +\@onlypreamble\DeclareCaptionOption +\@onlypreamble\caption@declareoption +\DeclareCaptionOption{default}[]{% + \caption@setup{style=default,position=default,aboveskip=10pt,belowskip=0pt}} +\DeclareCaptionOption{style}{\caption@setstyle{#1}} +\DeclareCaptionOption{format}{\caption@setformat{#1}} +\DeclareCaptionOption{labelformat}{\caption@setlabelformat{#1}} +\DeclareCaptionOption{labelsep}{\caption@setlabelseparator{#1}} +\DeclareCaptionOption{labelseparator}{\caption@setlabelseparator{#1}} +\DeclareCaptionOption{justification}{\caption@setjustification{#1}} +\DeclareCaptionOption{size}{\caption@setfont{size}{#1}}% changed v3.0a +\DeclareCaptionOption{font}{\caption@setfont{font}{#1}} +\DeclareCaptionOption{labelfont}{\caption@setfont{labelfont}{#1}} +\DeclareCaptionOption{textfont}{\caption@setfont{textfont}{#1}} +\DeclareCaptionOption{margin}{\caption@setmargin{#1}} +\DeclareCaptionOption{width}{\caption@setwidth{#1}} +\DeclareCaptionOption{indent}[\leftmargini]{\setlength\captionindent{#1}} +\DeclareCaptionOption{indention}[\leftmargini]{\setlength\captionindent{#1}} +\DeclareCaptionOption{parindent}[\parindent]{\setlength\captionparindent{#1}}% changed v3.0b +\DeclareCaptionOption{hangindent}[0pt]{\setlength\captionhangindent{#1}}% changed v3.0b +\DeclareCaptionOption{parskip}[5pt]{\AtBeginCaption{\setlength\parskip{#1}}} +\DeclareCaptionOption{singlelinecheck}[1]{\caption@setbool{slc}{#1}} +\DeclareCaptionOption{aboveskip}{\setlength\abovecaptionskip{#1}} +\DeclareCaptionOption{belowskip}{\setlength\belowcaptionskip{#1}} +\DeclareCaptionOption{position}{\caption@setposition{#1}} +\DeclareCaptionOption{listof}{\caption@setbool{lof}{#1}}% new v3.0b +\DeclareCaptionOption{debug}{\def\caption@debug{#1}} +\captionsetup{style=default,position=default,listof=1,debug=0} +\newcommand\caption@fixposition{% + \ifx\caption@position\@undefined + \caption@autoposition + \fi} +\newcommand\caption@autoposition{% bugfixed v3.0a + \ifvmode + \ifodd\caption@debug\relax + \edef\caption@tempa{\the\prevdepth}% + \PackageInfo{caption}{\protect\prevdepth=\caption@tempa}% + \fi + \ifdim\prevdepth>-\p@ + \let\caption@position\@secondoftwo + \else + \let\caption@position\@firstoftwo + \fi + \else + \ifodd\caption@debug\relax + \PackageInfo{caption}{no \protect\prevdepth}% + \fi + \let\caption@position\@secondoftwo + \fi} +\newcommand\caption@iftop{% bugfixed v3.0a + \ifx\caption@position\@firstoftwo + \expandafter\@firstoftwo + \else + \expandafter\@secondoftwo + \fi} +\newcommand\caption@make[2]{% + \caption@@make{\caption@lfmt{#1}{#2}}} +\newcommand\caption@@make[2]{% + \caption@beginhook + \caption@calcmargin + \advance\captionmargin by \captionindent + \advance\captionwidth by -\captionindent + \hskip\captionmargin + \vbox{\hsize=\captionwidth + \ifdim\captionindent=\z@\else + \hskip-\captionindent + \fi + \caption@ifslc{% + \ifx\caption@sls\@empty\else + \caption@beginslc + \sbox\@tempboxa{\caption@@@make{#1}{#2}}% + \ifdim\wd\@tempboxa >\hsize + \caption@endslc + \else + \caption@endslc + \caption@esetup\caption@sls + \fi + \fi}{}% + \captionsize\captionfont\strut + \caption@@@make{#1}{#2}}% + \caption@endhook + \global\caption@starfalse} +\newcommand\caption@calcmargin{% + \ifcaption@width + \captionmargin\hsize + \advance\captionmargin by -\captionwidth + \divide\captionmargin by 2 + \else + \captionwidth\hsize + \advance\captionwidth by -2\captionmargin + \fi + \ifodd\caption@debug\relax + \PackageInfo{caption}{\protect\hsize=\the\hsize, + \protect\margin=\the\captionmargin, + \protect\width=\the\captionwidth}% + \fi} +\newcommand\caption@beginslc{% + \begingroup + \let\label\@gobble\let\@footnotetext\@gobble + \def\stepcounter##1{\advance\csname c@##1\endcsname\@ne\relax}} +\newcommand\caption@endslc{% + \endgroup} +\newcommand\caption@@@make[2]{% + \ifcaption@star + \let\caption@lfmt\@gobbletwo + \let\caption@lsep\relax + \fi + \def\caption@tempa{#2}% + \def\caption@tempb{\ignorespaces}% + \ifx\caption@tempa\caption@tempb + \let\caption@tempa\@empty + \fi + \ifx\caption@tempa\@empty + \let\caption@lsep\relax + \fi + \def\caption@@par{% + \parindent\captionparindent\hangindent\captionhangindent}% + \@setpar{\@@par\caption@@par}\caption@@par + \caption@hj\captionsize\captionfont + \caption@fmt{{\captionlabelfont#1}}% + {{\captionlabelfont\caption@lsep}}% + {{\captiontextfont\nobreak\hskip\z@skip#2\par}}} +\DeclareCaptionOption{config}[caption]{% + \InputIfFileExists{#1.cfg}{\typeout{*** Local configuration file + #1.cfg used ***}}% + {\PackageWarning{caption}{Configuration + file #1.cfg not found}}} +\DeclareCaptionOption*{figureposition}{\captionsetup[figure]{position=#1}}% new v3.0a +\DeclareCaptionOption*{tableposition}{\captionsetup[table]{position=#1}}% new v3.0a +\DeclareCaptionOption*{normal}[]{\caption@setformat{normal}} +\DeclareCaptionOption*{isu}[]{\caption@setformat{hang}} +\DeclareCaptionOption*{hang}[]{\caption@setformat{hang}} +\DeclareCaptionOption*{center}[]{\caption@setjustification{centering}} +\DeclareCaptionOption*{anne}[]{\caption@setjustification{centerlast}} +\DeclareCaptionOption*{centerlast}[]{\caption@setjustification{centerlast}} +\DeclareCaptionOption*{nooneline}[]{\caption@setbool{slc}{0}} +\DeclareCaptionOption*{scriptsize}[]{\def\captionfont{\scriptsize}} +\DeclareCaptionOption*{footnotesize}[]{\def\captionfont{\footnotesize}} +\DeclareCaptionOption*{small}[]{\def\captionfont{\small}} +\DeclareCaptionOption*{normalsize}[]{\def\captionfont{\normalsize}} +\DeclareCaptionOption*{large}[]{\def\captionfont{\large}} +\DeclareCaptionOption*{Large}[]{\def\captionfont{\Large}} +\DeclareCaptionOption*{up}[]{\l@addto@macro\captionlabelfont\upshape} +\DeclareCaptionOption*{it}[]{\l@addto@macro\captionlabelfont\itshape} +\DeclareCaptionOption*{sl}[]{\l@addto@macro\captionlabelfont\slshape} +\DeclareCaptionOption*{sc}[]{\l@addto@macro\captionlabelfont\scshape} +\DeclareCaptionOption*{md}[]{\l@addto@macro\captionlabelfont\mdseries} +\DeclareCaptionOption*{bf}[]{\l@addto@macro\captionlabelfont\bfseries} +\DeclareCaptionOption*{rm}[]{\l@addto@macro\captionlabelfont\rmfamily} +\DeclareCaptionOption*{sf}[]{\l@addto@macro\captionlabelfont\sffamily} +\DeclareCaptionOption*{tt}[]{\l@addto@macro\captionlabelfont\ttfamily} +\caption@setbool{ruled}{0} +\DeclareCaptionOption*{ruled}[]{\caption@setbool{ruled}{1}} +\newcommand*\DeclareCaptionPackage[1]{% + \caption@setbool{pkt@#1}{1}% + \DeclareCaptionOption*{#1}{\caption@setbool{pkt@#1}{##1}}} +\DeclareCaptionPackage{caption} +\DeclareCaptionPackage{float} +\DeclareCaptionPackage{listings} +\DeclareCaptionPackage{longtable} +\DeclareCaptionPackage{rotating} +\DeclareCaptionPackage{sidecap} +\DeclareCaptionPackage{supertabular} +\let\DeclareCaptionPackage\@undefined +\def\ProcessOptionsWithKV#1{% bugfixed v3.0a + \let\@tempc\relax + \let\caption@tempa\@empty + \@for\CurrentOption:=\@classoptionslist\do{% + \@ifundefined{KV@#1@\CurrentOption}% + {}% + {% + \edef\caption@tempa{\caption@tempa,\CurrentOption,}% + \@expandtwoargs\@removeelement\CurrentOption + \@unusedoptionlist\@unusedoptionlist + }% + }% + \edef\caption@tempa{% + \noexpand\setkeys{#1}{% + \caption@tempa\@ptionlist{\@currname.\@currext}% + }% + }% + \caption@tempa + \let\CurrentOption\@empty + \AtEndOfPackage{\let\@unprocessedoptions\relax}} +\ProcessOptionsWithKV{caption} +\let\ProcessOptionsWithKV\@undefined +\def\captionof{\@ifstar{\caption@of{\caption*}}{\caption@of\caption}} +\newcommand*\caption@of[2]{\def\@captype{#2}#1} +\providecommand\ContinuedFloat{% + \ifx\@captype\@undefined + \@latex@error{\noexpand\ContinuedFloat outside float}\@ehd + \else + \addtocounter{\@captype}{\m@ne}% + \fi}% +\newcommand*\caption@floatname[1]{\@nameuse{#1name}} +\newcommand*\caption@thefloat[1]{\@nameuse{the#1}} +\def\caption@letfloattype#1{% + \def\caption@setfloattype##1{% + \caption@settype{##1}\caption@settype{#1}}} +\newcommand*\caption@begin[1]{% + \begingroup + \caption@setfloattype{#1}% + \@namedef{fnum@#1}{% + \caption@lfmt{\caption@floatname{#1}}{\caption@thefloat{#1}}}% + \caption@fixposition + \global\let\caption@fixedposition\caption@position + \caption@@begin{#1}} +\newcommand*\caption@beginex[1]{% + \caption@begin{#1}% + \caption@preparelof} +\newcommand*\caption@end{% + \caption@@end + \endgroup + \let\caption@position\caption@fixedposition} +\let\caption@@begin\@gobble% new v3.0a +\let\caption@@end\@empty% new v3.0a +\newcommand*\caption@preparelof[1]{% changed v3.0b + \caption@ifbool{lof}% + {\def\caption@tempa{#1}}% + {\let\caption@tempa\@empty}% + \ifx\caption@tempa\@empty + \def\addcontentsline##1##2##3{}% + \fi} +\caption@ifpkt@caption{ + \renewcommand\@makecaption[2]{% + \caption@iftop{\vskip\belowcaptionskip}{\vskip\abovecaptionskip}% + \ifnum\caption@debug>1 % + \llap{$\caption@iftop\downarrow\uparrow$ }% + \fi + \caption@@make{#1}{#2}% + \caption@iftop{\vskip\abovecaptionskip}{\vskip\belowcaptionskip}} + \AtBeginDocument{% + \@ifundefined{cc@caption}{% + \def\caption@caption#1{% + \@ifstar{\global\caption@startrue\@ifnextchar[{#1}{#1[]}}{#1}}% + \let\caption@old\caption + \def\caption{\caption@caption\caption@old}% + \let\caption@@old\@caption + \long\def\@caption#1[#2]#3{% + \caption@beginex{#1}{#2}% + \caption@@old{#1}[{#2}]{#3}% + \caption@end}% + }{% + \PackageInfo{caption}{captcont package v2.0 detected}% + \def\caption@caption#1{#1}% added v3.0c + }% + }}{} +\AtEndOfPackage{\let\caption@ifpkt@caption\@undefined}% bugfixed v3.0a +\newcommand*\caption@ifpackage[2]{% + \let\next\@gobble + \caption@ifpkt@caption{% + \caption@ifbool{pkt@#1}{% + \@ifundefined{#2}% + {\let\next\AtBeginDocument}% + {\let\next\@firstofone}}{}% + \ifodd\caption@debug\relax + \edef\caption@tempa{% + \caption@ifbool{pkt@#1}{% + \@ifundefined{#2}{AtBeginDocument}{firstofone}% + }{gobble}}% + \PackageInfo{caption}{#1 = \caption@ifbool{pkt@#1}{1}{0} % + (\@ifundefined{#2}{not }{}loaded -> \caption@tempa)}% + \fi + }{}% + \@nameundef{caption@ifpkt@#1}% bugfixed v3.0a + \next} +\AtEndOfPackage{\let\caption@ifpackage\@undefined} +\def\caption@setfloatposition{% + \caption@setposition{\@fs@iftopcapt t\else b\fi}} +\caption@ifpackage{float}{float@caption}{% + \ifx\float@caption\relax + \else + \PackageInfo{caption}{float package v1.2 (or newer) detected}% + \let\caption@of@float\@gobble + \renewcommand*\caption@of[2]{% + \@ifundefined{fst@#2}{}{% + \let\caption@of@float\@firstofone + \@nameuse{fst@#2}\@float@setevery{#2}}% + \def\@captype{#2}#1}% + \renewcommand*\caption@floatname[1]{% + \@nameuse{\@ifundefined{fname@#1}{#1name}{fname@#1}}}% + \let\caption@@float\float@caption + \long\def\float@caption#1[#2]#3{% + \caption@beginex{#1}{#2}% + \let\@fs@capt\caption@@make + \caption@@float{#1}[{#2}]{#3}% + \caption@of@float{% + \def\caption@@make##1##2{\unvbox\@floatcapt}% + \@makecaption{}{}}% + \caption@end}% + \renewcommand*\caption@setfloattype[1]{% improved v3.0a + \caption@fixfloat@c{#1}% + \expandafter\ifx\csname @float@c@#1\endcsname\float@caption + \expandafter\let\expandafter\caption@fst\csname fst@#1\endcsname + \edef\caption@fst{\noexpand\string\expandafter\noexpand\caption@fst}% + \edef\caption@fst{\noexpand\@gobblefour\caption@fst}% + \@ifundefined{caption@sty@\caption@fst}{}{\caption@setstyle\caption@fst}% + \caption@setfloatposition% changed v3.0b + \fi + \caption@settype{#1}}% + \let\caption@float\caption + \def\caption{% + \ifx\@captype\@undefined + \@latex@error{\noexpand\caption outside float}\@ehd + \expandafter\@gobble + \else + \caption@fixfloat@c\@captype + \fi + \caption@float}% + \def\caption@fixfloat@c#1{% + \expandafter\let\expandafter\caption@tempa\csname @float@c@#1\endcsname + \ifx\caption@tempa\relax + \else\ifx\caption@tempa\float@caption + \else\ifx\caption@tempa\@caption + \else\ifx\caption@tempa\caption@@float + \ifodd\caption@debug\relax + \PackageInfo{caption}{\protect\@float@c@#1\space := \protect\float@caption}% + \fi + \expandafter\let\csname @float@c@#1\endcsname\float@caption + \else + \ifodd\caption@debug\relax + \PackageInfo{caption}{\protect\@float@c@#1\space := \protect\@caption}% + \fi + \expandafter\let\csname @float@c@#1\endcsname\@caption + \fi\fi\fi\fi}% + \fi} +\caption@ifbool{ruled}{}{% + \DeclareCaptionStyle{ruled}{labelfont=bf,labelsep=space}} +\let\caption@ifruled\@undefined +\caption@ifpackage{listings}{lst@MakeCaption}{% + \ifx\lst@MakeCaption\relax + \else + \PackageInfo{caption}{listings package v1.2 (or newer) detected}% + \let\caption@lst@MakeCaption\lst@MakeCaption + \def\lst@MakeCaption#1{% + \let\caption@setfloattype\caption@settype + \def\caption@autoposition{\caption@setposition{#1}}% + \caption@begin{lstlisting}% + \caption@lst@MakeCaption{#1}% + \caption@end}% + \fi} +\caption@ifpackage{longtable}{LT@makecaption}{% + \ifx\LT@makecaption\relax + \else + \PackageInfo{caption}{longtable package v3.15 (or newer) detected}% + \def\LT@makecaption#1#2#3{% + \LT@mcol\LT@cols c{\hbox to\z@{\hss\parbox[t]\linewidth{% + \caption@letfloattype{longtable}% + \caption@begin{table}% + \ifdim\LTcapwidth=4in \else + \caption@setwidth\LTcapwidth + \fi + \caption@startrue#1\caption@starfalse + \caption@@make{#2}{#3}% + \endgraf\vskip\baselineskip + \caption@end}% + \hss}}}% + \fi} +\caption@ifpackage{rotating}{@rotcaption}{% + \ifx\@rotcaption\relax + \else + \PackageInfo{caption}{rotating package v2.0 (or newer) detected}% + \let\caption@rot\rotcaption + \def\rotcaption{\caption@caption\caption@rot}% + \let\caption@@rot\@rotcaption + \long\def\@rotcaption#1[#2]#3{% + \caption@beginex{#1}{#2}% + \caption@@rot{#1}[{#2}]{#3}% + \caption@end}% + \long\def\@makerotcaption#1#2{% + \rotatebox{90}{% + \begin{minipage}{.8\textheight}% + \caption@@make{#1}{#2}% + \end{minipage}% + }\par + \hspace{12pt}}% + \fi} +\caption@ifpackage{sidecap}{endSC@FLOAT}{% + \ifx\endSC@FLOAT\relax + \else + \PackageInfo{caption}{sidecap package v1.4d (or newer) detected}% + \let\SC@caption=\caption + \let\caption@SC@zfloat\SC@zfloat + \def\SC@zfloat#1#2#3[#4]{% + \caption@SC@zfloat{#1}{#2}{#3}[#4]% + \global\let\SC@CAPsetup\@empty + \renewcommand\captionsetup[1]{\g@addto@macro\SC@CAPsetup{,##1}}% + \let\caption@old\caption + \def\caption{\caption@caption\caption@old}% + }% + \let\caption@endSC@FLOAT\endSC@FLOAT + \def\endSC@FLOAT{% + \caption@setmargin\z@ + \@ifundefined{SC@justify}{}{% + \ifx\SC@justify\@empty\else + \let\caption@hj\SC@justify + \let\SC@justify\@empty + \fi}% + \caption@esetup\SC@CAPsetup + \caption@letfloattype{SC\@captype}% + \caption@endSC@FLOAT}% + \fi} +\def\caption@setSTposition{% + \caption@setposition{\if@topcaption t\else b\fi}} +\caption@ifpackage{supertabular}{ST@caption}{% + \ifx\ST@caption\relax + \else + \PackageInfo{caption}{supertabular package detected}% + \let\caption@ST\ST@caption + \long\def\ST@caption#1[#2]#3{\par% bugfixed v3.0a + \caption@letfloattype{supertabular}% + \let\caption@fixposition\caption@setSTposition + \caption@beginex{#1}{#2}% + \addcontentsline{\csname ext@#1\endcsname}{#1}% + {\protect\numberline{% + \csname the#1\endcsname}{\ignorespaces #2}}% + \@parboxrestore + \normalsize + \@makecaption{\csname fnum@#1\endcsname}{\ignorespaces #3}\par + \caption@end}% + \fi} +\AtBeginDocument{\let\scr@caption\caption} +\endinput +%% +%% End of file `caption.sty'. Added: trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex (rev 0) +++ trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex 2007-09-09 09:29:53 UTC (rev 1084) @@ -0,0 +1,199 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%GRASS PROMOTION FLYER % +%(c) 2007 GRASS PROMOTION TEAM % +%GNU Free Documentation License % +%Version 1.2 % +%Needs leaflet.cls % +%www.ctan.org/tex-archive/macros/latex/contrib/leaflet/% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%Sometimes printing engines need the 2nd side upside down +%in this case, use tumble (which is default) instead of notumble +%If this causes problems, use notumble +%If you need a foldmark, delete nofoldmark +\documentclass[notumble,a4paper,10pt,nofoldmark]{leaflet} +\usepackage{helvet,courier,xcolor} +\usepackage[utf8]{inputenc} + +% Set Helvetica as the default font +\renewcommand*\familydefault\sfdefault +% Let LaTeX knows that pictures are found in ./pix +\graphicspath{{pix/}} + +% Setting up things for the captions +\usepackage{caption}[2004/07/16] +\captionsetup{% + font={small,it},% + labelformat=empty,% Leaves out label: ``Figure 1'' + labelsep=none,% + aboveskip=0pt% +} +% Defining a new 'figure' environment for the document +\newenvironment{myfig}[1][0pt plus 1.5ex minus .5ex]{\par\vspace*{#1}\begin{minipage}{\textwidth}\centering}{\end{minipage}} + +% Defining the GRASS homepage +\newcommand{\GRASSurl}{\url{http://grass.itc.it}} + +% Define a color for the URIs +\definecolor{darkblue}{RGB}{0,0,88} + +\usepackage{hyperref} +% Setting up some document info +\hypersetup{% + colorlinks=true,% + urlcolor=darkblue,% Redefine this color to change URIs color + pdfauthor={GRASS Community},% + pdftitle={GRASS GIS: U?innost Svodody \& Transparentnosti},% + pdfsubject={GRASS propaga?n? let?k GRASS},% + breaklinks=true,% + plainpages=false% +} + +% Title page stuff +\title{\textbf{\huge GRASS GIS}\\% +\textsl{U?innost Svodody \& Transparentnosti}} +\author{Komunita GRASSu} +\date{\includegraphics[width=\textwidth]{grasslogo_vector}\\[2ex] +\large\GRASSurl} + +\begin{document} + +\maketitle +\thispagestyle{empty}% Necessary to leave out the page number on the first page + +\newpage + +\section{Co je GRASS} + +GRASS (Geographic Resources Analysis Support System) je svobodn?/Open Source software ur?en? pro prostorov? anal?zy. Obsahuje v?ce ne? 350 modul? pro zpracov?n? 2D/3D vektorov?ch a rastrov?ch dat. Nab?z? ?adu rozhran? k dal??m program?m v dan? oblasti jako je geostatistika, datab?ze, mapov? slu?by a dokonce i k dal??m GIS aplikac?m. Je nejrozs?hlej??m Open Source GISem. M??e slou?it jako Desktop GIS ?i jako p?te? kompletn? GIS infrastrukturu. + +\section{Kde je GRASS pou??v?n} + +GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? spr?v? po cel?m sv?t?. GRASS pokytuje v mnoha p?ipadech velk? potenci?l pro ?e?en? geoprostorov?ch ?loh. + +\section{Historie} + +GRASS byl p?vodn? vyv?jen od po??tku 80-t?ch let agenturou US Army Construction Engineering Research Laboratories (USA-CERL) a byl poskytnut jako public domain software. V okam?iku kdy USA-CERL upustil od v?voje, vzniknul mezin?rodn? t?m v?voj??? kter? d?l software vyv?j?. Od roku 1999 je GRASS uvoln?n jako free software pod licenc? GNU General Public Licence. +\begin{myfig}[1.5ex] +\includegraphics[width=0.7\textwidth]{visibility} +\captionof{figure}{Anal?za viditelnost provedena v GRASSu} +\end{myfig} + +\section{Filozofie Open Source} + +Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do zdrovov?ch k?du a struktury programu, obrovskou m?ru transparentnosti. U?ivatel m??e roz???it program dle sv?ch pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez nutnosti zdrovov?ho k?du GRASSu. + +\section{Technick? data} + +\subsection{Licence} + +V?eobecn? ve?ejn? licence GNU (GNU General Public License, Free Software Foundation) + +\subsection{Podporovan? platformy} + +GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? syst?my podporuj?c? Posix, MS-Windows a MacOS X. + +\subsection{Design} + +\begin{itemize} +\item Modul?rn? +\item Obsahuje v?ce ne? 350 modul? +\end{itemize} + +\subsection{Programovac? jazyky} + +\begin{itemize} +\item ANSI C +\item Rozhran? GRASS- SWIG +\item Python pro WebGIS aplikace +\item Verze pro Javu: JGRASS +\end{itemize} + +\subsection{Mo?nosti spr?vy dat} + +\begin{itemize} +\item Zpracov?n? rasterov?ch / vektorov?ch / voxel dat +\item Modelov?n? 2D / 3D rastrov?ch / vektorov?ch dat +\item Zpracov?n? obrazov?ch dat +\item Vektorov? topologie / S??ov? anal?zy +\item Geostatistika (rozhran? pro R) +\end{itemize} + +\begin{myfig}[1ex] +\includegraphics[width=0.7\textwidth]{trento3d} +\captionof{figure}{3D pohled na Trento, It?lie} +\end{myfig} + +\section{Podporovan? datov? form?ty} + +GRASS podporuje t?m?? v?echny dob?e zn?m? GIS datov? form?ty d?ky knihovn? GDAL/OGR. Nav?c podporuje Open GIS Consortium's Simple Features. + +\subsection{Vektorov? datov? form?ty} +ASCII, ARC/INFO ungenerate, ARC/INFO E00, Arc\-View SHAPE, BIL, DLG (U.S.), DXF, DXF3D, GMT, GPS-ASCII USGS-DEM, IDRISI, MOSS, MapInfo MIF, TIGER, VRML, \dots + +\subsection{Rastrov? datov? form?ty} +ASCII, ARC/GRID, E00, GIF, GMT, TIF, PNG, Vis5D, SURFER (.grd),\dots +\begin{myfig} +\includegraphics[width=0.7\textwidth]{isodist} +\captionof{figure}{V?choz? konfigurace GUI ukazuj?c? mo?nosti GRASSu pro s??ov? anal?zy} +\end{myfig} + +\subsection{Obrazov? datov? form?ty} + +CEOS (SAR, SRTM, LANDSAT7 etc.), ERDAS LAN / IMG, HDF, LANDSAT TM/MSS, NHAP aerial photos, SAR, SPOT, \dots +\begin{myfig}[1.5ex] +\includegraphics[width=0.7\textwidth]{ndvi} +\captionof{figure}{Mo?nosti GRASS ve zpracov?n? obrazov?ch dat} +\end{myfig} + +\subsection{Podpora databaz?} + +\begin{itemize} +\item PostgreSQL / PostGIS +\item MySQL +\item SQLite +\item ODBC +\item DBF +\end{itemize} + +\subsection{V?stup} + +\begin{itemize} +\item Moduly pro tvorbu mapov?ch v?stup? +\item NVIZ pro vizualizaci 2.5D a 3D dat (tvorba animac? \& pohled?) +%\item{GMT export} +%item{VRML} +\item VTK, POVray +\item WebGIS pomoc? Mapserver, Python, a pod. +\end{itemize} + +\subsection{Interoperabilita v??i dal??m GIS program?m} + +\begin{itemize} +\item Quantum GIS (Free Geodata (nejen) prohl??e?) +\item R- Language (statistika) +\item Gstat (geostatistika) +\item UMN Mapserver (webov? slu?by) +\end{itemize} + +\section{Kde naj?t dal?? informace} + +\begin{itemize} +%\begin{flushleft} +\item{Webov? str?nky projektu: \\\GRASSurl} +\item{GRASS Wiki: \\\url{http://grass.gdf.hannover.de/wiki}} +\item{Propaga?n? t?m GRASSu: \\\url{malte@perlomat.de}} +\item{Elektronick? konference GRASSu: \\\url{http://grass.itc.it/community/support.php}} +%\end{flushleft} +\end{itemize} + +\vfill +\section{OSGeo} + +GRASS je zakl?daj?c?m projektem Open Source Geospatial Foundation, kter? si klade za c?l tvorbu vysoce kvalitn?ho Open Source GIS software. Pro dal?? informace nav?tivte domovskou str?nku OSGeo: +\begin{center} +\includegraphics[width=0.8\textwidth]{OSGeo_CMYK}\\ +\url{http://www.osgeo.org} +\end{center} + +\end{document} Added: trunk/grassaddons/grassflyer/flyer1/cz/leaflet.cls =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/leaflet.cls (rev 0) +++ trunk/grassaddons/grassflyer/flyer1/cz/leaflet.cls 2007-09-09 09:29:53 UTC (rev 1084) @@ -0,0 +1,503 @@ +%% +%% This is file `leaflet.cls', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% leaflet.dtx (with options: `class') +%% +%% Copyright (C) 2003, 2004 +%% Rolf Niepraschk, Rolf.Niepraschk@ptb.de +%% Hubert Gaesslein, HubertJG@open.mind.de +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% of this license or (at your option) any later version. +%% The latest version of this license is in +%% http://www.latex-project.org/lppl.txt +%% and version 1.3 or later is part of all distributions of LaTeX +%% version 2003/12/01 or later. +%% +%% This work has the LPPL maintenance status "author-maintained". +%% +\NeedsTeXFormat{LaTeX2e}[1999/12/01] +\ProvidesClass{leaflet} + [2004/12/22 v1.0d LaTeX document class (JS,WaS,RN,HjG)] +\let\LL@shipout\shipout \let\LL@outputpage\@outputpage +\let\LL@begindvi\@begindvi \let\LL@@end\@@end +\@ifundefined{iflandscape}{\newif\iflandscape}{}% +\@ifundefined{iftumble}{\newif\iftumble}{}% +\newcommand\LL@debug@info[1]{}% +\DeclareOption{dvips}{\PassOptionsToPackage{\CurrentOption}{graphics}} +\DeclareOption{pdftex}{\PassOptionsToPackage{\CurrentOption}{graphics}} +\DeclareOption{vtex}{\PassOptionsToPackage{\CurrentOption}{graphics}} +\DeclareOption{dvipdfm}{\PassOptionsToPackage{\CurrentOption}{graphics}} +\DeclareOption{twoside}{\OptionNotUsed} +\DeclareOption{twocolumn}{\OptionNotUsed} +\DeclareOption{landscape}{\landscapetrue} +\DeclareOption{portrait}{\landscapefalse} +\DeclareOption{debug}{\let\LL@debug@info\typeout} +\DeclareOption{nospecialtricks}{% + \AtEndOfClass{% + \ifLL@combine + \let\immediate\@@@immediate\let\write\@@@write + \let\openout\@@@openout\let\closeout\@@@closeout + \let\special\@@@special\let\@@@exec@outs\relax + \fi}} +\newcommand*\LL@setPaperSize{} +\DeclareOption{a3paper}{\def\LL@setPaperSize{% + \paperwidth=420mm\paperheight=297mm\relax}}% +\@ifdefinable\ifLL@combine{\newif\ifLL@combine} +\DeclareOption{combine}{\LL@combinetrue} +\DeclareOption{nocombine}{\LL@combinefalse} +\newcommand*\LL@selectOutput{} +\DeclareOption{frontside}{\def\LL@selectOutput#1#2{#1}} +\DeclareOption{backside}{\def\LL@selectOutput#1#2{#2}} +\DeclareOption{bothsides}{\def\LL@selectOutput#1#2{#1#2}} +\DeclareOption{tumble}{\tumbletrue} +\DeclareOption{notumble}{\tumblefalse} +\newcommand*\LL@foldmark{} +\DeclareOption{foldmark}{% + \def\LL@foldmark{% + \begingroup + \linethickness{\LenToUnit{\foldmarkrule}}% + \setlength\@tempdima{\paperheight-\LL@tmargin}% + \put(0,\LenToUnit{\@tempdima}){% + \line(0,-1){\LenToUnit{\foldmarklength}}}% + \endgroup}% +} +\DeclareOption{nofoldmark}{\def\LL@foldmark{}}% +\newcommand*\LL@toomanypages[2]{} +\DeclareOption{draft}{\PassOptionsToClass{\CurrentOption}{article}% + \AtEndOfClass{% + \def\LL@toomanypages#1#2{% + \ClassWarningNoLine{leaflet}{#1.\MessageBreak#2}}% + }% +} +\DeclareOption{final}{\PassOptionsToClass{\CurrentOption}{article}% + \AtEndOfClass{% + \ifLL@combine + \def\LL@toomanypages#1#2{% + \ClassError{leaflet}{#1}{#2.}}% + \else + \def\LL@toomanypages#1#2{% + \ClassWarningNoLine{leaflet}{#1.\MessageBreak#2}}% + \fi + }% +} +\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} +\PassOptionsToClass{landscape,a4paper}{article} +\ExecuteOptions{tumble,foldmark,bothsides,combine,landscape,final} +\ProcessOptions\relax +\ifLL@combine + \newcommand*\LL@rotate@I{}\newcommand*\LL@rotate@II{}% + \iflandscape + \def\LL@rotate@I#1{#1}% + \iftumble + \def\LL@rotate@II#1{\rotatebox[origin=c]{180}{#1}}% + \else + \def\LL@rotate@II#1{#1}% + \fi + \else + \def\LL@rotate@I#1{\rotatebox[origin=c]{90}{#1}}% + \iftumble + \def\LL@rotate@II#1{\rotatebox[origin=c]{270}{#1}}% + \else + \def\LL@rotate@II#1{\rotatebox[origin=c]{90}{#1}}% + \fi + \fi + \def\@@@pending@outs{}\let\@@@immediate\immediate + \let\@@@write\write \let\@@@special\special + \let\@@@openout\openout \let\@@@closeout\closeout + \def\immediate{% + \let\write\immediate@write% + \let\openout\immediate@openout% + \let\closeout\immediate@closeout% + \let\special\immediate@special}% + \def\reset@immediate{% + \let\write\pending@write% + \let\openout\pending@openout% + \let\closeout\pending@closeout% + \let\special\@@@special}% + \long\def\pending@write#1#{\pending@@write{#1}} + \def\immediate@write{% + \reset@immediate\@@@immediate\@@@write}% + \def\immediate@openout{% + \reset@immediate\@@@immediate\@@@openout}% + \def\immediate@closeout{% + \reset@immediate\@@@immediate\@@@closeout}% + \def\immediate@special{% + \reset@immediate\@@@immediate\@@@special}% + \let\write\pending@write + \let\openout\pending@openout + \let\closeout\pending@closeout + \def\@dummy@whatsit{\special{}} + \begingroup\@ifundefined{pdfoutput}% + {\endgroup} + {\endgroup + \ifnum\pdfoutput>\z@\def\@dummy@whatsit{\pdfliteral{}}\fi} + \begingroup\expandafter\expandafter\expandafter\endgroup + \expandafter\ifx\csname eTeXversion\endcsname\relax + %%% Test is from Markus Kohm (d.c.t.t, 29 Jun 2004) + \ClassWarningNoLine{leaflet}{% + *************************************\MessageBreak + * It's very recommended to use eTeX \MessageBreak + * with this package! \MessageBreak + *************************************}% + \long\def\pending@@write#1#2{% + \@dummy@whatsit + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@write\number#1{#2},}}% + \def\pending@openout#1 {% + \@dummy@whatsit + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@openout\number#1,}}% + \def\pending@closeout#1{% + \@dummy@whatsit + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@closeout\number#1,}}% + \newcommand*\@@@exec@outs{% + \@@@pending@outs\gdef\@@@pending@outs{}% + \LL@debug@info{% + >>> execute the output commands of the current page <<<}}% + \else + \RequirePackage{etex} + \globmarks\@@@out@mark + \newcounter{@@total@outs}\setcounter{@@total@outs}{0} + \newcounter{@@last@exec}\setcounter{@@last@exec}{0} + \long\def\pending@@write#1#2{% + \global\advance\c@@@total@outs\@ne% + \marks\@@@out@mark{\the\c@@@total@outs}% + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@write\number#1{#2},}}% +\def\pending@openout#1 {% + \global\advance\c@@@total@outs\@ne% + \marks\@@@out@mark{\the\c@@@total@outs}% + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@openout\number#1,}}% +\def\pending@closeout#1{% + \global\advance\c@@@total@outs\@ne% + \marks\@@@out@mark{\the\c@@@total@outs}% + \g@addto@macro\@@@pending@outs{\@@@immediate\@@@closeout\number#1,}}% + \newcommand*\@@@exec@outs{% + \begingroup + \@tempcntb\c@@@total@outs\advance\@tempcntb-\c@@@last@exec% + \edef\reserved@a{\botmarks\@@@out@mark}% + \ifx\reserved@a\@empty\@tempcnta\z@\else\@tempcnta\reserved@a\fi% + \LL@debug@info{PENDING-OUTS:\the\@tempcntb\space\space + TOTAL-OUTS:\the\c@@@total@outs\space\space + LAST-EXEC:\the\c@@@last@exec\space\space + TOPMARK:\topmarks\@@@out@mark\space\space + FIRSTMARK:\firstmarks\@@@out@mark\space\space + BOTMARK:\botmarks\@@@out@mark}% + \advance\@tempcnta-\c@@@total@outs \advance\@tempcntb\@tempcnta + \@tempcnta-\@tempcnta% + \ifnum\@tempcnta>\z@ + \LL@debug@info{% + >>> resave \the\@tempcnta\space output command(s). + Too early to execute! <<<}% + \fi + \@tempcnta\z@ \def\reserved@b{}% + \@for\reserved@a :=\@@@pending@outs\do{% + \ifx\reserved@a\@empty\else + \ifnum\@tempcnta<\@tempcntb% + \reserved@a% execute output's related to the current page box. + \global\advance\c@@@last@exec\@ne + \LL@debug@info{>>> execute output command number + \the\c@@@last@exec\space<<<}% + \else + \expandafter\g@addto@macro\expandafter\reserved@b\expandafter{% + \reserved@a,}% + \fi + \advance\@tempcnta\@ne% + \fi}% + \expandafter\@temptokena\expandafter{\reserved@b}% + \xdef\@@@pending@outs{\the\@temptokena}% + \endgroup}% + \fi% end of eTeX test. + \long\def\protected@write#1#2#3{% + \begingroup + \let\thepage\relax + #2% + \let\protect\@unexpandable@protect + \edef\reserved@a{\noexpand\write#1{#3}}% + \reserved@a% + \endgroup + \if@nobreak\ifvmode\nobreak\fi\fi}% + \def\shipout{\deadcycles\z@\setbox\@tempboxa=} + \let\@begindvi\@empty +\fi% end of \ifLL@combine +\LoadClass{article} +\RequirePackage{everyshi,calc,graphicx} +\newcommand*\LL@pagesize@specials[2]{} +\@ifundefined{Gin@driver}{}% +{% + \ifx\Gin@driver\@empty\else% + \filename@parse{\Gin@driver}\@tempswafalse% + \def\reserved@a{dvips}% + \ifx\filename@base\reserved@a\@tempswatrue\fi% + \def\reserved@a{dvipdfm}% + \ifx\filename@base\reserved@a\@tempswatrue\fi% + \if@tempswa% + \ClassInfo{leaflet}{Generating code for dvips}% + \def\LL@pagesize@specials#1#2{% + \@tempdima=#1\@tempdimb=#2% + \AtBeginDvi{\special{papersize=\the\@tempdima,\the\@tempdimb}}}% + \fi% + \def\reserved@a{pdftex}% + \ifx\filename@base\reserved@a + \ClassInfo{leaflet}{Generating code for pdfTeX}% + \def\LL@pagesize@specials#1#2{% + \@tempdima=#1\@tempdimb=#2% + \pdfpagewidth\@tempdima\pdfpageheight\@tempdimb}% + \fi% + \def\reserved@a{vtex}% + \ifx\filename@base\reserved@a + \ClassInfo{leaflet}{Generating code for VTeX}% + \def\LL@pagesize@specials#1#2{% + \@tempdima=#1\@tempdimb=#2% + \mediawidth\@tempdima\mediaheight\@tempdimb}% + \fi% + \fi +} +\newcommand*\LL@CmdIgnored[1]{% + \ClassWarning{leaflet}{% + `\string#1' ignored}} +\setlength{\parskip}{1ex plus 2pt} +\@listi% +\setlength{\labelwidth}{\leftmargin} +\addtolength{\labelwidth}{-\labelsep} +\pagestyle{empty} +\headheight\z@ +\headsep\z@ +\footskip\z@ +\marginparwidth\z@ +\marginparsep\z@ +\sloppy +\setcounter{secnumdepth}{0} +\renewcommand\twocolumn[1][]{\LL@CmdIgnored{\twocolumn}} +\renewcommand\onecolumn{\LL@CmdIgnored{\onecolumn}} +\renewcommand\topfraction{0.7} +\renewcommand\bottomfraction{0.7} +\setlength{\textfloatsep}{10pt plus 4pt minus 3pt} +\setlength{\parindent}{\z@} +\setlength{\leftmargini}{1.5em} +\setlength{\leftmarginii}{1.5em} +\setlength{\leftmarginiii}{1.5em} +\setlength{\leftmarginiv}{1.5em} +\setlength{\leftmarginv}{1.5em} +\setlength{\leftmarginvi}{1.5em} +\setlength{\labelsep}{.5em} +\setlength \labelwidth{\leftmargini} +\addtolength\labelwidth{-\labelsep} +\def\noparskip{\par\vspace{-\parskip}} +\let\old@small\small +\renewcommand{\small}{\old@small\let\@listi\@listI} +\let\old@footnotesize\footnotesize +\renewcommand{\footnotesize}{\old@footnotesize\let\@listi\@listI} +\newcommand{\sectfont}{\bfseries} +\renewcommand\section{\@startsection{section}{1}{\z@}% + {-3.5ex \@plus -.75ex}% + {1ex} %{1.5ex}% + {\normalfont\large\sectfont}} +\renewcommand\subsection{\@startsection{subsection}{2}{\z@}% + {-2.5ex plus -.5ex}% + {1\p@} %{1ex}% + {\normalfont\normalsize\sectfont}} +\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% + {-2.5ex plus -.5ex}% + {-1em}% + {\normalfont\normalsize\sectfont}} +\def\part{\LL@CmdIgnored{\part}\secdef\@part\@spart} +\def\@part[#1]#2{} +\def\@spart#1{} + +\renewcommand*\descriptionlabel[1]{% + \hspace\labelsep\normalfont\descfont #1} +\newcommand*\descfont{\bfseries} +\iffalse +\g@addto@macro\enumerate{\parsep2\p@\@plus2\p@\@minus\z@} +\g@addto@macro\itemize{\parsep2\p@\@plus2\p@\@minus\z@} +\g@addto@macro\description{\parsep2\p@\@plus2\p@\@minus\z@} +\else +\newcommand*\LL@listsetup{% + \parsep1ex\@plus.5ex\@minus.25ex% + \LL@debug@info{***parsep=\the\parsep}% + \itemsep\z@ + \LL@debug@info{***itemsep=\the\itemsep}% + \topsep\z@ + \LL@debug@info{***topsep=\the\topsep}% + \LL@debug@info{***partopsep=\the\partopsep}% +} +\def\enumerate{% + \ifnum \@enumdepth >\thr@@\@toodeep\else + \advance\@enumdepth\@ne + \edef\@enumctr{enum\romannumeral\the\@enumdepth}% + \expandafter + \list + \csname label\@enumctr\endcsname + {\usecounter\@enumctr + \def\makelabel##1{\hss\llap{##1}}% + %\def\makelabel##1{##1\hfill}% + %\def\makelabel##1{\hss##1}% + \LL@listsetup + }% + \fi} +\def\itemize{% + \ifnum \@itemdepth >\thr@@\@toodeep\else + \advance\@itemdepth\@ne + \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% + \expandafter + \list + \csname\@itemitem\endcsname + {% + \def\makelabel##1{\hss\llap{##1}}% + %\def\makelabel##1{##1\hfill}% + %\def\makelabel##1{\hss##1}% + \LL@listsetup + }% + \fi} +\renewenvironment{description} + {\list{}{\labelwidth\z@ \itemindent-\leftmargin + \let\makelabel\descriptionlabel + \LL@listsetup}} + {\endlist} +\fi +\newcommand*\setmargins[4]{% + \setlength\topmargin{#1}% + \edef\LL@tmargin{\the\topmargin}% + \setlength\evensidemargin{#2}% + \setlength\textheight{% + \paperheight-\topmargin-\evensidemargin% + -\headheight-\headsep-\footskip}% + \setlength\oddsidemargin{#3}% + \setlength\evensidemargin{#4}% + \setlength\textwidth{% + \paperwidth-\oddsidemargin-\evensidemargin-\marginparwidth-\marginparsep}% + \addtolength\topmargin{-1in}% + \addtolength\oddsidemargin{-1in}% + \evensidemargin\oddsidemargin% +} +\LL@setPaperSize +\paperwidth=0.333333334\paperwidth +\setmargins{11mm}{11mm}{8mm}{8mm} +\newcommand*\foldmarkrule{0.4pt} +\newcommand*\foldmarklength{2mm} +\newcommand\AddToBackground{% + \@ifstar{\@tempswatrue\LL@AddToBackground} + {\@tempswafalse\LL@AddToBackground}} +\@onlypreamble\AddToBackground +\newcommand\LL@AddToBackground[2]{% + \if@tempswa\def\@tempa{LL@largePic}\else\def\@tempa{LL@smallPic}\fi + \expandafter\providecommand\csname\@tempa\@Roman{#1}\endcsname{}% + \expandafter\g@addto@macro\csname\@tempa\@Roman{#1}\endcsname{#2}} +\newcommand\LenToUnit[1]{#1\@gobble} +\newcommand*\CutLine{% + \@ifstar{\@tempswatrue\LL@CutLine}{\@tempswafalse\LL@CutLine}} +\@onlypreamble\CutLine +\newcommand*\LL@CutLine[1]{% + \ifLL@combine + \ifx\Scissors\@empty\@tempswatrue\fi + \if@tempswa + \AddToBackground{#1}{% + \put(0,0){% + \rotatebox{90}{\makebox(\LenToUnit{\paperheight},0){% + \normalsize + \dotfill}}}}% + \else + \AddToBackground{#1}{% + \put(0,0){% + \rotatebox{90}{\makebox(\LenToUnit{\paperheight},0){% + \normalsize + \dotfill\Scissors\dotfill\dotfill\Scissors\dotfill}}}}% + \fi + \fi} +\IfFileExists{pifont.sty} + {\RequirePackage{pifont}% + \newcommand*\Scissors{\raisebox{-0.85ex}{\large\ding{34}}}}% + {\newcommand*\Scissors{}} +\AddToBackground{3}{\LL@foldmark} +\providecommand*\vb@xt@{\vbox to} +\AtBeginDocument{\EveryShipout{\LL@savePage}} +\newcounter{LL@page}\setcounter{LL@page}{1} +\newcommand\LL@tempa{} +\newcommand*\LL@savePage{% + \ifnum\c@LL@page<7\relax + \setbox\@cclv\vbox{% + \vbox{\@tempdima=1in\relax + \@tempdimb=\paperheight\advance\@tempdimb-\@tempdima + \pictur@(0,0)(\LenToUnit{\@tempdima},\LenToUnit{\@tempdimb})% + \begingroup + \set@typeset@protect + \@nameuse{LL@smallPic\Roman{LL@page}}% + %\set@display@protect + \endgroup + \endpicture}% + \nointerlineskip\box\@cclv}% + \ifLL@combine + \@@@exec@outs + \expandafter\newsavebox\csname LL@box\Roman{LL@page}\endcsname% + \setbox\@cclv=\vbox{\vskip1in\unvbox\@cclv}% + \setbox\@cclv=\vbox{\moveright1in\box\@cclv}% + \setbox\@cclv=\hb@xt@\paperwidth{\box\@cclv\hss}% + \setbox\@cclv=\vb@xt@\paperheight{\box\@cclv\vss}% + \global\expandafter\setbox% + \csname LL@box\Roman{LL@page}\endcsname=\box\@cclv% + \typeout{\@spaces[\the\c@LL@page] ==> [\Roman{LL@page}]}% + \fi + \fi + \ifnum\c@LL@page=7\relax + \begingroup + \set@typeset@protect + \LL@toomanypages{% + The text you supplied fills more than six pages\MessageBreak + and will therefore not fit onto a single flyer}{% + Try using smaller fonts or reducing vertical space}% + \endgroup + \fi + \stepcounter{LL@page}} +\ifLL@combine + \def\@@end{% + \clearpage\pagestyle{empty}% + \let\@outputpage\LL@outputpage + \def\@EveryShipout@Hook{}% + \def\@EveryShipout@AtNextHook{}% + \EveryShipout{\LL@savePage}% + \loop\ifnum\c@LL@page<7\relax + \ClassInfo{leaflet}{Generating empty page \the\c@page}% + \null\newpage + \repeat + \let\shipout\LL@shipout \let\@begindvi\LL@begindvi + \paperwidth=3\paperwidth + \iflandscape + \LL@pagesize@specials{\paperwidth}{\paperheight}% + \else + \LL@pagesize@specials{\paperheight}{\paperwidth}% + \fi + \newcommand*\LL@shipoutPage[1]{% + \let \protect \noexpand + \shipout\vb@xt@\paperheight{% + \set@typeset@protect + \vskip-1in% + \@begindvi\hb@xt@\paperwidth{\hskip-1in##1\hss}\vss}}% + \newcommand*\LL@preparePages[3]{% + \typeout{[\@Roman{##1}\space\@Roman{##2}\space\@Roman{##3}] ==>}% + \pictur@(0,0)\@nameuse{LL@largePic\Roman{page}}\endpicture% + \LL@preparePage{##1}\LL@preparePage{##2}\LL@preparePage{##3}}% + \newcommand*\LL@preparePage[1]{% + \expandafter\box\csname LL@box\@Roman{##1}\endcsname}% + \LL@selectOutput + {\setcounter{page}{1}% + \LL@shipoutPage{\LL@rotate@I{\LL@preparePages{5}{6}{1}}}}% + {\setcounter{page}{2}% + \LL@shipoutPage{\LL@rotate@II{\LL@preparePages{2}{3}{4}}}}% + \LL@@end + }% +\else + \LL@pagesize@specials{\paperwidth}{\paperheight}% + \AtEndDocument{% + \clearpage\pagestyle{empty}% + \loop\ifnum\c@LL@page<7\relax + \ClassInfo{leaflet}{Generating empty page \the\c@page}% + \null\newpage + \repeat + } +\fi +\endinput +%% +%% End of file `leaflet.cls'. Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/OSGeo_CMYK.pdf =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/OSGeo_CMYK.pdf ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/grasslogo_vector.pdf =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/grasslogo_vector.pdf ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/isodist.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/isodist.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/ndvi.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/ndvi.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/trento3d.pdf =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/trento3d.pdf ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/grassflyer/flyer1/cz/pix/visibility.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/grassflyer/flyer1/cz/pix/visibility.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From landa at grass.itc.it Sun Sep 9 11:39:20 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 9 11:39:22 2007 Subject: [grass-addons] r1085 - trunk/grassaddons/grassflyer/flyer1/en Message-ID: <200709090939.l899dKvm030481@grass.itc.it> Author: landa Date: 2007-09-09 11:39:16 +0200 (Sun, 09 Sep 2007) New Revision: 1085 Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex Log: Revert BAAAD commit (from cz translation branch). Not sure how it has happened. Sorry for that! Modified: trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-09 09:29:53 UTC (rev 1084) +++ trunk/grassaddons/grassflyer/flyer1/en/grassflyer.tex 2007-09-09 09:39:16 UTC (rev 1085) @@ -13,7 +13,6 @@ %If you need a foldmark, delete nofoldmark \documentclass[notumble,a4paper,10pt,nofoldmark]{leaflet} \usepackage{helvet,courier,xcolor} -\usepackage[utf8]{inputenc} % Set Helvetica as the default font \renewcommand*\familydefault\sfdefault @@ -42,17 +41,17 @@ \hypersetup{% colorlinks=true,% urlcolor=darkblue,% Redefine this color to change URIs color - pdfauthor={GRASS Community},% - pdftitle={GRASS GIS: U?innost Svodody \& Transparentnosti},% - pdfsubject={GRASS propaga?n? let?k GRASS},% + pdfauthor={The GRASS Community},% + pdftitle={GRASS GIS: Efficiency through Freedom \& Transparency},% + pdfsubject={GRASS Promotion Flyer},% breaklinks=true,% plainpages=false% } % Title page stuff \title{\textbf{\huge GRASS GIS}\\% -\textsl{U?innost Svodody \& Transparentnosti}} -\author{Komunita GRASSu} +\textsl{Efficiency through Freedom \& Transparency}} +\author{The GRASS Community} \date{\includegraphics[width=\textwidth]{grasslogo_vector}\\[2ex] \large\GRASSurl} @@ -63,90 +62,90 @@ \newpage -\section{Co je GRASS} +\section{What is GRASS} -GRASS (Geographic Resources Analysis Support System) je svobodn?/Open Source software ur?en? pro prostorov? anal?zy. Obsahuje v?ce ne? 350 modul? pro zpracov?n? 2D/3D vektorov?ch a rastrov?ch dat. Nab?z? ?adu rozhran? k dal??m program?m v dan? oblasti jako je geostatistika, datab?ze, mapov? slu?by a dokonce i k dal??m GIS aplikac?m. Je nejrozs?hlej??m Open Source GISem. M??e slou?it jako Desktop GIS ?i jako p?te? kompletn? GIS infrastrukturu. +GRASS (Geographic Resources Analysis Support System) is a free and Open Source Software for performing spatial analysis. It consists of more than 350 modules for processing vector (2D/3D), raster and voxel data. Many interfaces to other programs in related domains like geostatistics, databases, mapserver and even other GIS software exist. It is the largest Open Source GIS. It can serve as a Desktop GIS and as the backbone of a complete GIS Infrastructure. -\section{Kde je GRASS pou??v?n} +\section{Where is GRASS used} -GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? spr?v? po cel?m sv?t?. GRASS pokytuje v mnoha p?ipadech velk? potenci?l pro ?e?en? geoprostorov?ch ?loh. +GRASS is used in scientific applications, commercial settings and by public authorities all over the world. GRASS has shown strong potential for solving geospatial problems in numerous situations world-wide. -\section{Historie} +\section{History} -GRASS byl p?vodn? vyv?jen od po??tku 80-t?ch let agenturou US Army Construction Engineering Research Laboratories (USA-CERL) a byl poskytnut jako public domain software. V okam?iku kdy USA-CERL upustil od v?voje, vzniknul mezin?rodn? t?m v?voj??? kter? d?l software vyv?j?. Od roku 1999 je GRASS uvoln?n jako free software pod licenc? GNU General Public Licence. +GRASS was originally developed in the beginning of the 1980's by the US Army Construction Engineering Research Laboratories (USA-CERL) and was published as public domain software. When the USA-CERL withdrew from GRASS development, an international developer team took over this work. Since 1999, GRASS has been published as free software under the terms of the GNU General Public Licence. \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{visibility} -\captionof{figure}{Anal?za viditelnost provedena v GRASSu} +\captionof{figure}{Viewshed analysis performed with GRASS} \end{myfig} -\section{Filozofie Open Source} +\section{Open Source Philosophy} -Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do zdrovov?ch k?du a struktury programu, obrovskou m?ru transparentnosti. U?ivatel m??e roz???it program dle sv?ch pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez nutnosti zdrovov?ho k?du GRASSu. +The Open Source philosophy provides the user the ability to see the source code and structure of the program which offers a great transparency. Users can extend the program for their own needs. Immediate source code peer review increases the quality. With the help of the extension manager new modules can be created without GRASS package source code. -\section{Technick? data} +\section{Technical Data Sheet} -\subsection{Licence} +\subsection{License} -V?eobecn? ve?ejn? licence GNU (GNU General Public License, Free Software Foundation) +GNU General Public License (Free Software Foundation) -\subsection{Podporovan? platformy} +\subsection{Supported platforms} -GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? syst?my podporuj?c? Posix, MS-Windows a MacOS X. +GRASS runs on nearly all platforms. It supports GNU/Linux, Posix compliant Unix Systems, MS-Windows and MacOS X. \subsection{Design} \begin{itemize} -\item Modul?rn? -\item Obsahuje v?ce ne? 350 modul? +\item Modular +\item Consists of more than 350 modules \end{itemize} -\subsection{Programovac? jazyky} +\subsection{Programming Languages} \begin{itemize} \item ANSI C -\item Rozhran? GRASS- SWIG -\item Python pro WebGIS aplikace -\item Verze pro Javu: JGRASS +\item GRASS- SWIG interface +\item Python for WebGIS applications +\item Java Version: JGRASS \end{itemize} -\subsection{Mo?nosti spr?vy dat} +\subsection{Data Management Capabilities} \begin{itemize} -\item Zpracov?n? rasterov?ch / vektorov?ch / voxel dat -\item Modelov?n? 2D / 3D rastrov?ch / vektorov?ch dat -\item Zpracov?n? obrazov?ch dat -\item Vektorov? topologie / S??ov? anal?zy -\item Geostatistika (rozhran? pro R) +\item Raster / Vector / Voxel data processing +\item 2D / 3D Raster / Vector modelling +\item Image manipulation +\item Vector topology / Network analysis +\item Geostatistics (Interface to R) \end{itemize} \begin{myfig}[1ex] \includegraphics[width=0.7\textwidth]{trento3d} -\captionof{figure}{3D pohled na Trento, It?lie} +\captionof{figure}{A flyby of the city of Trento, Italy} \end{myfig} -\section{Podporovan? datov? form?ty} +\section{Supported File Formats} -GRASS podporuje t?m?? v?echny dob?e zn?m? GIS datov? form?ty d?ky knihovn? GDAL/OGR. Nav?c podporuje Open GIS Consortium's Simple Features. +GRASS supports nearly all common GIS file formats through the use of the GDAL/OGR library. In addition it supports the Open GIS Consortium's Simple Features. -\subsection{Vektorov? datov? form?ty} +\subsection{Vector File formats} ASCII, ARC/INFO ungenerate, ARC/INFO E00, Arc\-View SHAPE, BIL, DLG (U.S.), DXF, DXF3D, GMT, GPS-ASCII USGS-DEM, IDRISI, MOSS, MapInfo MIF, TIGER, VRML, \dots -\subsection{Rastrov? datov? form?ty} +\subsection{Raster File Formats} ASCII, ARC/GRID, E00, GIF, GMT, TIF, PNG, Vis5D, SURFER (.grd),\dots \begin{myfig} \includegraphics[width=0.7\textwidth]{isodist} -\captionof{figure}{V?choz? konfigurace GUI ukazuj?c? mo?nosti GRASSu pro s??ov? anal?zy} +\captionof{figure}{Default GUI configuration showing GRASS network analysis capabilites} \end{myfig} -\subsection{Obrazov? datov? form?ty} +\subsection{Image File Formats} CEOS (SAR, SRTM, LANDSAT7 etc.), ERDAS LAN / IMG, HDF, LANDSAT TM/MSS, NHAP aerial photos, SAR, SPOT, \dots \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{ndvi} -\captionof{figure}{Mo?nosti GRASS ve zpracov?n? obrazov?ch dat} +\captionof{figure}{Image processing capabilities of GRASS} \end{myfig} -\subsection{Podpora databaz?} +\subsection{Database support} \begin{itemize} \item PostgreSQL / PostGIS @@ -156,41 +155,41 @@ \item DBF \end{itemize} -\subsection{V?stup} +\subsection{Output} \begin{itemize} -\item Moduly pro tvorbu mapov?ch v?stup? -\item NVIZ pro vizualizaci 2.5D a 3D dat (tvorba animac? \& pohled?) +\item Modules for creating maps +\item NVIZ for visualization of 2.5D and 3D data (creation of animations \& flybys) %\item{GMT export} %item{VRML} \item VTK, POVray -\item WebGIS pomoc? Mapserver, Python, a pod. +\item WebGIS via Mapserver, Python, etc. \end{itemize} -\subsection{Interoperabilita v??i dal??m GIS program?m} +\subsection{Interoperability to other GIS- related Software} \begin{itemize} -\item Quantum GIS (Free Geodata (nejen) prohl??e?) -\item R- Language (statistika) -\item Gstat (geostatistika) -\item UMN Mapserver (webov? slu?by) +\item Quantum GIS (Free Geodata Viewer and more) +\item R- Language (Statistics) +\item Gstat (Geostatistics) +\item UMN Mapserver (Webmapping) \end{itemize} -\section{Kde naj?t dal?? informace} +\section{Where to find more information} \begin{itemize} %\begin{flushleft} -\item{Webov? str?nky projektu: \\\GRASSurl} +\item{Project Website: \\\GRASSurl} \item{GRASS Wiki: \\\url{http://grass.gdf.hannover.de/wiki}} -\item{Propaga?n? t?m GRASSu: \\\url{malte@perlomat.de}} -\item{Elektronick? konference GRASSu: \\\url{http://grass.itc.it/community/support.php}} +\item{GRASS Promotion Team: \\\url{malte@perlomat.de}} +\item{GRASS mailing lists: \\\url{http://grass.itc.it/community/support.php}} %\end{flushleft} \end{itemize} \vfill \section{OSGeo} -GRASS je zakl?daj?c?m projektem Open Source Geospatial Foundation, kter? si klade za c?l tvorbu vysoce kvalitn?ho Open Source GIS software. Pro dal?? informace nav?tivte domovskou str?nku OSGeo: +GRASS is a founding project of the Open Source Geospatial Foundation which has the aim to create high quality open source geospatial software. For further information visit the OSGeo homepage: \begin{center} \includegraphics[width=0.8\textwidth]{OSGeo_CMYK}\\ \url{http://www.osgeo.org} From landa at grass.itc.it Mon Sep 10 13:52:05 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Sep 10 17:45:05 2007 Subject: [grass-addons] r1087 - in trunk/grassaddons/gui: display_driver gui_modules icons Message-ID: <200709101152.l8ABq5wr008119@grass.itc.it> Author: landa Date: 2007-09-10 13:52:03 +0200 (Mon, 10 Sep 2007) New Revision: 1087 Modified: trunk/grassaddons/gui/display_driver/Makefile trunk/grassaddons/gui/display_driver/driver.cc trunk/grassaddons/gui/gui_modules/dbm.py 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 Log: Fix DisplayAttributesDialog (support for more layers/categories). DigitCategoryDialog introduced (not finished). Modified: trunk/grassaddons/gui/display_driver/Makefile =================================================================== --- trunk/grassaddons/gui/display_driver/Makefile 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/display_driver/Makefile 2007-09-10 11:52:03 UTC (rev 1087) @@ -1,4 +1,4 @@ -PYTHONVERSION=2.5 +PYTHONVERSION=2.4 MODULE_TOPDIR = ../../.. Modified: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-10 11:52:03 UTC (rev 1087) @@ -798,9 +798,9 @@ } else { returnId.push_back(DCid - 2); - Cell2Pixel(points->x[Gid-2], points->y[Gid-2], points->z[Gid-2], + Cell2Pixel(points->x[Gid-1], points->y[Gid-1], points->z[Gid-1], &vx, &vy, &vz); - wxRect rect (x, y, 0, 0); + wxRect rect (vx, vy, 0, 0); dc->SetIdBounds(DCid-2, rect); } @@ -810,9 +810,9 @@ } else { returnId.push_back(DCid + 2); - Cell2Pixel(points->x[Gid+2], points->y[Gid+2], points->z[Gid+2], + Cell2Pixel(points->x[Gid+1], points->y[Gid+1], points->z[Gid+1], &vx, &vy, &vz); - wxRect rect (x, y, 0, 0); + wxRect rect (vx, vy, 0, 0); dc->SetIdBounds(DCid + 2, rect); } Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-10 11:52:03 UTC (rev 1087) @@ -19,7 +19,7 @@ AUTHOR(S): GRASS Development Team Original author: Jachym Cepicky - Martin Landa + Various updates: Martin Landa COPYRIGHT: (C) 2007 by the GRASS Development Team @@ -589,14 +589,14 @@ class DisplayAttributesDialog(wx.Dialog): """ - Standard dialog used for adding new/updating existing or - displaying (read-only mode) attributes of vector map layers. + Standard dialog used to add/update/display attributes linked + to the vector map. Attribute data can be selected based on layer and category number - or coordinates. If layer=-1 all layer are queried. - """ + or coordinates""" def __init__(self, parent, map, - layer=1, cat=1, queryCoords=None, qdist=1, + layer=-1, cat=-1, # select by layer/cat + queryCoords=None, qdist=-1, # select by point style=wx.DEFAULT_DIALOG_STYLE, pos=wx.DefaultPosition, action="add"): @@ -607,16 +607,26 @@ self.qdist = qdist self.action = action - self.selectedLines = [] # id of selected feature + # id of selected line + self.line = None - self.mapInfo = VectorAttributesInfo(self.map) + # get layer/table/column information + self.mapInfo = VectorAttributeInfo(self.map) - if self.layer > 0 and \ - self.layer not in self.mapInfo.layers.keys(): + layers = self.mapInfo.layers.keys() # get available layers + + # check if db connection / layer exists + if (self.layer == -1 and len(layers) <= 0) or \ + (self.layer > 0 and self.layer not in layers): + if self.layer == -1: + label = "Database connection for vector map <%s> " + "is not defined in DB file" % self.map + else: + label = "Layer <%d> is not available for vector map <%s>" % self.map + dlg = wx.MessageDialog(None, - _("Attribute table not found.\n" - "Layer %d is not available in vector map <%s>") % \ - (layer, self.map), + _("No attribute table found.\n" + "%s") % (label), _("Error"), wx.OK | wx.ICON_ERROR) dlg.ShowModal() dlg.Destroy() @@ -629,82 +639,83 @@ # dialog body mainSizer = wx.BoxSizer(wx.VERTICAL) + if self.queryCoords: # select by point + self.line, nselected = self.mapInfo.SelectByPoint(self.queryCoords, + self.qdist) # notebook notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) - for layer in self.mapInfo.layers.keys(): + for layer in layers: # for each layer if self.layer > 0 and \ self.layer != layer: continue - # line detected, number of selected records - line, selected = self.mapInfo.SelectFromTable(layer, self.cat, - self.queryCoords, self.qdist) + if not self.queryCoords: + nselected = self.mapInfo.SelectFromTable(layer, self.cat) - if (self.action == "add" and selected > 0) or \ - self.action == "update": - self.SetTitle(_("Update attributes")) - elif self.action == "add": - self.SetTitle(_("Add attributes")) - else: - self.SetTitle(_("Display attributes")) - - if self.action == "add": - pass - else: - if not line and selected == 0: - continue - - if line: - self.selectedLines.append(line) - panel = wx.Panel(parent=notebook, id=wx.ID_ANY) notebook.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer)) # notebook body border = wx.BoxSizer(wx.VERTICAL) - box = wx.StaticBox (parent=panel, id=wx.ID_ANY, - label="") - boxFont = self.GetFont() - boxFont.SetWeight(wx.FONTWEIGHT_BOLD) - box.SetFont(boxFont) - sizer = wx.StaticBoxSizer(box, wx.VERTICAL) - flexSizer = wx.FlexGridSizer (cols=4, hgap=3, vgap=3) - flexSizer.AddGrowableCol(0) - table = self.mapInfo.layers[layer]["table"] + table = self.mapInfo.layers[layer]["table"] columns = self.mapInfo.tables[table] - # columns - for name in columns.keys(): - type = columns[name][0] - value = columns[name][1] - if name.lower() == "cat": - box.SetLabel(" %s %s " % (_("Category"), value)) - colValue = box - else: - colName = wx.StaticText(parent=panel, id=wx.ID_ANY, label=name) - colType = wx.StaticText(parent=panel, id=wx.ID_ANY, label="[" + type.lower() + "]") - delimiter = wx.StaticText(parent=panel, id=wx.ID_ANY, label=":") + # value + for idx in range(len(columns["cat"][1])): + flexSizer = wx.FlexGridSizer (cols=4, hgap=3, vgap=3) + flexSizer.AddGrowableCol(0) + # columns + for name in columns.keys(): + type = columns[name][0] + value = columns[name][1][idx] + if name.lower() == "cat": + box = wx.StaticBox (parent=panel, id=wx.ID_ANY, + label=" %s %s " % (_("Category"), value)) + boxFont = self.GetFont() + boxFont.SetWeight(wx.FONTWEIGHT_BOLD) + box.SetFont(boxFont) + sizer = wx.StaticBoxSizer(box, wx.VERTICAL) + colValue = box + else: + colName = wx.StaticText(parent=panel, id=wx.ID_ANY, + label=name) + colType = wx.StaticText(parent=panel, id=wx.ID_ANY, + label="[" + type.lower() + "]") + delimiter = wx.StaticText(parent=panel, id=wx.ID_ANY, label=":") - colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value, size=(250, -1)) # TODO: validator - colValue.SetName(name) - self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue) + colValue = wx.TextCtrl(parent=panel, id=wx.ID_ANY, value=value, + size=(250, -1)) # TODO: validator + colValue.SetName(name) + self.Bind(wx.EVT_TEXT, self.OnSQLStatement, colValue) - flexSizer.Add(colName, proportion=0, - flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) - flexSizer.Add(colType, proportion=0, - flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) - flexSizer.Add(delimiter, proportion=0, - flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) - flexSizer.Add(colValue, proportion=0, - flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(colName, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(colType, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(delimiter, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(colValue, proportion=0, + flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL) + # add widget reference to self.columns + columns[name][2].append(colValue.GetId()) # name, type, values, id - sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5) - border.Add(item=sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5) - panel.SetSizer(border) + # for each attribute (including category) END + 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) + # for each category END - # add widget reference to self.columns - columns[name].append(colValue.GetId()) + panel.SetSizer(border) + # for each layer END + # set title + if (self.action == "add" and selected > 0) or \ + self.action == "update": + self.SetTitle(_("Update attributes")) + elif self.action == "add": + self.SetTitle(_("Add attributes")) + else: + self.SetTitle(_("Display attributes")) + # buttons btnSizer = wx.StdDialogButtonSizer() btnCancel = wx.Button(self, wx.ID_CANCEL) @@ -741,76 +752,88 @@ def GetSQLString(self): """Create SQL statement string based on self.sqlStatement""" - for layer in self.mapInfo.layers.keys(): + sqlCommands = [] + # find updated values for each layer/category + for layer in self.mapInfo.layers.keys(): # for each layer table = self.mapInfo.layers[layer]["table"] columns = self.mapInfo.tables[table] - cat = columns["cat"][1] - # find updated values - updatedColumns = [] - updatedValues = [] - for name in columns.keys(): - if name == "cat": + for idx in range(len(columns["cat"][1])): # for each category + updatedColumns = [] + updatedValues = [] + for name in columns.keys(): + if name == "cat": + cat = columns[name][1][idx] + continue + type = columns[name][0] + value = columns[name][1][idx] + id = columns[name][2][idx] + try: + newvalue = self.FindWindowById(id).GetValue() + except: + newvalue = self.FindWindowById(id).GetLabel() + + if newvalue != value: + updatedColumns.append(name) + if type != 'character': + updatedValues.append(newvalue) + else: + updatedValues.append("'" + newvalue + "'") + + if self.action != "add" and len(updatedValues) == 0: continue - type, value, id = columns[name] - try: - newvalue = self.FindWindowById(id).GetValue() - except: - newvalue = self.FindWindowById(id).GetLabel() - if newvalue != value: - updatedColumns.append(name) - if type != 'character': - updatedValues.append(newvalue) - else: - updatedValues.append("'" + newvalue + "'") - if self.action != "add" and len(updatedValues) == 0: - sqlString = "" - Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlString) - return sqlString - - if self.action == "add": - sqlString = "INSERT INTO %s (cat," % table - else: - sqlString = "UPDATE %s SET " % table - - for idx in range(len(updatedColumns)): - name = updatedColumns[idx] if self.action == "add": - sqlString += name + "," + sqlString = "INSERT INTO %s (cat," % table else: - sqlString += name + "=" + updatedValues[idx] + "," + sqlString = "UPDATE %s SET " % table - sqlString = sqlString[:-1] # remove last comma + for idx in range(len(updatedColumns)): + name = updatedColumns[idx] + if self.action == "add": + sqlString += name + "," + else: + sqlString += name + "=" + updatedValues[idx] + "," - if self.action == "add": - sqlString += ") VALUES (%s," % cat - for value in updatedValues: - sqlString += str(value) + "," sqlString = sqlString[:-1] # remove last comma - sqlString += ")" - else: - sqlString += " WHERE cat=%s" % cat - Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlString) - return sqlString + if self.action == "add": + sqlString += ") VALUES (%s," % cat + for value in updatedValues: + sqlString += str(value) + "," + sqlString = sqlString[:-1] # remove last comma + sqlString += ")" + else: + sqlString += " WHERE cat=%s" % cat + sqlCommands.append(sqlString) + # for each category + # for each layer END + Debug.msg(3, "DisplayAttributesDialog.GetSQLString(): %s" % sqlCommands) + return sqlCommands + def OnReset(self, event): """Reset form""" for layer in self.mapInfo.layers.keys(): table = self.mapInfo.layers[layer]["table"] columns = self.mapInfo.tables[table] - for name in columns.keys(): - type, value, id = columns[name] - if name.lower() != "cat": - self.FindWindowById(id).SetValue(value) + for idx in range(len(columns["cat"][1])): + for name in columns.keys(): + type = columns[name][0] + value = columns[name][1][idx] + id = columns[name][2][idx] + if name.lower() != "cat": + self.FindWindowById(id).SetValue(value) def OnSubmit(self, event): """Submit record""" - self.Close() -class VectorAttributesInfo: - """Class providing information about attributes + def GetLine(self): + """Get id of selected line or 'None' if no line is selected""" + return self.line + +class VectorAttributeInfo: + """Class providing information about attribute tables linked to the vector map""" def __init__(self, map): self.map = map @@ -818,6 +841,7 @@ self.layers = {} # {table : [(column name, type, value)]} self.tables = {} + if not self.__CheckDBConnection(): # -> self.layers return @@ -853,65 +877,79 @@ "layer=%d" % layer]) table = self.layers[layer]["table"] - columns = {} # {name: [type, value]} + columns = {} # {name: type, [values], [ids]} if columnsCommand.returncode == 0: for line in columnsCommand.ReadStdOutput(): columnType, columnName = line.split('|') columnType = columnType.lower().strip() - columns[columnName] = [columnType, ""] # default value ("") + columns[columnName] = [columnType, [], []] else: pass self.tables[table] = columns - def SelectFromTable(self, layer=1, cat=1, queryCoords=None, qdist=1): - """Select records from the table + def SelectByPoint(self, queryCoords, qdist): + """Get attributes by coordinates (all available layers) - Based on coordinates or category - """ - table = self.layers[layer]["table"] - selected = 0 + Return line id or None if no line is found""" line = None - if queryCoords: - # snapping distance - cmdWhat = cmd.Command(cmd=['v.what', - '-a', '-d', '--q', - 'map=%s' % self.map, - 'east_north=%f,%f' % \ + nselected = 0 + cmdWhat = cmd.Command(cmd=['v.what', + '-a', '--q', + 'map=%s' % self.map, + 'east_north=%f,%f' % \ (float(queryCoords[0]), float(queryCoords[1])), - 'distance=%f' % qdist]) + 'distance=%f' % qdist]) - if cmdWhat.returncode == 0: - read = False - for item in cmdWhat.ReadStdOutput(): - found = True - if read: - name, value = item.split(':') - name = name.strip() - self.tables[table][name][1] = value.strip() - selected+=1; - if "line:" in item.lower(): - line = int(item.split(':')[1].strip()) - elif "category:" in item.lower(): - self.tables[table]["cat"][1] = item.split(':')[1].strip() - elif "key column:" in item.lower(): - read = True - else: - # select values - selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q", - "map=%s" % self.map, - "layer=%d" % layer, - "where=cat=%d" % cat]) - self.tables[table]["cat"][1] = str(cat) - if selectCommand.returncode == 0: - for line in selectCommand.ReadStdOutput(): - name, value = line.split('|') - self.tables[table][name][1] = value - selected+=1 + if cmdWhat.returncode == 0: + read = False + for item in cmdWhat.ReadStdOutput(): + litem = item.lower() + if read: + name, value = item.split(':') + name = name.strip() + # append value to the column + try: + self.tables[table][name][1].append(value.strip()) + except: + read = False + + if "line:" in litem: # get line id + line = int(item.split(':')[1].strip()) + elif "key column:" in litem: # start reading attributes + read = True + nselected = nselected + 1 + elif "layer:" in litem: # get layer id + layer = int(item.split(':')[1].strip()) + table = self.layers[layer]["table"] # get table desc + read = False - return (line, selected) + return (line, nselected) + def SelectFromTable(self, layer, cat): + """Select records from the table + + Return True on success False on error + """ + if layer <= 0: + return False + + table = self.layers[layer]["table"] # get table desc + # select values (only one record) + selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q", + "map=%s" % self.map, + "layer=%d" % layer, + "where=cat=%d" % cat]) + + self.tables[table]["cat"][1] = str(cat) + if selectCommand.returncode == 0: + for line in selectCommand.ReadStdOutput(): + name, value = line.split('|') + self.tables[table][name][1].append(value) + + return True + def main(argv=None): if argv is None: argv = sys.argv Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-10 11:52:03 UTC (rev 1087) @@ -8,8 +8,9 @@ * AbstractDisplayDriver * PyDisplayDriver * CDisplayDriver - * SettingsDialog - + * DigitSettingsDialog + * DigitCategoryDialog + PURPOSE: Digitization tool wxPython GUI prototype Note: Initial version under development @@ -36,6 +37,7 @@ import wx import wx.lib.colourselect as csel +import wx.lib.mixins.listctrl as listmix import gcmd as cmd import dbm @@ -97,7 +99,7 @@ self.settings["lineWidth"] = (2, "screen pixels") # snapping - self.settings["snapping"] = (10, "screen pixels") # value, unit + self.settings["snapping"] = (20, "screen pixels") # value, unit self.settings["snapToVertex"] = False # digitize new record @@ -390,14 +392,25 @@ self.ids = {} # dict[g6id] = [pdcId] self.selected = [] # list of selected objects (grassId!) - def GetThreshold(self): + def GetThreshold(self, value=None, units=None): """Return threshold in map units""" - if self.parent.settings["snapping"][1] == "screen pixels": + if not value: + value = self.parent.settings["snapping"][0] + + if not units: + units = self.parent.settings["snapping"][1] + + if units == "screen pixels": # pixel -> cell - threshold = self.mapwindow.Distance(beginpt=(0,0), - endpt=(self.parent.settings["snapping"][0],0))[0] + reg = self.mapwindow.Map.region + if reg['nsres'] > reg['ewres']: + res = reg['nsres'] + else: + res = reg['ewres'] + + threshold = value * res else: - threshold = Digit.settings["snapping"][0] + threshold = value Debug.msg(4, "AbstractDisplayDriver.GetThreshold(): thresh=%f" % threshold) @@ -1047,9 +1060,11 @@ 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), value=str(self.parent.digit.settings["snapping"][0]), min=1, 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"]) self.snappingUnit.SetValue(self.parent.digit.settings["snapping"][1]) + self.snappingUnit.Bind(wx.EVT_COMBOBOX, self.OnChangeSnappingUnits) flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) flexSizer.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE) flexSizer.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE) @@ -1058,6 +1073,12 @@ label=_("Snap also to vertex")) self.snapVertex.SetValue(self.parent.digit.settings["snapToVertex"]) vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) + self.mapUnits = self.parent.MapWindow.Map.ProjInfo()['units'] + self.snappingInfo = wx.StaticText(parent=panel, id=wx.ID_ANY, + label=_("Snapping threshold is %.1f %s") % \ + (self.parent.digit.threshold, + self.mapUnits)) + vertexSizer.Add(item=self.snappingInfo, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) sizer.Add(item=vertexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) @@ -1159,6 +1180,33 @@ """Checkbox 'Add new record' status changed""" self.category.SetValue(str(self.parent.digit.SetCategory())) + def OnChangeSnappingValue(self, event): + """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") % \ + (threshold, + self.mapUnits)) + + event.Skip() + + def OnChangeSnappingUnits(self, event): + """Snapping units change -> update static text""" + value = self.snappingValue.GetValue() + units = self.snappingUnit.GetValue() + threshold = self.parent.digit.driver.GetThreshold(value, units) + + if units == "map units": + self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % \ + (value, + self.mapUnits)) + else: + self.snappingInfo.SetLabel(_("Snapping threshold is %.1f %s") % \ + (threshold, + self.mapUnits)) + + event.Skip() + def OnOK(self, event): """Button 'OK' clicked""" self.UpdateSettings() @@ -1207,3 +1255,131 @@ # redraw map if auto-rendering is enabled if self.parent.autoRender.GetValue(): self.parent.ReRender(None) + +class DigitCategoryDialog(wx.Dialog): + """ + Dialog used to display/modify categories of vector objects + """ + def __init__(self, parent, title, + map, queryCoords, qdist, + pos=wx.DefaultPosition, + style=wx.DEFAULT_DIALOG_STYLE): + # map name + self.map = map + + # line id (if not found remains 'None') + self.line = None + + # {layer: [categories]} + self.cats = {} + + # do not display dialog if no line is found + if self.__GetCategories(queryCoords, qdist) == 0 or not self.line: + Debug.msg(3, "DigitCategoryDialog(): nothing found!") + return + + Debug.msg(3, "DigitCategoryDialog(): line=%d, cats=%s" % \ + (self.line, self.cats)) + + wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style) + + self.parent = parent # mapdisplay.BufferedWindow class instance + + # list + listSizer = wx.BoxSizer(wx.VERTICAL) + self.list = CategoryListCtrl(parent=self, id=wx.ID_ANY, + style=wx.LC_REPORT | + wx.BORDER_NONE | + wx.LC_SORT_ASCENDING) + listSizer.Add(item=self.list, proportion=1, flag=wx.EXPAND) + + # buttons + btnApply = wx.Button(self, wx.ID_APPLY, _("Apply") ) + btnCancel = wx.Button(self, wx.ID_CANCEL) + btnOk = wx.Button(self, wx.ID_OK, _("OK") ) + btnOk.SetDefault() + + # bindigs + btnApply.Bind(wx.EVT_BUTTON, self.OnApply) + btnOk.Bind(wx.EVT_BUTTON, self.OnOK) + + # sizers + btnSizer = wx.StdDialogButtonSizer() + btnSizer.AddButton(btnCancel) + btnSizer.AddButton(btnApply) + btnSizer.AddButton(btnOk) + btnSizer.Realize() + + mainSizer = wx.BoxSizer(wx.VERTICAL) + mainSizer.Add(item=listSizer, proportion=0, + flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) + mainSizer.Add(item=btnSizer, proportion=0, + flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) + + self.SetSizer(mainSizer) + mainSizer.Fit(self) + + def __GetCategories(self, coords, qdist): + """Get layer/category pairs for all available + layers + + Return True line found or False if not found""" + + cmdWhat = cmd.Command(cmd=['v.what', + '--q', + 'map=%s' % self.map, + 'east_north=%f,%f' % \ + (float(coords[0]), float(coords[1])), + 'distance=%f' % qdist]) + + if cmdWhat.returncode != 0: + return False + + for item in cmdWhat.ReadStdOutput(): + litem = item.lower() + if "line:" in litem: # get line id + self.line = int(item.split(':')[1].strip()) + elif "layer:" in litem: # add layer + layer = int(item.split(':')[1].strip()) + if layer not in self.cats.keys(): + self.cats[layer] = [] + elif "category:" in litem: # add category + self.cats[layer].append(int(item.split(':')[1].strip())) + + return True + + def OnApply(self, event): + """Apply button clicked""" + self.Close() + + def OnOK(self, event): + """OK button clicked""" + self.Close() + + def GetLine(self): + """Get id of selected line of 'None' if no line is selected""" + return self.line + +class CategoryListCtrl(wx.ListCtrl, + listmix.ListCtrlAutoWidthMixin, + listmix.TextEditMixin): + """List of layers/categories""" + + def __init__(self, parent, id, pos=wx.DefaultPosition, + size=wx.DefaultSize, style=0): + + wx.ListCtrl.__init__(self, parent, id, pos, size, style) + + listmix.ListCtrlAutoWidthMixin.__init__(self) + self.Populate() + listmix.TextEditMixin.__init__(self) + + def Populate(self): + """Populate the list""" + self.InsertColumn(0, _("Layer")) + self.InsertColumn(1, _("Category")) + + self.SetColumnWidth(0, 100) + self.SetColumnWidth(1, wx.LIST_AUTOSIZE) + + self.currentItem = 0 Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-10 11:52:03 UTC (rev 1087) @@ -64,6 +64,7 @@ import histogram as histogram import profile as profile from digit import Digit as Digit +from digit import DigitCategoryDialog as DigitCategoryDialog from debug import Debug as Debug from icon import Icons as Icons @@ -476,7 +477,7 @@ return img - def UpdateMap(self, render=True): + def UpdateMap(self, render=True, renderVector=True): """ Updates the canvas anytime there is a change to the underlaying images or to the geometry of the canvas. @@ -518,7 +519,7 @@ # render vector map layer # digitToolbar = self.parent.digittoolbar - if digitToolbar and \ + if renderVector and digitToolbar and \ digitToolbar.layerSelectedID != None: # set region self.parent.digit.driver.UpdateRegion() @@ -575,12 +576,6 @@ 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.statusbar.SetStatusText("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"]), - # 0) return True @@ -875,38 +870,54 @@ self.pdcVector.SetPen(self.polypen) elif digitToolbar.action == "splitLine": pass - elif digitToolbar.action == "displayAttributes": + elif digitToolbar.action in ["displayAttributes", "displayCategories"]: qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / self.Map.width) - # select attributes based on coordinates (all layers) - updateRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, - layer=-1, queryCoords=(east, north), - qdist=qdist, - pos=posWindow, - action="update") - if not updateRecordDlg.mapInfo and \ - self.parent.digit.settings["addRecord"]: + redraw = False + if digitToolbar.action == "displayAttributes": + # select attributes based on coordinates (all layers) updateRecordDlg = dbm.DisplayAttributesDialog(parent=self, map=map, - layer=-1, queryCoords=(east, north), qdist=qdist, pos=posWindow, - action="add") - if updateRecordDlg.mapInfo: - # highlight feature & re-draw map - self.parent.digit.driver.SetSelected(updateRecordDlg.selectedLines) - self.UpdateMap(render=False) + action="update") + if updateRecordDlg.mapInfo and \ + updateRecordDlg.GetLine(): + # highlight feature & re-draw map + self.parent.digit.driver.SetSelected([updateRecordDlg.GetLine()]) + self.UpdateMap(render=False) + redraw = True + if updateRecordDlg.ShowModal() == wx.ID_OK: + sqlCommands = updateRecordDlg.GetSQLString() + if len(sqlCommands) > 0: + sqlfile = tempfile.NamedTemporaryFile(mode="w") + for sql in sqlCommands: + sqlfile.file.write(sql + ";\n") + sqlfile.file.flush() + executeCommand = cmd.Command(cmd=["db.execute", + "--q", + "input=%s" % sqlfile.name]) + else: # displayCategories + categoryDlg = DigitCategoryDialog(parent=self, + map=map, + queryCoords=(east, north), + qdist=qdist, + pos=posWindow, + title=_("Display categories")) - if updateRecordDlg.ShowModal() == wx.ID_OK: - sqlfile = tempfile.NamedTemporaryFile(mode="w") - sqlfile.file.write(updateRecordDlg.GetSQLString()) - sqlfile.file.flush() - executeCommand = cmd.Command(cmd=["db.execute", - "--q", - "input=%s" % sqlfile.name]) - # unselect & re-draw + if categoryDlg.GetLine(): + # highlight feature & re-draw map + self.parent.digit.driver.SetSelected([categoryDlg.GetLine()]) + self.UpdateMap(render=False) + redraw = True + + if categoryDlg.ShowModal() == wx.ID_OK: + pass + # unselect & re-draw + if redraw: # PyDisplayDriver: Digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() self.UpdateMap(render=False) + else: # get decoration id self.lastpos = self.mouse['begin'] @@ -982,7 +993,8 @@ else: # -> move vertex self.moveIds = driver.GetSelectedVertex(pos1) - + else: + self.UpdateMap(render=False, renderVector=False) elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]: self.parent.digit.driver.SelectLinesByPoint(pos1, onlyType="line") self.UpdateMap(render=False) @@ -1228,16 +1240,16 @@ # draw polyline self.pdcVector.TranslateId(self.moveIds[0], dx, dy) - self.pdcVector.RemoveId(self.moveIds[0]) - self.pdcVector.RemoveId(self.moveIds[-1]) - self.pdcVector.RemoveId(self.moveIds[-2]) + #self.pdcVector.RemoveId(self.moveIds[0]) + #self.pdcVector.RemoveId(self.moveIds[-1]) + #self.pdcVector.RemoveId(self.moveIds[-2]) self.polycoords = [] - if self.moveIds[-2] > 0: # left line + if self.moveIds[1] > 0: # left vertex x1, y1 = self.pdcVector.GetIdBounds(self.moveIds[1])[0:2] self.polycoords.append((x1, y1)) x2, y2 = self.mouse['end'] self.polycoords.append((x2, y2)) - if self.moveIds[-1] > 0: # right line + if self.moveIds[2] > 0: # right line x3, y3 = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2] self.polycoords.append((x3, y3)) Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-10 11:52:03 UTC (rev 1087) @@ -54,8 +54,8 @@ if label: tool = toolbar.AddLabelTool(wx.ID_ANY, label, bitmap, - bmpDisabled, kind, - shortHelp, longHelp) + bmpDisabled, kind, + shortHelp, longHelp) parent.Bind(wx.EVT_TOOL, handler, tool) else: # add separator toolbar.AddSeparator() @@ -353,9 +353,7 @@ self.parent.MapWindow.mouse['box'] = 'point' def OnExit (self, event): - """ - Quit digitization tool - """ + """Quit digitization tool""" # stop editing of the currently selected map layer try: self.StopEditing(self.layers[self.layerSelectedID]) @@ -366,48 +364,61 @@ self.parent.RemoveToolbar ("digit") def OnMoveVertex(self, event): + """Move line vertex""" Debug.msg(2, "Digittoolbar.OnMoveVertex():") self.action = "moveVertex" self.parent.MapWindow.mouse['box'] = 'point' def OnAddVertex(self, event): + """Add line vertex""" Debug.msg(2, "Digittoolbar.OnAddVertex():") self.action = "addVertex" self.parent.MapWindow.mouse['box'] = 'point' def OnRemoveVertex(self, event): + """Remove line vertex""" Debug.msg(2, "Digittoolbar.OnRemoveVertex():") self.action = "removeVertex" self.parent.MapWindow.mouse['box'] = 'point' def OnSplitLine(self, event): + """Split line""" Debug.msg(2, "Digittoolbar.OnSplitLine():") self.action = "splitLine" self.parent.MapWindow.mouse['box'] = 'point' def OnEditLine(self, event): + """Edit line""" pass def OnMoveLine(self, event): + """Move line""" Debug.msg(2, "Digittoolbar.OnMoveLine():") self.action = "moveLine" self.parent.MapWindow.mouse['box'] = 'box' def OnDeleteLine(self, event): + """Delete line""" Debug.msg(2, "Digittoolbar.OnDeleteLine():") self.action = "deleteLine" self.parent.MapWindow.mouse['box'] = 'box' def OnDisplayCats(self, event): - pass + """Display/update categories""" + Debug.msg(2, "Digittoolbar.OnDisplayCats():") + self.action="displayCategories" + self.parent.MapWindow.mouse['box'] = 'point' def OnDisplayAttr(self, event): + """Display/update attributes""" + Debug.msg(2, "Digittoolbar.OnDisplayAttr():") self.action="displayAttributes" - Debug.msg(2, "Digittoolbar.OnDisplayAttr():") + self.parent.MapWindow.mouse['box'] = 'point' def OnCopyCats(self, event): + """Copy categories""" pass def OnSettings(self, event): Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-09-10 08:04:10 UTC (rev 1086) +++ trunk/grassaddons/gui/icons/icon.py 2007-09-10 11:52:03 UTC (rev 1087) @@ -239,9 +239,9 @@ desc="Not implemented yet"), "digDeleteLine": MetaIcon (img=icons_img["digDeleteLine"], label="Delete line", desc="Left: Select; Middle: Unselect; Right: Confirm"), - "digDispAttr": MetaIcon (img=icons_img["digDispAttr"], label="Display attributes", + "digDispAttr": MetaIcon (img=icons_img["digDispAttr"], label="Display/update attributes", desc="Display attributes of given feature"), - "digDispCats": MetaIcon (img=icons_img["digDispCats"], label="Display categories", + "digDispCats": MetaIcon (img=icons_img["digDispCats"], label="Display/update categories", desc="Not implemented yet"), "digEditLine": MetaIcon (img=icons_img["digEditLine"], label="Edit line", desc="Not implemented yet"), From landa at grass.itc.it Mon Sep 10 10:04:11 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Mon Sep 10 17:45:07 2007 Subject: [grass-addons] r1086 - trunk/grassaddons/grassflyer/flyer1/cz Message-ID: <200709100804.l8A84BD7003592@grass.itc.it> Author: landa Date: 2007-09-10 10:04:10 +0200 (Mon, 10 Sep 2007) New Revision: 1086 Modified: trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex Log: Format LaTex code, little corrections... Update README_PDF file. Modified: trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt 2007-09-09 09:39:16 UTC (rev 1085) +++ trunk/grassaddons/grassflyer/flyer1/cz/README_PDF.txt 2007-09-10 08:04:10 UTC (rev 1086) @@ -1,8 +1,3 @@ PDF Version: -ISO A4 format: - http://www.geog.fu-berlin.de/~malte/flyer_v1.pdf - -Letter format: - http://www.geog.fu-berlin.de/~malte/grassflyer_letter.pdf - + http://gama.fsv.cvut.cz/data/grasswikicz/grassflyer-cz.pdf Modified: trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex 2007-09-09 09:39:16 UTC (rev 1085) +++ trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex 2007-09-10 08:04:10 UTC (rev 1086) @@ -1,16 +1,18 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %GRASS PROMOTION FLYER % %(c) 2007 GRASS PROMOTION TEAM % +%Translated from English version by Martin Landa % +% % %GNU Free Documentation License % %Version 1.2 % %Needs leaflet.cls % %www.ctan.org/tex-archive/macros/latex/contrib/leaflet/% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%Sometimes printing engines need the 2nd side upside down -%in this case, use tumble (which is default) instead of notumble -%If this causes problems, use notumble -%If you need a foldmark, delete nofoldmark +%Sometimes printing engines need the 2nd side upside down in this +% case, use tumble (which is default) instead of notumble If this +% causes problems, use notumble If you need a foldmark, delete +% nofoldmark \documentclass[notumble,a4paper,10pt,nofoldmark]{leaflet} \usepackage{helvet,courier,xcolor} \usepackage[utf8]{inputenc} @@ -29,7 +31,8 @@ aboveskip=0pt% } % Defining a new 'figure' environment for the document -\newenvironment{myfig}[1][0pt plus 1.5ex minus .5ex]{\par\vspace*{#1}\begin{minipage}{\textwidth}\centering}{\end{minipage}} +\newenvironment{myfig}[1][0pt plus 1.5ex minus +.5ex]{\par\vspace*{#1}\begin{minipage}{\textwidth}\centering}{\end{minipage}} % Defining the GRASS homepage \newcommand{\GRASSurl}{\url{http://grass.itc.it}} @@ -43,7 +46,7 @@ colorlinks=true,% urlcolor=darkblue,% Redefine this color to change URIs color pdfauthor={GRASS Community},% - pdftitle={GRASS GIS: U?innost Svodody \& Transparentnosti},% + pdftitle={GRASS GIS: Efektivita d?ky Svodod? \& Transparentnosti},% pdfsubject={GRASS propaga?n? let?k GRASS},% breaklinks=true,% plainpages=false% @@ -51,7 +54,7 @@ % Title page stuff \title{\textbf{\huge GRASS GIS}\\% -\textsl{U?innost Svodody \& Transparentnosti}} +\textsl{Efektivita d?ky Svodod? \& Transparentnosti}} \author{Komunita GRASSu} \date{\includegraphics[width=\textwidth]{grasslogo_vector}\\[2ex] \large\GRASSurl} @@ -65,33 +68,53 @@ \section{Co je GRASS} -GRASS (Geographic Resources Analysis Support System) je svobodn?/Open Source software ur?en? pro prostorov? anal?zy. Obsahuje v?ce ne? 350 modul? pro zpracov?n? 2D/3D vektorov?ch a rastrov?ch dat. Nab?z? ?adu rozhran? k dal??m program?m v dan? oblasti jako je geostatistika, datab?ze, mapov? slu?by a dokonce i k dal??m GIS aplikac?m. Je nejrozs?hlej??m Open Source GISem. M??e slou?it jako Desktop GIS ?i jako p?te? kompletn? GIS infrastrukturu. +GRASS (Geographic Resources Analysis Support System) je Svobodn?/Open +Source Software ur?en? pro prostorov? anal?zy. Obsahuje v?ce ne? 350 +modul? pro zpracov?n? 2D/3D vektorov?ch a rastrov?ch dat. Nab?z? ?adu +rozhran? k dal??m program?m v dan? oblasti jako je geostatistika, +datab?ze, mapov? slu?by a dokonce i k dal??m GIS aplikac?m. Je +nej-rozs?hlej??m Open Source GISem. M??e slou?it jako Desktop GIS ?i +jako p?te? kompletn? GIS infrastruktury. \section{Kde je GRASS pou??v?n} -GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? spr?v? po cel?m sv?t?. GRASS pokytuje v mnoha p?ipadech velk? potenci?l pro ?e?en? geoprostorov?ch ?loh. +GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? +spr?v? po cel?m sv?t?. GRASS poskytuje v mnoha p?ipadech velk? +potenci?l pro ?e?en? geoprostorov?ch ?loh. \section{Historie} -GRASS byl p?vodn? vyv?jen od po??tku 80-t?ch let agenturou US Army Construction Engineering Research Laboratories (USA-CERL) a byl poskytnut jako public domain software. V okam?iku kdy USA-CERL upustil od v?voje, vzniknul mezin?rodn? t?m v?voj??? kter? d?l software vyv?j?. Od roku 1999 je GRASS uvoln?n jako free software pod licenc? GNU General Public Licence. +GRASS byl p?vodn? vyv?jen od po??tku 80-t?ch let agenturou US Army +Construction Engineering Research Laboratories (USA-CERL) a byl +poskytnut jako public domain software. V okam?iku kdy USA-CERL upustil +od v?voje, vznikl mezin?rodn? t?m v?voj???, kter? d?l software +vyv?j?. Od roku 1999 je GRASS uvoln?n jako Free Software pod licenc? +GNU General Public Licence. \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{visibility} -\captionof{figure}{Anal?za viditelnost provedena v GRASSu} +\captionof{figure}{Anal?za viditelnost provedena pomoc? GRASSu} \end{myfig} \section{Filozofie Open Source} -Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do zdrovov?ch k?du a struktury programu, obrovskou m?ru transparentnosti. U?ivatel m??e roz???it program dle sv?ch pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez nutnosti zdrovov?ho k?du GRASSu. +Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do +zdrovov?ch k?du a struktury programu, obrovskou m?ru +transparentnosti. U?ivatel m??e roz???it program dle sv?ch +pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho +kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez +nutnosti zdrovov?ho k?du GRASSu. \section{Technick? data} \subsection{Licence} -V?eobecn? ve?ejn? licence GNU (GNU General Public License, Free Software Foundation) +V?eobecn? ve?ejn? licence GNU (GNU General Public License, Free +Software Foundation). \subsection{Podporovan? platformy} -GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? syst?my podporuj?c? Posix, MS-Windows a MacOS X. +GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? +syst?my podporuj?c? Posix, MS-Windows a MacOS X. \subsection{Design} @@ -112,7 +135,7 @@ \subsection{Mo?nosti spr?vy dat} \begin{itemize} -\item Zpracov?n? rasterov?ch / vektorov?ch / voxel dat +\item Zpracov?n? rastrov?ch / vektorov?ch / voxel dat \item Modelov?n? 2D / 3D rastrov?ch / vektorov?ch dat \item Zpracov?n? obrazov?ch dat \item Vektorov? topologie / S??ov? anal?zy @@ -126,27 +149,33 @@ \section{Podporovan? datov? form?ty} -GRASS podporuje t?m?? v?echny dob?e zn?m? GIS datov? form?ty d?ky knihovn? GDAL/OGR. Nav?c podporuje Open GIS Consortium's Simple Features. +GRASS podporuje t?m?? v?echny dob?e zn?m? GIS datov? form?ty d?ky +knihovn? GDAL/OGR. Nav?c podporuje Open GIS Consortium's Simple +Features. \subsection{Vektorov? datov? form?ty} -ASCII, ARC/INFO ungenerate, ARC/INFO E00, Arc\-View SHAPE, BIL, DLG (U.S.), DXF, DXF3D, GMT, GPS-ASCII USGS-DEM, IDRISI, MOSS, MapInfo MIF, TIGER, VRML, \dots +ASCII, ARC/INFO ungenerate, ARC/INFO E00, Arc\-View SHAPE, BIL, DLG +(U.S.), DXF, DXF3D, GMT, GPS-ASCII USGS-DEM, IDRISI, MOSS, MapInfo +MIF, TIGER, VRML, \dots \subsection{Rastrov? datov? form?ty} ASCII, ARC/GRID, E00, GIF, GMT, TIF, PNG, Vis5D, SURFER (.grd),\dots \begin{myfig} \includegraphics[width=0.7\textwidth]{isodist} -\captionof{figure}{V?choz? konfigurace GUI ukazuj?c? mo?nosti GRASSu pro s??ov? anal?zy} +\captionof{figure}{V?choz? konfigurace GUI demonstruj?c? mo?nosti + GRASSu pro s??ov? anal?zy} \end{myfig} \subsection{Obrazov? datov? form?ty} -CEOS (SAR, SRTM, LANDSAT7 etc.), ERDAS LAN / IMG, HDF, LANDSAT TM/MSS, NHAP aerial photos, SAR, SPOT, \dots +CEOS (SAR, SRTM, LANDSAT7 a pod.), ERDAS LAN / IMG, HDF, LANDSAT +TM/MSS, NHAP leteck? sn?mky, SAR, SPOT, \dots \begin{myfig}[1.5ex] \includegraphics[width=0.7\textwidth]{ndvi} -\captionof{figure}{Mo?nosti GRASS ve zpracov?n? obrazov?ch dat} +\captionof{figure}{Mo?nosti GRASSu ve zpracov?n? obrazov?ch dat} \end{myfig} -\subsection{Podpora databaz?} +\subsection{Podpora datab?z?} \begin{itemize} \item PostgreSQL / PostGIS @@ -164,13 +193,13 @@ %\item{GMT export} %item{VRML} \item VTK, POVray -\item WebGIS pomoc? Mapserver, Python, a pod. +\item WebGIS s vyu?it?m Mapserveru, Pythonu, a pod. \end{itemize} \subsection{Interoperabilita v??i dal??m GIS program?m} \begin{itemize} -\item Quantum GIS (Free Geodata (nejen) prohl??e?) +\item Quantum GIS (Free prohl??e? geodat) \item R- Language (statistika) \item Gstat (geostatistika) \item UMN Mapserver (webov? slu?by) @@ -183,14 +212,17 @@ \item{Webov? str?nky projektu: \\\GRASSurl} \item{GRASS Wiki: \\\url{http://grass.gdf.hannover.de/wiki}} \item{Propaga?n? t?m GRASSu: \\\url{malte@perlomat.de}} -\item{Elektronick? konference GRASSu: \\\url{http://grass.itc.it/community/support.php}} +\item{Elektronick? konference GRASSu: + \\\url{http://grass.itc.it/community/support.php}} %\end{flushleft} \end{itemize} \vfill \section{OSGeo} -GRASS je zakl?daj?c?m projektem Open Source Geospatial Foundation, kter? si klade za c?l tvorbu vysoce kvalitn?ho Open Source GIS software. Pro dal?? informace nav?tivte domovskou str?nku OSGeo: +GRASS je zakl?daj?c?m projektem Open Source Geospatial Foundation, +kter? si klade za c?l tvorbu vysoce kvalitn?ho Open Source GIS +software. Pro dal?? informace nav?tivte domovskou str?nku OSGeo: \begin{center} \includegraphics[width=0.8\textwidth]{OSGeo_CMYK}\\ \url{http://www.osgeo.org} From landa at grass.itc.it Wed Sep 12 11:32:14 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Sep 12 11:32:15 2007 Subject: [grass-addons] r1088 - trunk/grassaddons/grassflyer/flyer1/cz Message-ID: <200709120932.l8C9WECi011863@grass.itc.it> Author: landa Date: 2007-09-12 11:32:13 +0200 (Wed, 12 Sep 2007) New Revision: 1088 Modified: trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex Log: Typo fixed Modified: trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex =================================================================== --- trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex 2007-09-10 11:52:03 UTC (rev 1087) +++ trunk/grassaddons/grassflyer/flyer1/cz/grassflyer.tex 2007-09-12 09:32:13 UTC (rev 1088) @@ -46,7 +46,7 @@ colorlinks=true,% urlcolor=darkblue,% Redefine this color to change URIs color pdfauthor={GRASS Community},% - pdftitle={GRASS GIS: Efektivita d?ky Svodod? \& Transparentnosti},% + pdftitle={GRASS GIS: Efektivita d?ky Svobod? \& Transparentnosti},% pdfsubject={GRASS propaga?n? let?k GRASS},% breaklinks=true,% plainpages=false% @@ -54,7 +54,7 @@ % Title page stuff \title{\textbf{\huge GRASS GIS}\\% -\textsl{Efektivita d?ky Svodod? \& Transparentnosti}} +\textsl{Efektivita d?ky Svobod? \& Transparentnosti}} \author{Komunita GRASSu} \date{\includegraphics[width=\textwidth]{grasslogo_vector}\\[2ex] \large\GRASSurl} @@ -79,7 +79,7 @@ \section{Kde je GRASS pou??v?n} GRASS je pou??v?n ve v?deck?ch aplikac?ch, komer?n? ?i ve ve?ejn? -spr?v? po cel?m sv?t?. GRASS poskytuje v mnoha p?ipadech velk? +spr?v? po cel?m sv?t?. GRASS poskytuje v mnoha p??padech velk? potenci?l pro ?e?en? geoprostorov?ch ?loh. \section{Historie} @@ -98,11 +98,11 @@ \section{Filozofie Open Source} Filozofie Open Source nab?z? u?ivateli mo?nost nahl?dnut? do -zdrovov?ch k?du a struktury programu, obrovskou m?ru +zdrojov?ch k?du a struktury programu, obrovskou m?ru transparentnosti. U?ivatel m??e roz???it program dle sv?ch pot?eb. Vz?jemn? kontrola zdrojov?ho k?du zvy?uje jeho kvalitu. Tzv. extension manager umo??uje vytv??et nov? moduly bez -nutnosti zdrovov?ho k?du GRASSu. +nutnosti zdrojov?ho k?du GRASSu. \section{Technick? data} @@ -113,7 +113,7 @@ \subsection{Podporovan? platformy} -GRASS b??? na t?me? v?ech platform?ch. Podporuje GNU/Linux, unixov? +GRASS b??? na t?m?? v?ech platform?ch. Podporuje GNU/Linux, unixov? syst?my podporuj?c? Posix, MS-Windows a MacOS X. \subsection{Design} From neteler at grass.itc.it Fri Sep 14 11:19:16 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Fri Sep 14 11:19:18 2007 Subject: [grass-addons] r1089 - trunk/grassaddons/gui/gui_modules Message-ID: <200709140919.l8E9JGLI020924@grass.itc.it> Author: neteler Date: 2007-09-14 11:19:16 +0200 (Fri, 14 Sep 2007) New Revision: 1089 Modified: trunk/grassaddons/gui/gui_modules/menudata.py Log: typo Modified: trunk/grassaddons/gui/gui_modules/menudata.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menudata.py 2007-09-12 09:32:13 UTC (rev 1088) +++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-09-14 09:19:16 UTC (rev 1089) @@ -499,7 +499,7 @@ ("3D MASK", "Create 3D mask for grid3D operations", "self.OnMenuCmd", "r3.mask"), ("3D map calculator", "Map calculator for volumetric map algebra", "self.OnMenuCmd", "r3.mapcalculator"), ("Cross section", "Create 2D raster cross section from grid3d volume", "self.OnMenuCmd", "r3.cross.rast"), - ("Interpoloate volume from points", "Interpolate volume from vector points using splines", "self.OnMenuCmd", "v.vol.rst"), + ("Interpolate volume from points", "Interpolate volume from vector points using splines", "self.OnMenuCmd", "v.vol.rst"), ("","","", ""), ("Report and Statistics", ( ("Basic volume information", "Report basic information about grid3D volume", "self.OnMenuCmd", "r3.info"), From neteler at grass.itc.it Fri Sep 14 11:34:38 2007 From: neteler at grass.itc.it (neteler@grass.itc.it) Date: Fri Sep 14 11:34:40 2007 Subject: [grass-addons] r1090 - trunk/grassaddons/gui/gui_modules Message-ID: <200709140934.l8E9YcHH021001@grass.itc.it> Author: neteler Date: 2007-09-14 11:34:38 +0200 (Fri, 14 Sep 2007) New Revision: 1090 Modified: trunk/grassaddons/gui/gui_modules/render.py Log: fixed white-space-in-path quote problem Modified: trunk/grassaddons/gui/gui_modules/render.py =================================================================== --- trunk/grassaddons/gui/gui_modules/render.py 2007-09-14 09:19:16 UTC (rev 1089) +++ trunk/grassaddons/gui/gui_modules/render.py 2007-09-14 09:34:38 UTC (rev 1090) @@ -607,13 +607,13 @@ opacstr = repr(",".join(opacities)) # compose command - compcmd = "g.pnmcomp in=" + mapstr + \ - " mask=" + maskstr + \ - " opacity=" + opacstr + \ + compcmd = "g.pnmcomp in='" + mapstr + \ + "' mask='" + maskstr + \ + "' opacity=" + opacstr + \ " background=255:255:255" + \ " width=" + str(self.width) + \ " height=" + str(self.height) + \ - " output=" + self.mapfile + " output='" + self.mapfile + "'" # render overlays @@ -624,7 +624,7 @@ # run g.composite to get composite image if os.system(compcmd): - sys.stderr.write("Could not run g.pnmcomp\n") + sys.stderr.write("Could not run g.pnmcomp [%s]\n" % compcmd) raise Exception (compcmd) Debug.msg (2, "Map.Render() force=%s file=%s" % (force, self.mapfile)) From calvelo at grass.itc.it Fri Sep 14 19:30:00 2007 From: calvelo at grass.itc.it (calvelo@grass.itc.it) Date: Fri Sep 14 19:30:02 2007 Subject: [grass-addons] r1091 - trunk/grassaddons/gui/gui_modules Message-ID: <200709141730.l8EHU0dr026279@grass.itc.it> Author: calvelo Date: 2007-09-14 19:29:54 +0200 (Fri, 14 Sep 2007) New Revision: 1091 Modified: trunk/grassaddons/gui/gui_modules/toolbox.py Log: - Begin work on other more esoteric parameters: file added Modified: trunk/grassaddons/gui/gui_modules/toolbox.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbox.py 2007-09-14 09:34:38 UTC (rev 1090) +++ trunk/grassaddons/gui/gui_modules/toolbox.py 2007-09-14 17:29:54 UTC (rev 1091) @@ -133,7 +133,7 @@ self.task.description = self.description menuform.GrassGUIApp( self.task ).MainLoop() - def handleOption( self, opt, getit = menuform.grassTask.get_param ): + def handleOption( self, opt, getit = menuform.grassTask.get_param, **other ): a = dict(opt.attributes.items()) p = getit( self.task, a['key'] ) # visibility: @@ -143,6 +143,8 @@ # overrides: if a.has_key( 'answer' ): p['value'] = a['answer'] if a.has_key( 'label' ): p['description'] = a['label'] + for (k,i) in other.items(): + p[k] = i # exclusions: if a.has_key('exclude'): vals = p['value'].split(',') @@ -160,7 +162,12 @@ if tag == 'field': pass elif tag == 'file': - pass + filters = dict(opt.attributes.items()).get('filters','(*.*)') + try: + glob = re.match(r'\((.+)\)').groups(0) + except KeyError: + glob = '*.*' + self.handleOption( opt, gisprompt=True, element='file', filemask=glob ) elif tag == 'selection': pass From landa at grass.itc.it Sun Sep 16 13:28:20 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 16 13:28:22 2007 Subject: [grass-addons] r1092 - trunk/grassaddons/gui/screenshots Message-ID: <200709161128.l8GBSKgF018473@grass.itc.it> Author: landa Date: 2007-09-16 12:48:15 +0200 (Sun, 16 Sep 2007) New Revision: 1092 Added: trunk/grassaddons/gui/screenshots/aui-toolbars.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/wxgrass-2007-03-mac.png trunk/grassaddons/gui/screenshots/wxgrass-2007-05-linux.png Removed: trunk/grassaddons/gui/screenshots/wxgrass-aui-toolbars.png trunk/grassaddons/gui/screenshots/wxgrass63-2007-05.png trunk/grassaddons/gui/screenshots/wxgrass_20-03-2007.jpeg Log: screenshot cleaning: rename some files, add new files Added: trunk/grassaddons/gui/screenshots/aui-toolbars.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/aui-toolbars.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-01.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-01.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-02.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-02.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-03.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-03.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/wxgrass-2007-03-mac.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/wxgrass-2007-03-mac.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/wxgrass-2007-05-linux.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/wxgrass-2007-05-linux.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Deleted: trunk/grassaddons/gui/screenshots/wxgrass-aui-toolbars.png =================================================================== (Binary files differ) Deleted: trunk/grassaddons/gui/screenshots/wxgrass63-2007-05.png =================================================================== (Binary files differ) Deleted: trunk/grassaddons/gui/screenshots/wxgrass_20-03-2007.jpeg =================================================================== (Binary files differ) From ullah at grass.itc.it Wed Sep 19 21:10:44 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Wed Sep 19 21:10:46 2007 Subject: [grass-addons] r1093 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709191910.l8JJAibn026567@grass.itc.it> Author: ullah Date: 2007-09-19 21:10:38 +0200 (Wed, 19 Sep 2007) New Revision: 1093 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: changed linear regression for application of the "m" and "n" coefficients in the fllow calculations. updated color rules ofr net change, and added color rules for soildepths. Note that it may now be advisble to run the simulation with terraflow instead of r.flow (check the appropriate flag in the flow panel), and after some more testing, this may become the default option. Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-16 10:48:15 UTC (rev 1092) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-19 19:10:38 UTC (rev 1093) @@ -140,14 +140,22 @@ #% guisection: Variables #%end #%option -#% key: cutoff +#% key: cutoff1 #% type: string #% description: Flow accumultion breakpoint value for shift from diffusion to overland flow (number of cells) -#% answer: 8 +#% answer: 4 #% required : yes #% guisection: Variables #%end #%option +#% key: cutoff2 +#% type: string +#% description: Flow accumultion breakpoint value for shift from overland flow to channelized flow (number of cells) +#% answer: 50 +#% required : yes +#% guisection: Variables +#%end +#%option #% key: number #% type: integer #% description: number of iterations to run @@ -189,14 +197,6 @@ #% required : yes #% guisection: Smoothing_Filter #%end -# #%option -# #% key: sigma -# #% type: string -# #% description: Band-pass filter threshold value, sigma (meters) -# #% answer: 0.10 -# #% required : yes -# #% guisection: Smoothing_Filter -# #%end #%option #% key: method #% type: string @@ -295,7 +295,8 @@ aplpha=$GIS_OPT_method sigma=$GIS_OPT_sigma nbhood=$GIS_OPT_nbhood -cutoff=$GIS_OPT_cutoff +cutoff1=$GIS_OPT_cutoff1 +cutoff2=$GIS_OPT_cutoff2 number=$GIS_OPT_number echo "total number of iterations to be run= $number" echo "" @@ -562,29 +563,23 @@ else -maxflow=`eval r.univar -g map=$flowacc percentile=90 | grep "max=" | cut -d"=" -f2` -minflow=`eval r.univar -g map=$flowacc percentile=90 | grep "min=" | cut -d"=" -f2` +maxflow=`eval r.info -r map=$flowacc | grep "max=" | cut -d"=" -f2` + echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +echo "The raw max ($maxflow) flow accumulation, min cutoff $cutoff1, and middle cutoff $cutoff2 will be used to scale flow exponents 'm' and 'n' as flow progresses in the drainage network" echo "" -echo "" -echo "Calculating with appropriate flow types on different landforms" +echo "" +echo "calculating with appropriate flow types on different landforms" -r.mapcalc "$m=1+($flowacc * (0.3/($maxflow - $minflow)))" -r.mapcalc "$n=1+($flowacc * (0.15/($maxflow - $minflow)))" +r.mapcalc "$m=if($flowacc > $cutoff2, 1.6, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.6/($cutoff2 - $cutoff1)))), 1))" -report1=`eval r.info -r map=$m | grep "max=" | cut -d"=" -f2` -report2=`eval r.info -r map=$m | grep "min=" | cut -d"=" -f2` +r.mapcalc "$n=if($flowacc > $cutoff2,1.3, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.3/($cutoff2 - $cutoff1)))), 1))" -echo "" -echo "(for diagnostics only) max m = $report1, min m = $report2" +r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff1, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" - - fi echo "" @@ -692,21 +687,22 @@ # create temporary file to code colors for $netchange -# create temporary file to list all the smoothdz files for statistics TMP1=`g.tempfile pid=$$` if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file to list all the netchange files for statistics" 1>&2 + echo "ERROR: unable to create temporary file for netchange colors" 1>&2 exit 1 fi + + echo "100% 0 0 100" > $TMP1 -echo "2 blue" >> $TMP1 +echo "1 blue" >> $TMP1 echo "0.5 indigo" >> $TMP1 -echo "0.1 green" >> $TMP1 +echo "0.01 green" >> $TMP1 echo "0 white" >> $TMP1 -echo "-0.1 yellow" >> $TMP1 +echo "-0.01 yellow" >> $TMP1 echo "-0.5 orange" >> $TMP1 -echo "-2 red" >> $TMP1 +echo "-1 red" >> $TMP1 echo "0% 150 0 50" >> $TMP1 @@ -714,7 +710,30 @@ fi +# create temporary file to code colors for $soildepth +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for soil colors" 1>&2 + exit 1 +fi + + + +echo "100% 0 0 100" > $TMP4 +echo "10 blue" >> $TMP4 +echo "5 indigo" >> $TMP4 +echo "1 green" >> $TMP4 +echo "0.1 yellow" >> $TMP4 +echo "0.03 orange" >> $TMP4 +echo "0.01 red" >> $TMP4 +echo "0.001 150 0 50" >> $TMP4 +echo "0 white" >> $TMP4 + +r.colors --quiet map=$new_soil rules=$TMP4 + +fi + if [ $GIS_FLAG_b -eq 1 ]; then echo "" @@ -747,13 +766,39 @@ r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" -fi - - #these are the old soil equations that I failed to be able to implement... I leave them in for documentation purposes #r.mapcalc "$new_bdrk=$initbdrk - ($Ba * ($Bb*($smoothdz - $initbdrk)))" #r.mapcalc "$new_soil=if (($smoothdz - $initbdrk) < 0, 0, ($smoothdz - $initbdrk))" +fi + + +# create temporary file to code colors for $soildepth + +TMP4=`g.tempfile pid=$$` +if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for soil colors" 1>&2 + exit 1 +fi + + + +echo "100% 0 0 100" > $TMP4 +echo "10 blue" >> $TMP4 +echo "5 indigo" >> $TMP4 +echo "1 green" >> $TMP4 +echo "0.1 yellow" >> $TMP4 +echo "0.03 orange" >> $TMP4 +echo "0.01 red" >> $TMP4 +echo "0.001 150 0 50" >> $TMP4 +echo "0 white" >> $TMP4 + +r.colors --quiet map=$new_soil rules=$TMP4 + +fi + + + #grabsomestats tmperosion=$prfx"tmperosion"$num tmpdep=$prfx"tmpdep"$num @@ -1050,22 +1095,22 @@ else -maxflow=`eval r.univar -g map=$flowacc percentile=90 | grep "max=" | cut -d"=" -f2` -minflow=`eval r.univar -g map=$flowacc percentile=90 | grep "min=" | cut -d"=" -f2` +maxflow=`eval r.info -r map=$flowacc | grep "max=" | cut -d"=" -f2` echo "" -echo "The raw max ($maxflow) and min ($minflow) flow accumulation will be used to scale flow exponents 'm' and 'n' " +echo "The raw max ($maxflow) flow accumulation, min cutoff $cutoff1, and middle cutoff $cutoff2 will be used to scale flow exponents 'm' and 'n' as flow progresses in the drainage network" echo "" echo "" echo "calculating with appropriate flow types on different landforms" -r.mapcalc "$m=1+($flowacc * (0.6/($maxflow - $minflow)))" -r.mapcalc "$n=1+($flowacc * (0.3/($maxflow - $minflow)))" +r.mapcalc "$m=if($flowacc > $cutoff2, 1.6, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.6/($cutoff2 - $cutoff1)))), 1))" -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" +r.mapcalc "$n=if($flowacc > $cutoff2,1.3, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.3/($cutoff2 - $cutoff1)))), 1))" +r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff1, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" + fi @@ -1190,13 +1235,16 @@ r.mapcalc "$new_bdrk=$old_bdrk - $rate" r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" -fi - #these are the old soil equations that I failed to be able to implement... I leave them in for documentation purposes #r.mapcalc "$new_bdrk= $old_bdrk - ($Ba * (exp(($smoothdz - $old_bdrk),$Bb)))" #r.mapcalc "$new_soil=if (($smoothdz - $old_bdrk) < 0, 0, ($smoothdz - $old_bdrk))" +fi +#setting colors to our rules +r.colors --quiet map=$new_soil rules=$TMP4 + + #grabsomestats tmperosion=$prfx"_tmperosion"$step tmpdep=$prfx"_tmpdep"$step @@ -1388,11 +1436,11 @@ fi -#remove color file +#remove temporary color rule files \rm -f $TMP1 +\rm -f $TMP4 - if [ "$GIS_FLAG_z" -eq 1 ]; then echo "" echo "Iterations complete, keeping region set to output maps" From ullah at grass.itc.it Wed Sep 19 22:32:31 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Wed Sep 19 22:32:32 2007 Subject: [grass-addons] r1094 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709192032.l8JKWVxZ028087@grass.itc.it> Author: ullah Date: 2007-09-19 22:32:25 +0200 (Wed, 19 Sep 2007) New Revision: 1094 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: small error fix Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-19 19:10:38 UTC (rev 1093) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-19 20:32:25 UTC (rev 1094) @@ -732,7 +732,6 @@ r.colors --quiet map=$new_soil rules=$TMP4 -fi if [ $GIS_FLAG_b -eq 1 ]; then From ullah at grass.itc.it Thu Sep 20 01:23:52 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Sep 20 01:23:55 2007 Subject: [grass-addons] r1095 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709192323.l8JNNqOl029944@grass.itc.it> Author: ullah Date: 2007-09-20 01:23:47 +0200 (Thu, 20 Sep 2007) New Revision: 1095 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: another small bug fix Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-19 20:32:25 UTC (rev 1094) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-19 23:23:47 UTC (rev 1095) @@ -629,7 +629,7 @@ if [ "$GIS_FLAG_y" -eq 1 ]; then -echo ""echo "You have selected not to smooth your files... Oh Well!" +echo "You have selected not to smooth your files... Oh Well!" echo "" r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" @@ -712,27 +712,8 @@ # create temporary file to code colors for $soildepth -TMP4=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then - echo "ERROR: unable to create temporary file for soil colors" 1>&2 - exit 1 -fi - -echo "100% 0 0 100" > $TMP4 -echo "10 blue" >> $TMP4 -echo "5 indigo" >> $TMP4 -echo "1 green" >> $TMP4 -echo "0.1 yellow" >> $TMP4 -echo "0.03 orange" >> $TMP4 -echo "0.01 red" >> $TMP4 -echo "0.001 150 0 50" >> $TMP4 -echo "0 white" >> $TMP4 - -r.colors --quiet map=$new_soil rules=$TMP4 - - if [ $GIS_FLAG_b -eq 1 ]; then echo "" @@ -794,7 +775,6 @@ r.colors --quiet map=$new_soil rules=$TMP4 -fi @@ -1045,7 +1025,7 @@ echo "" echo "calculating for channelzed flow across the entire map" - r.mapcalc "$sflowtopo=exp(($flowacc),$m) * exp(sin($slope),$n)" + r.mapcalc "$sflowtopo=exp(($flowacc),1.6) * exp(sin($slope),1.3)" elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 0 ] @@ -1186,7 +1166,7 @@ #put the net dz back where it is upposed to go and then subtract it from dem to make new dem -r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, x)))" +r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, x)))" #make $netchange if asked if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 0 -o "$GIS_FLAG_t" -eq 0 ]; then From landa at grass.itc.it Sat Sep 22 14:42:55 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sat Sep 22 14:42:56 2007 Subject: [grass-addons] r1096 - trunk/grassaddons/gui/screenshots Message-ID: <200709221242.l8MCgtFZ032638@grass.itc.it> Author: landa Date: 2007-09-22 14:41:29 +0200 (Sat, 22 Sep 2007) New Revision: 1096 Added: 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 Log: new screenshots added (digit) Added: trunk/grassaddons/gui/screenshots/digit-attributes.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-attributes.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-gism.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-gism.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-mapdisplay.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-mapdisplay.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-move.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-move.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-new-feature.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-new-feature.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-settings-1.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-settings-1.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/digit-settings.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/digit-settings.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/gism-0.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/gism-0.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/screenshots/mapdisplay-0.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/screenshots/mapdisplay-0.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From landa at grass.itc.it Sat Sep 22 14:49:01 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sat Sep 22 14:49:03 2007 Subject: [grass-addons] r1097 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709221249.l8MCn15k000345@grass.itc.it> Author: landa Date: 2007-09-22 14:48:55 +0200 (Sat, 22 Sep 2007) New Revision: 1097 Modified: trunk/grassaddons/gui/display_driver/driver.cc trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Various fixes for dialog 'Display categories' Modified: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-22 12:41:29 UTC (rev 1096) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-22 12:48:55 UTC (rev 1097) @@ -86,6 +86,7 @@ return -1; int nlines; + BOUND_BOX mapBox; struct ilist *listLines; // initialize @@ -95,16 +96,39 @@ /* nlines = Vect_get_num_lines(mapInfo); */ + Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); + Vect_build(mapInfo, stderr); + // draw lines inside of current display region - nlines = Vect_select_lines_by_box(mapInfo,&(region.box), + nlines = Vect_select_lines_by_box(mapInfo, &(region.box), GV_POINTS | GV_LINES, // fixme listLines); + Vect_get_map_box(mapInfo, &mapBox); + nlines = Vect_select_lines_by_box(mapInfo, &mapBox, + GV_POINTS | GV_LINES, // fixme + listLines); + for (int i = 0; i < listLines->n_values; i++) { DrawLine(listLines->value[i]); } #ifdef DEBUG + std::cout << "region: W=" << region.box.W + << "; E=" << region.box.E + << "; S=" << region.box.S + << "; N=" << region.box.N << std::endl; + + std::cout << "-> nlines=" << nlines << std::endl; +#endif + + /* + nlines = Vect_get_num_lines(mapInfo); + for (int line = 1; line <= nlines; line++) { + DrawLine(line); + } + */ +#ifdef DEBUG PrintIds(); #endif Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-22 12:41:29 UTC (rev 1096) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-22 12:48:55 UTC (rev 1097) @@ -37,7 +37,7 @@ import wx.lib.mixins.listctrl as listmix import grassenv -import cmd +import gcmd as cmd from debug import Debug as Debug class Log: @@ -619,10 +619,11 @@ if (self.layer == -1 and len(layers) <= 0) or \ (self.layer > 0 and self.layer not in layers): if self.layer == -1: - label = "Database connection for vector map <%s> " - "is not defined in DB file" % self.map + label = "Database connection for vector map <%s> " \ + "is not defined in DB file." % (self.map) else: - label = "Layer <%d> is not available for vector map <%s>" % self.map + label = "Layer <%d> is not available for vector map <%s>." % \ + (self.layer, self.map) dlg = wx.MessageDialog(None, _("No attribute table found.\n" Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-22 12:41:29 UTC (rev 1096) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-22 12:48:55 UTC (rev 1097) @@ -34,6 +34,7 @@ import os import sys import string +import copy import wx import wx.lib.colourselect as csel @@ -1263,7 +1264,11 @@ def __init__(self, parent, title, map, queryCoords, qdist, pos=wx.DefaultPosition, - style=wx.DEFAULT_DIALOG_STYLE): + style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): + + # parent + self.parent = parent # mapdisplay.BufferedWindow class instance + # map name self.map = map @@ -1272,53 +1277,198 @@ # {layer: [categories]} self.cats = {} - - # do not display dialog if no line is found + # do not display dialog if no line is found (-> self.cats) if self.__GetCategories(queryCoords, qdist) == 0 or not self.line: Debug.msg(3, "DigitCategoryDialog(): nothing found!") return + + # make copy of cats (used for 'reload') + self.cats_orig = copy.deepcopy(self.cats) Debug.msg(3, "DigitCategoryDialog(): line=%d, cats=%s" % \ (self.line, self.cats)) - wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style) + wx.Dialog.__init__(self, parent=self.parent, id=wx.ID_ANY, title=title, style=style) - self.parent = parent # mapdisplay.BufferedWindow class instance - - # list - listSizer = wx.BoxSizer(wx.VERTICAL) + # list of categories + box = wx.StaticBox(parent=self, id=wx.ID_ANY, + label=" %s " % _("List of categories")) + listSizer = wx.StaticBoxSizer(box, wx.VERTICAL) self.list = CategoryListCtrl(parent=self, id=wx.ID_ANY, style=wx.LC_REPORT | wx.BORDER_NONE | - wx.LC_SORT_ASCENDING) + wx.LC_SORT_ASCENDING | + wx.LC_HRULES | + wx.LC_VRULES) listSizer.Add(item=self.list, proportion=1, flag=wx.EXPAND) + # add new category + box = wx.StaticBox(parent=self, id=wx.ID_ANY, + label=" %s " % _("Add new category")) + addSizer = wx.StaticBoxSizer(box, wx.VERTICAL) + flexSizer = wx.FlexGridSizer (cols=5, hgap=5, vgap=5) + flexSizer.AddGrowableCol(3) + + layerNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY, + label="%s:" % _("Layer")) + self.layerNew = wx.TextCtrl(parent=self, id=wx.ID_ANY, size=(50, -1), + value="1") + catNewTxt = wx.StaticText(parent=self, id=wx.ID_ANY, + label="%s:" % _("Category")) + try: + newCat = max(self.cats[1]) + 1 + except: + newCat = 1 + self.catNew = wx.TextCtrl(parent=self, id=wx.ID_ANY, size=(50, -1), + value=str(newCat)) + btnAddCat = wx.Button(self, wx.ID_ADD) + flexSizer.Add(item=layerNewTxt, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(item=self.layerNew, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(item=catNewTxt, proportion=0, + flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT, + border=10) + flexSizer.Add(item=self.catNew, proportion=0, + flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL) + flexSizer.Add(item=btnAddCat, proportion=0, + flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.FIXED_MINSIZE) + addSizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=5) + # buttons - btnApply = wx.Button(self, wx.ID_APPLY, _("Apply") ) + btnApply = wx.Button(self, wx.ID_APPLY) btnCancel = wx.Button(self, wx.ID_CANCEL) - btnOk = wx.Button(self, wx.ID_OK, _("OK") ) + btnReload = wx.Button(self, wx.ID_UNDO, _("Reload")) + btnOk = wx.Button(self, wx.ID_OK) btnOk.SetDefault() - # bindigs - btnApply.Bind(wx.EVT_BUTTON, self.OnApply) - btnOk.Bind(wx.EVT_BUTTON, self.OnOK) - # sizers btnSizer = wx.StdDialogButtonSizer() btnSizer.AddButton(btnCancel) + btnSizer.AddButton(btnReload) + btnSizer.SetNegativeButton(btnReload) btnSizer.AddButton(btnApply) btnSizer.AddButton(btnOk) btnSizer.Realize() mainSizer = wx.BoxSizer(wx.VERTICAL) - mainSizer.Add(item=listSizer, proportion=0, + mainSizer.Add(item=listSizer, proportion=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) + mainSizer.Add(item=addSizer, proportion=0, + flag=wx.EXPAND | wx.ALIGN_CENTER | + wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5) mainSizer.Add(item=btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) self.SetSizer(mainSizer) mainSizer.Fit(self) + self.SetAutoLayout(True) + # set min size for dialog + self.SetMinSize(self.GetMinSize()) + + # bindings + # buttons + btnReload.Bind(wx.EVT_BUTTON, self.OnReload) + btnApply.Bind(wx.EVT_BUTTON, self.OnApply) + btnOk.Bind(wx.EVT_BUTTON, self.OnOK) + btnAddCat.Bind(wx.EVT_BUTTON, self.OnAddCat) + + # list + # self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) + + # self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) + self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp) #wxMSW + self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) #wxGTK + self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list) + self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit, self.list) + + def OnBeginEdit(self, event): + """Editing of item started""" + event.Allow() + + def OnEndEdit(self, event): + """Finish editing of item""" + itemIndex = event.GetIndex() + layerOld = int (self.list.GetItem(itemIndex, 0).GetText()) + catOld = int (self.list.GetItem(itemIndex, 1).GetText()) + + if event.GetColumn() == 0: + layerNew = int(event.GetLabel()) + catNew = catOld + else: + layerNew = layerOld + catNew = int(event.GetLabel()) + + try: + if layerNew not in self.cats.keys(): + self.cats[layerNew] = [] + self.cats[layerNew].append(catNew) + self.cats[layerOld].remove(catOld) + except: + event.Veto() + self.list.SetStringItem(itemIndex, 0, str(layerNew)) + self.list.SetStringItem(itemIndex, 1, str(catNew)) + dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%s/%s>.\n" + "Layer and category number must be integer.\n" + "Layer number must be greater then zero.") % + (str(self.layerNew.GetValue()), str(self.catNew.GetValue())), + _("Error"), wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return False + def OnRightDown(self, event): + """Mouse right button down""" + x = event.GetX() + y = event.GetY() + item, flags = self.list.HitTest((x, y)) + + if item != wx.NOT_FOUND and \ + flags & wx.LIST_HITTEST_ONITEM: + self.list.Select(item) + + event.Skip() + + def OnRightUp(self, event): + """Mouse right button up""" + if not hasattr(self, "popupID1"): + self.popupID1 = wx.NewId() + self.popupID2 = wx.NewId() + self.Bind(wx.EVT_MENU, self.OnItemDelete, id=self.popupID1) + self.Bind(wx.EVT_MENU, self.OnItemDeleteAll, id=self.popupID2) + + # generate popup-menu + menu = wx.Menu() + menu.Append(self.popupID1, _("Delete selected")) + menu.Append(self.popupID2, _("Delete all")) + + self.PopupMenu(menu) + menu.Destroy() + + def OnItemSelected(self, event): + """Item selected""" + event.Skip() + + def OnItemDelete(self, event): + """Delete selected item(s) from the list (layer/category pair)""" + item = self.list.GetFirstSelected() + while item != -1: + layer = int (self.list.GetItem(item, 0).GetText()) + cat = int (self.list.GetItem(item, 1).GetText()) + self.list.DeleteItem(item) + self.cats[layer].remove(cat) + + item = self.list.GetFirstSelected() + + event.Skip() + + def OnItemDeleteAll(self, event): + """Delete all items from the list""" + self.list.DeleteAllItems() + self.cats = [] + + event.Skip() + def __GetCategories(self, coords, qdist): """Get layer/category pairs for all available layers @@ -1348,14 +1498,83 @@ return True + def OnReload(self, event): + """Reload button clicked""" + # restore original list + self.cats = copy.deepcopy(self.cats_orig) + + # polulate list + self.list.Populate(update=True) + + event.Skip() + def OnApply(self, event): """Apply button clicked""" - self.Close() + # action : (catsFrom, catsTo) + check = {'catadd': (self.cats, self.cats_orig), + 'catdel': (self.cats_orig, self.cats)} + + # add/delete new category + for action, cats in check.iteritems(): + for layer in cats[0].keys(): + catList = "" + for cat in cats[0][layer]: + if layer not in cats[1].keys() or \ + cat not in cats[1][layer]: + catList += "%s," % cat + if catList != "": + catList = catList[:-1] # remove last comma + vEditCmd = ['v.edit', '--q', + 'map=%s' % self.map, + 'layer=%d' % layer, + 'tool=%s' % action, + 'cats=%s' % catList, + 'id=%d' % self.line] + + cmd.Command(vEditCmd) + + self.cats_orig = copy.deepcopy(self.cats) + + event.Skip() + def OnOK(self, event): """OK button clicked""" + self.OnApply(event) self.Close() + def OnAddCat(self, event): + """Button 'Add' new category clicked""" + try: + layer = int(self.layerNew.GetValue()) + cat = int(self.catNew.GetValue()) + if layer <= 0: + raise ValueError + except ValueError: + dlg = wx.MessageDialog(self, _("Unable to add new layer/category <%s/%s>.\n" + "Layer and category number must be integer.\n" + "Layer number must be greater then zero.") % + (str(self.layerNew.GetValue()), str(self.catNew.GetValue())), + _("Error"), wx.OK | wx.ICON_ERROR) + dlg.ShowModal() + dlg.Destroy() + return False + + if layer not in self.cats.keys(): + self.cats[layer] = [] + + self.cats[layer].append(cat) + + # reload list + self.list.Populate(update=True) + + # update category number for add + self.catNew.SetValue(str(cat + 1)) + + event.Skip() + + return True + def GetLine(self): """Get id of selected line of 'None' if no line is selected""" return self.line @@ -1367,19 +1586,36 @@ def __init__(self, parent, id, pos=wx.DefaultPosition, size=wx.DefaultSize, style=0): - + + self.parent = parent + wx.ListCtrl.__init__(self, parent, id, pos, size, style) listmix.ListCtrlAutoWidthMixin.__init__(self) self.Populate() listmix.TextEditMixin.__init__(self) - def Populate(self): + def Populate(self, update=False): """Populate the list""" - self.InsertColumn(0, _("Layer")) - self.InsertColumn(1, _("Category")) + if not update: + self.InsertColumn(0, _("Layer")) + self.InsertColumn(1, _("Category")) + else: + self.DeleteAllItems() - self.SetColumnWidth(0, 100) - self.SetColumnWidth(1, wx.LIST_AUTOSIZE) + i = 0 + for layer in self.parent.cats.keys(): + catsList = self.parent.cats[layer] + for cat in catsList: + index = self.InsertStringItem(sys.maxint, str(catsList[0])) + self.SetStringItem(index, 0, str(layer)) + self.SetStringItem(index, 1, str(cat)) + self.SetItemData(index, i) + i = i + 1 + if not update: + self.SetColumnWidth(0, 100) + self.SetColumnWidth(1, wx.LIST_AUTOSIZE) + self.currentItem = 0 + Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-22 12:41:29 UTC (rev 1096) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-22 12:48:55 UTC (rev 1097) @@ -571,7 +571,7 @@ if self.parent.statusText == "Extent": self.parent.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["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"], From landa at grass.itc.it Sat Sep 22 16:52:59 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sat Sep 22 16:53:01 2007 Subject: [grass-addons] r1098 - in trunk/grassaddons/gui: compat display_driver gui_modules icons images Message-ID: <200709221452.l8MEqxIG001643@grass.itc.it> Author: landa Date: 2007-09-22 16:52:53 +0200 (Sat, 22 Sep 2007) New Revision: 1098 Modified: trunk/grassaddons/gui/compat/ trunk/grassaddons/gui/display_driver/ trunk/grassaddons/gui/gui_modules/ trunk/grassaddons/gui/icons/ trunk/grassaddons/gui/images/ Log: set property:ignore Property changes on: trunk/grassaddons/gui/compat ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: trunk/grassaddons/gui/display_driver ___________________________________________________________________ Name: svn:ignore + grass6_wxdriver.i grass6_wxdriver.py grass6_wxdriver_wrap.cxx grass6_wxdriver.pyc _grass6_wxdriver.so Property changes on: trunk/grassaddons/gui/gui_modules ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: trunk/grassaddons/gui/icons ___________________________________________________________________ Name: svn:ignore + *.pyc Property changes on: trunk/grassaddons/gui/images ___________________________________________________________________ Name: svn:ignore + *.pyc From landa at grass.itc.it Sun Sep 23 16:24:10 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 23 16:24:13 2007 Subject: [grass-addons] r1099 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709231424.l8NEOABo001208@grass.itc.it> Author: landa Date: 2007-09-23 16:24:04 +0200 (Sun, 23 Sep 2007) New Revision: 1099 Modified: trunk/grassaddons/gui/display_driver/driver.cc trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Various minor fixes in digitization tool Modified: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-22 14:52:53 UTC (rev 1098) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-23 14:24:04 UTC (rev 1099) @@ -96,18 +96,18 @@ /* nlines = Vect_get_num_lines(mapInfo); */ - Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); - Vect_build(mapInfo, stderr); + //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); + //Vect_build(mapInfo, stderr); // draw lines inside of current display region - nlines = Vect_select_lines_by_box(mapInfo, &(region.box), - GV_POINTS | GV_LINES, // fixme - listLines); + // nlines = Vect_select_lines_by_box(mapInfo, &(region.box), + // GV_POINTS | GV_LINES, // fixme + // listLines); Vect_get_map_box(mapInfo, &mapBox); nlines = Vect_select_lines_by_box(mapInfo, &mapBox, GV_POINTS | GV_LINES, // fixme - listLines); + listLines); for (int i = 0; i < listLines->n_values; i++) { DrawLine(listLines->value[i]); @@ -428,7 +428,11 @@ Vect_close(mapInfo); mapInfo = NULL; - return OpenMap(name, mapset); + OpenMap(name, mapset); + //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); + //Vect_build(mapInfo, stderr); + + return; } /* Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-22 14:52:53 UTC (rev 1098) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-23 14:24:04 UTC (rev 1099) @@ -640,9 +640,9 @@ # dialog body mainSizer = wx.BoxSizer(wx.VERTICAL) - if self.queryCoords: # select by point + if self.queryCoords: # select by position self.line, nselected = self.mapInfo.SelectByPoint(self.queryCoords, - self.qdist) + self.qdist) # notebook notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) for layer in layers: # for each layer @@ -650,9 +650,24 @@ self.layer != layer: continue - if not self.queryCoords: + if not self.queryCoords: # select using layer/cat nselected = self.mapInfo.SelectFromTable(layer, self.cat) + if nselected <= 0 and self.action != "add": + continue # nothing selected ... + + if self.action == "add": + if nselected <= 0: + table = self.mapInfo.layers[layer]["table"] + columns = self.mapInfo.tables[table] + for name in columns.keys(): + if name == "cat": + self.mapInfo.tables[table][name][1].append(self.cat) + else: + self.mapInfo.tables[table][name][1].append('') + else: # change status 'add' -> 'update' + self.action = "update" + panel = wx.Panel(parent=notebook, id=wx.ID_ANY) notebook.AddPage(page=panel, text=_(" %s %d ") % (_("Layer"), layer)) @@ -709,8 +724,7 @@ # for each layer END # set title - if (self.action == "add" and selected > 0) or \ - self.action == "update": + if self.action == "update": self.SetTitle(_("Update attributes")) elif self.action == "add": self.SetTitle(_("Add attributes")) @@ -931,11 +945,13 @@ def SelectFromTable(self, layer, cat): """Select records from the table - Return True on success False on error + Return number of selected records, -1 on error """ if layer <= 0: - return False + return -1 + nselected = 0 + table = self.layers[layer]["table"] # get table desc # select values (only one record) selectCommand = cmd.Command(cmd=["v.db.select", "-v", "--q", @@ -943,13 +959,14 @@ "layer=%d" % layer, "where=cat=%d" % cat]) - self.tables[table]["cat"][1] = str(cat) + #self.tables[table]["cat"][1] = str(cat) if selectCommand.returncode == 0: for line in selectCommand.ReadStdOutput(): name, value = line.split('|') self.tables[table][name][1].append(value) + nselected = 1 - return True + return nselected def main(argv=None): if argv is None: Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-22 14:52:53 UTC (rev 1098) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-23 14:24:04 UTC (rev 1099) @@ -124,6 +124,9 @@ Returns 'True' on success, 'False' on failure """ + # vector map layer without categories, reset to '1' + self.settings['category'] = 1 + if self.map: categoryCmd = cmd.Command(cmd=["v.category", "-g", "--q", "input=%s" % self.map, @@ -141,9 +144,7 @@ except: return False return True - else: - self.settings["category"] = 1 - + def SetCategory(self): """Return category number to use (according Settings)""" if self.settings["categoryMode"] == "No category": @@ -266,7 +267,7 @@ Debug.msg(4, "Digit.DeleteSelectedLines(): ids=%s" % \ ids) - command = [ "v.edit", "--q", + command = [ "v.edit", "map=%s" % self.map, "tool=delete", "ids=%s" % ids] @@ -446,8 +447,11 @@ self.__display.CloseMap() def ReloadMap(self): - """Reload map (close and re-open). Needed for v.edit.""" + """Reload map (close and re-open). + + Needed for v.edit, TODO: get rid of that...""" + Debug.msg(4, "CDisplayDriver.ReloadMap():") self.__display.ReloadMap() def DrawMap(self): @@ -1038,7 +1042,7 @@ # line width text = wx.StaticText(parent=panel, id=wx.ID_ANY, label=_("Line width")) self.lineWidthValue = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(50, -1), - value=str(self.parent.digit.settings["lineWidth"][0]), + initial=self.parent.digit.settings["lineWidth"][0], min=1, max=1e6) self.lineWidthUnit = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(125, -1), choices=["screen pixels", "map units"]) @@ -1060,7 +1064,8 @@ # snapping 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), - value=str(self.parent.digit.settings["snapping"][0]), min=1, max=1e6) + initial=self.parent.digit.settings["snapping"][0], + min=1, 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"]) @@ -1227,7 +1232,7 @@ self.parent.digit.settings[key] = (None, color.GetColour()) # display self.parent.digit.settings["lineWidth"] = (int(self.lineWidthValue.GetValue()), - self.lineWidthUnit.GetValue()) + self.lineWidthUnit.GetValue()) # snapping self.parent.digit.settings["snapping"] = (int(self.snappingValue.GetValue()), # value @@ -1257,7 +1262,7 @@ if self.parent.autoRender.GetValue(): self.parent.ReRender(None) -class DigitCategoryDialog(wx.Dialog): +class DigitCategoryDialog(wx.Dialog, listmix.ColumnSorterMixin): """ Dialog used to display/modify categories of vector objects """ @@ -1300,6 +1305,10 @@ wx.LC_SORT_ASCENDING | wx.LC_HRULES | wx.LC_VRULES) + # sorter + self.itemDataMap = self.list.Populate() + listmix.ColumnSorterMixin.__init__(self, 2) + listSizer.Add(item=self.list, proportion=1, flag=wx.EXPAND) # add new category @@ -1365,7 +1374,7 @@ self.SetAutoLayout(True) # set min size for dialog - self.SetMinSize(self.GetMinSize()) + self.SetMinSize(self.GetBestSize()) # bindings # buttons @@ -1376,13 +1385,21 @@ # list # self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list) - # self.list.Bind(wx.EVT_RIGHT_DOWN, self.OnRightDown) self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp) #wxMSW self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp) #wxGTK self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list) self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit, self.list) + self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list) + def GetListCtrl(self): + """Used by ColumnSorterMixin""" + return self.list + + def OnColClick(self, event): + """Click on column header (order by)""" + event.Skip() + def OnBeginEdit(self, event): """Editing of item started""" event.Allow() @@ -1465,7 +1482,7 @@ def OnItemDeleteAll(self, event): """Delete all items from the list""" self.list.DeleteAllItems() - self.cats = [] + self.cats = {} event.Skip() @@ -1504,7 +1521,7 @@ self.cats = copy.deepcopy(self.cats_orig) # polulate list - self.list.Populate(update=True) + self.itemDataMap = self.list.Populate(update=True) event.Skip() @@ -1566,7 +1583,7 @@ self.cats[layer].append(cat) # reload list - self.list.Populate(update=True) + self.itemDataMap = self.list.Populate(update=True) # update category number for add self.catNew.SetValue(str(cat + 1)) @@ -1592,18 +1609,20 @@ wx.ListCtrl.__init__(self, parent, id, pos, size, style) listmix.ListCtrlAutoWidthMixin.__init__(self) - self.Populate() listmix.TextEditMixin.__init__(self) def Populate(self, update=False): """Populate the list""" + + itemData = {} # requested by sorter + if not update: self.InsertColumn(0, _("Layer")) self.InsertColumn(1, _("Category")) else: self.DeleteAllItems() - i = 0 + i = 1 for layer in self.parent.cats.keys(): catsList = self.parent.cats[layer] for cat in catsList: @@ -1611,6 +1630,7 @@ self.SetStringItem(index, 0, str(layer)) self.SetStringItem(index, 1, str(cat)) self.SetItemData(index, i) + itemData[i] = (str(layer), str(cat)) i = i + 1 if not update: @@ -1619,3 +1639,4 @@ self.currentItem = 0 + return itemData Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-22 14:52:53 UTC (rev 1098) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-23 14:24:04 UTC (rev 1099) @@ -846,7 +846,8 @@ if addRecordDlg.mapInfo and \ addRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") - sqlfile.file.write(addRecordDlg.GetSQLString()) + for sql in addRecordDlg.GetSQLString(): + sqlfile.file.write(sql) sqlfile.file.flush() executeCommand = cmd.Command(cmd=["db.execute", "--q", From ullah at grass.itc.it Mon Sep 24 22:17:11 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Mon Sep 24 22:17:15 2007 Subject: [grass-addons] r1100 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709242017.l8OKHB5l018222@grass.itc.it> Author: ullah Date: 2007-09-24 22:17:05 +0200 (Mon, 24 Sep 2007) New Revision: 1100 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: RADICAL REWRITE! The main programming loop has been condensed and made more elegant while retatinging full functionality. Also, simulation of very limited bedrock erosion has been added, which gretly stabilizes the longe term patterns of erosion and deposition. This version is significantly differnt from all previous versions, therefore: THIS CAN BE CONSIDERED A VERSION UPGRADE!!! Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-23 14:24:04 UTC (rev 1099) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-24 20:17:05 UTC (rev 1100) @@ -297,81 +297,10 @@ nbhood=$GIS_OPT_nbhood cutoff1=$GIS_OPT_cutoff1 cutoff2=$GIS_OPT_cutoff2 -number=$GIS_OPT_number -echo "total number of iterations to be run= $number" +num_iters=$GIS_OPT_number +echo "total number of iterations to be run= $num_iters" echo "" -if [ $number -eq 1 ] ; then - -num="" - -else - -num="1" - -fi - -echo "The following temporary files will be created:" -echo "" -tempsmoothdz=$prefx"tempsmoothdz"$num -echo "tempsmoothdz=$tempsmoothdz" -tempsmoothdz=$prefx"tempsmoothdz"$num -echo "temsmoothpdz=$tempsmoothdz" -flowacc=$prefx"flowacc"$num -echo "flowacc=$flowacc" -slope=$prefx"slope"$num -echo "slope=$slope" -aspect=$prefx"aspect"$num -echo "aspect=$aspect" -pc=$prefx"pc1" -echo "pc=$pc" -tc=$prefx"tc1" -echo "tc=$tc" -meancurv=$prefx"meancurv"$num -echo "meancurv=$meancurv" -rate=$prefx"rate"$num -echo "rate=$rate" -sflowtopo=$prefx"sflowtopo"$num -echo "sflowtopo=$sflowtopo" -qsx=$prefx"qsx"$num -echo "qsx=$qsx" -qsy=$prefx"qsy"$num -echo "qsy=$qsy" -qsxdx=$prefx"qsx_dx"$num -echo "qsxdx=$qsxdx" -qsydy=$prefx"qsy_dy"$num -echo "qsydy=$qsydy" -m=$prefx"mexp"$num -echo "m=$m" -n=$prefx"nexp"$num -echo "n=$n" -erdep=$prefx"erosdep"$num -echo "erdep=$erdep" - - - -echo "" -smoothdz=$prefx"smoothdz"$num -netchange=$prefix"netchange"$num -new_soil=$prefx$outsoil$num -new_dem=$prefx$outdem$num -initsoil=$prefx"initsoil" - -echo "The new net erosion/deposition map for this iteration will be called $netchange" -echo "The new dem for this iteration will be called $new_dem" -echo "The new soil depth map for this iteration will be called $new_soil" - -if [ "$GIS_FLAG_b" -eq 1 ]; then - -echo "" - -else - -new_bdrk=$prefx$outbdrk$num -echo "The new bedrock elevation map for this iteration will be called $new_bdrk" - -fi - #let's grab the current resolution res1=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` @@ -388,447 +317,488 @@ res=`eval g.region -p -m | grep "nsres:" | cut -d : -f 2` echo "" echo "New Resolution = $res" - - echo "" -# the first iteration must be run before the loop to set up the input data for the loop and to use the "initsoil" map to set up soil production function +# each iteration through the loop represents 1 simulation cycle echo "" echo "##################################################" echo "##################################################" echo "" - -if [ $number -eq 1 ] ; then - echo "STARTING SIMULATION" echo "" +echo "Beginning iteration sequence. This may take some time." echo "Process is not finished until you see the message: 'Done with everything' " - -else - echo "_____________________________________________________________" -echo "Beginning iteration sequence. This will take some time." -echo "" -echo "Process is not finished until you see the message: 'Done with everything' " echo "_____________________________________________________________" echo "" -echo "ITERATION 1" -fi +iter="0" +while [ "$iter" -lt "$num_iters" ] +do + last_iter=$iter + iter=$(($iter+1)) # loop iteration control -echo "" -echo "##################################################" -echo "" -echo "*************************" -echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" -echo "*************************" -echo "" + echo "" + echo "ITERATION $iter OF $num_iters" + echo "" + echo "****************************" + echo "" + echo "The following temporary files will be created:" + echo "" + tempsmoothdz=$prefx"tempsmoothdz"$iter + echo "tempsmoothdz=$tempsmoothdz" + tempsmoothdz=$prefx"tempsmoothdz"$iter + echo "temsmoothpdz=$tempsmoothdz" + flowacc=$prefx"flowacc"$iter + echo "flowacc=$flowacc" + slope=$prefx"slope"$iter + echo "slope=$slope" + aspect=$prefx"aspect"$iter + echo "aspect=$aspect" + pc=$prefx"pc"$iter + echo "pc=$pc" + tc=$prefx"tc"$iter + echo "tc=$tc" + meancurv=$prefx"meancurv"$iter + echo "meancurv=$meancurv" + rate=$prefx"rate"$iter + echo "rate=$rate" + sflowtopo=$prefx"sflowtopo"$iter + echo "sflowtopo=$sflowtopo" + qsx=$prefx"qsx"$iter + echo "qsx=$qsx" + qsy=$prefx"qsy"$iter + echo "qsy=$qsy" + qsxdx=$prefx"qsx_dx"$iter + echo "qsxdx=$qsxdx" + qsydy=$prefx"qsy_dy"$iter + echo "qsydy=$qsydy" + m=$prefx"mexp"$iter + echo "m=$m" + n=$prefx"nexp"$iter + echo "n=$n" + erdep=$prefx"erosdep"$iter + echo "erdep=$erdep" + echo "" + # if first iteration, use input maps. Otherwise, use maps generated from previous iterations + if [ "$iter" -eq 1 ]; then + old_dem=$elev + old_bdrk=$initbdrk + old_soil=$prefx$outsoil"_init" + r.mapcalc "$old_soil=$elev - $old_bdrk" + #stats output file + mapset=`eval g.gisenv get=MAPSET` + txtout=$mapset$prefx"erdep_stats.txt" + # create temporary file to code colors for $netchange + TMP1=`g.tempfile pid=$$` + if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then + echo "ERROR: unable to create temporary file for netchange colors" 1>&2 + exit 1 + fi + echo "100% 0 0 100" > $TMP1 + echo "1 blue" >> $TMP1 + echo "0.5 indigo" >> $TMP1 + echo "0.01 green" >> $TMP1 + echo "0 white" >> $TMP1 + echo "-0.01 yellow" >> $TMP1 + echo "-0.5 orange" >> $TMP1 + echo "-1 red" >> $TMP1 + echo "0% 150 0 50" >> $TMP1 -r.slope.aspect --q $elev slope=$slope aspect=$aspect pcurv=$pc tcurv=$tc + # create temporary file to code colors for $soildepth + TMP4=`g.tempfile pid=$$` + if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then + echo "ERROR: unable to create temporary file for soil colors" 1>&2 + exit 1 + fi + echo "100% 0 0 100" > $TMP4 + echo "10 blue" >> $TMP4 + echo "5 indigo" >> $TMP4 + echo "1 green" >> $TMP4 + echo "0.1 yellow" >> $TMP4 + echo "0.03 orange" >> $TMP4 + echo "0.01 red" >> $TMP4 + echo "0.001 150 0 50" >> $TMP4 + echo "0 white" >> $TMP4 + else + old_dem=$prefx$outdem$last_iter + old_bdrk=$prefx$outbdrk$last_iter + old_soil=$prefx$outsoil$last_iter + lastsmooth=$prefx"smoothdz"$last_iter + fi -echo "" -echo "*************************" -echo "step 2 of 8: calculating upslope accumulated flow" -echo "*************************" -echo "" + echo "old_dem=$old_dem" + echo "old_bdrk=$old_bdrk" + echo "old_soil=$old_soil" + echo "" + if [ $num_iters -ne 1 ]; then + smoothdz=$prefx"smoothdz"$iter + netchange=$prefx"netchange"$iter + new_dem=$prefx$outdem$iter + new_bdrk=$prefx$outbdrk$iter + new_soil=$prefx$outsoil$iter + else + smoothdz=$prefx"smoothdz" + netchange=$prefx"netchange" + new_dem=$prefx$outdem + new_bdrk=$prefx$outbdrk + new_soil=$prefx$outsoil + fi + + echo "The new net erosion/deposition map for this iteration will be called $netchange" + echo "The new dem for this iteration will be called $new_dem" + echo "The new soil depth map for this iteration will be called $new_soil" + + if [ "$GIS_FLAG_b" -eq 1 ]; then + echo "" + else + new_bdrk=$prefx$outbdrk$iter + echo "The new bedrock elevation map for this iteration will be called $new_bdrk" + fi -if [ "$GIS_FLAG_f" -eq 1 ]; then +# the first iteration must be run before the loop to set up the input data for the loop and to use the "new_soil" map to set up soil production function + echo "" + echo "##################################################" + echo "" + echo "*************************" + echo "step 1 of 8: calculating slope and aspect (if initial aspect not specified)" + echo "*************************" + echo "" -echo "using r.terraflow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" -echo "" + r.slope.aspect --quiet elevation=$old_dem slope=$slope aspect=$aspect pcurv=$pc tcurv=$tc -#First we need to grab the amount of free RAM for r.terraflow -mem=`eval free -mo | grep "Mem" | tr -s /[:blank:] /[:] | cut -d":" -f4` + echo "" + echo "*************************" + echo "step 2 of 8: calculating upslope accumulated flow" + echo "*************************" + echo "" -#r.terraflow can't handle it if you tell it to use more than 2 Gigs of RAM, so if you have more than that, we have to tell r.terraflow to only use up to 2 Gigs of the free RAM... + if [ "$GIS_FLAG_f" -eq 1 ]; then + echo "using r.terraflow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + echo "" -if [ "$mem" -lt "2000" ]; then + #First we need to grab the amount of free RAM for r.terraflow -mem=$mem + mem=`eval free -mo | grep "Mem" | tr -s /[:blank:] /[:] | cut -d":" -f4` -else + #r.terraflow can't handle it if you tell it to use more than 2 Gigs of RAM, so if you have more than that, we have to tell r.terraflow to only use up to 2 Gigs of the free RAM... -mem="2000" + if [ "$mem" -lt "2000" ]; then + mem=$mem + else + mem="2000" + fi -fi + echo "Amount of free RAM being allocated for this step: $mem Megabites" + tmpflacc=$prefx".tmpflacc" -echo "Amount of free RAM being allocated for this step: $mem Megabites" + r.terraflow --q elev=$old_dem filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$tmpflacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp -tmpflacc=$prefx".tmpflacc" + r.mapcalc "$flowacc=$tmpflacc/$res" -r.terraflow --q elev=$elev filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$tmpflacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp + g.remove --quiet rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$tmpflacc,$tmpdirection -r.mapcalc "$flowacc=$tmpflacc/$res" + rm -f /var/tmp/STREAM* + else + echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" -g.remove --quiet rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$tmpflacc,$tmpdirection -rm -f /var/tmp/STREAM* + tmpfilled=$prefx"tmpfilled"$iter + tmpdirection=$prefx"tmpdirection" -else + tmpflacc=$prefx"tmpflacc" -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" + r.fill.dir --quiet input=$old_dem elevation=$tmpfilled direction=$tmpdirection type=grass -tmpfilled=$prefx"tmpfilled"$num -tmpdirection=$prefx"tmpdirection" + r.flow -3 --quiet elevin=$tmpfilled aspin=$aspect dsout=$tmpflacc -tmpflacc=$prefx"tmpflacc" + r.mapcalc "$flowacc=$tmpflacc*$res" -r.fill.dir --quiet input=$elev elevation=$tmpfilled direction=$tmpdirection type=grass + g.remove --quiet rast=$tmpflacc,$tmpdirection,$tmpfilled + fi -r.flow -3 --quiet elevin=$tmpfilled aspin=$aspect dsout=$tmpflacc + echo "" + echo "*************************" + echo "step 3 of 8: calculating basic sediment transport rates" + echo "*************************" + echo "" -r.mapcalc "$flowacc=$tmpflacc*$res" + if [ "$GIS_FLAG_w" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 0 ]; then + echo "" + echo "calculating for sheetwash across the entire map" + r.mapcalc "$sflowtopo=$flowacc * sin($slope)" + elif [ "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_w" -eq 0 ]; then + echo "" + echo "calculating for channelzed flow across the entire map" -g.remove --quiet rast=$tmpflacc,$tmpdirection + r.mapcalc "$sflowtopo=exp(($flowacc),1.6) * exp(sin($slope),1.3)" + elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 0 ]; then + echo "" + echo "calculating for diffusive flow across the entire map" + r.mapcalc "$sflowtopo=$kappa * exp(($res),2) * sin($slope)" -fi + elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 0 ]; then + echo "" + echo "############################################################" + echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" + echo "############################################################" + echo "" -echo "" -echo "*************************" -echo "step 3 of 8: calculating basic sediment transport rates" -echo "*************************" -echo "" - + elif [ "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ]; then + echo "" + echo "############################################################" + echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" + echo "############################################################" + echo "" + elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 1 ]; then + echo "" + echo "############################################################" + echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" + echo "############################################################" + echo "" + elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ]; then + echo "" + echo "############################################################" + echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" + echo "############################################################" + echo "" + else + maxflow=`eval r.info -r map=$flowacc | grep "max=" | cut -d"=" -f2` -if [ "$GIS_FLAG_w" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 0 ]; then + echo "" + echo "The raw max ($maxflow) flow accumulation, min cutoff $cutoff1, and middle cutoff $cutoff2 will be used to scale flow exponents 'm' and 'n' as flow progresses in the drainage network" + echo "" + echo "" + echo "calculating with appropriate flow types on different landforms" -echo "" -echo "calculating for sheetwash across the entire map" - r.mapcalc "$sflowtopo=$flowacc * sin($slope)" + r.mapcalc "$m=if($flowacc > $cutoff2, 1.6, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.6/($cutoff2 - $cutoff1)))), 1))" -elif [ "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_w" -eq 0 ] -then + r.mapcalc "$n=if($flowacc > $cutoff2,1.3, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.3/($cutoff2 - $cutoff1)))), 1))" -echo "" -echo "calculating for channelzed flow across the entire map" - r.mapcalc "$sflowtopo=exp(($flowacc),1.6) * exp(sin($slope),1.3)" + r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff1, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" + fi + echo "" + echo "*************************" + echo "step 4 of 8: calculating sediment transport capacity in x and y directions" + echo "*************************" + echo "" + #if the old soil is 0 or negative(could happen i suppose) then we make k-factor really really small to simulate erosion on bedrock + r.mapcalc "$qsx=if ($old_soil <= 0, ($R * 0.001 * $C * $sflowtopo * cos($aspect)), ($R * $K * $C * $sflowtopo * cos($aspect)))" + r.mapcalc "$qsy=if ($old_soil <= 0, ($R * 0.001 * $C * $sflowtopo * cos($aspect)), ($R * $K * $C * $sflowtopo * sin($aspect)))" -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 0 ] -then + echo "" + echo "*************************" + echo "step 5 of 8: calculating partial derivatives for sediment transport" + echo "*************************" + echo "" -echo "" -echo "calculating for diffusive flow across the entire map" - r.mapcalc "$sflowtopo=$kappa * exp(($res),2) * sin($slope)" + r.slope.aspect --q $qsx dx=$qsxdx + r.slope.aspect --q $qsy dy=$qsydy + echo "" + echo "*************************" + echo "step 6 of 8: calculating net erosion and deposition" + echo "*************************" + echo "" -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 0 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -else - -maxflow=`eval r.info -r map=$flowacc | grep "max=" | cut -d"=" -f2` - - -echo "" -echo "The raw max ($maxflow) flow accumulation, min cutoff $cutoff1, and middle cutoff $cutoff2 will be used to scale flow exponents 'm' and 'n' as flow progresses in the drainage network" -echo "" - -echo "" -echo "calculating with appropriate flow types on different landforms" - -r.mapcalc "$m=if($flowacc > $cutoff2, 1.6, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.6/($cutoff2 - $cutoff1)))), 1))" - -r.mapcalc "$n=if($flowacc > $cutoff2,1.3, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.3/($cutoff2 - $cutoff1)))), 1))" - -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff1, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" - - -fi - -echo "" -echo "*************************" -echo "step 4 of 8: calculating sediment transport capacity in x and y directions" -echo "*************************" -echo "" - -r.mapcalc "$qsx=if ("$initbdrk" >= "$elev", 0, ($R * $K * $C * $sflowtopo * cos($aspect)))" -r.mapcalc "$qsy=if ("$initbdrk" >= "$elev", 0, ($R * $K * $C * $sflowtopo * sin($aspect)))" - - -echo "" -echo "*************************" -echo "step 5 of 8: calculating partial derivatives for sediment transport" -echo "*************************" -echo "" - -r.slope.aspect --q $qsx dx=$qsxdx -r.slope.aspect --q $qsy dy=$qsydy - - -echo "" -echo "*************************" -echo "step 6 of 8: calculating net erosion and deposition" -echo "*************************" -echo "" - - #this is commented out because I don't understand why we should multiply by the resolution again here. I think that it is actually a typo incorporated into every version of the script since the beginning. #echo "calculating for rill erosion" # r.mapcalc "$erdep=$res * ($qsxdx + $qsydy)" -r.mapcalc "$erdep=$qsxdx + $qsydy" + r.mapcalc "$erdep=if($old_soil >= 0, (if((-1 *($qsxdx + $qsydy) ) >= $old_soil, (-1 * $old_soil), ($qsxdx + $qsydy))), ($qsxdx + $qsydy))" + echo "" + echo "*************************" + echo "step 7 of 8: running despeckling filter" + echo "*************************" + echo "" -r.mapcalc "$initsoil=$elev - $initbdrk" + if [ "$GIS_FLAG_y" -eq 1 ]; then + echo "You have selected not to smooth your files... Oh Well!" + echo "" -echo "" -echo "*************************" -echo "step 7 of 8: running despeckling filter" -echo "*************************" -echo "" - - - - -if [ "$GIS_FLAG_y" -eq 1 ]; then - -echo "You have selected not to smooth your files... Oh Well!" -echo "" - -r.mapcalc "$smoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" - - -else + + else #commenting out the sigma-based truncation because it was causeing deletarious amplification of cell edges. Leaving it commented for posterity only... #r.mapcalc "$smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $initsoil, (-1 * $initsoil), $erdep)" -r.neighbors --q input=$tempsmoothdz output=$smoothdz method=$GIS_OPT_method size=$GIS_OPT_nbhood + r.neighbors --q input=$erdep output=$tempsmoothdz method=$GIS_OPT_method size=$GIS_OPT_nbhood + fi -fi + #now we must correct for the incredible edge shrinking effect by patching the last smoothdz underneath the new smoothdz + if [ $iter -ne 1 ]; then + r.patch input=$tempsmoothdz,$lastsmooth output=$smoothdz + g.remove --quiet rast=$tempsmoothdz + else + g.rename --quiet rast=$tempsmoothdz,$smoothdz + fi + echo "" + echo "*************************" + echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" + echo "*************************" + echo "" + #put the net dz back where it is upposed to go and then subtract it from dem to make new dem + if [ $num_iters -eq 1 ]; then + temp_dem=$prefx"temp_dem" + else + temp_dem=$new_dem + fi -#checking to see if we should keep the initial soil depths map + if [ "$GIS_FLAG_f" -eq 1 ]; then + + r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, if(x > ($old_dem + 25), ($old_dem + 25), x))))" + + else + + r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, x)))" + + fi + #set colors for maps + r.colors --q map=$temp_dem rast=$elev -echo "" -echo "*************************" -echo "step 8 of 8: calculating terrain evolution, new bedrock elevations, and new soil depths" -echo "*************************" -echo "" + if [ $num_iters -eq 1 ] ; then + r.patch --quiet input=$temp_dem,$old_dem output=$new_dem + g.remove --quiet rast=$temp_dem + fi -#put the net dz back where it is upposed to go and then subtract it from dem to make new dem -if [ $number -eq 1 ] ; then + #make $netchange if asked + if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then + + r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, if(x > 25, 25, x))))" + + #set colors for maps + r.colors --quiet map=$netchange rules=$TMP1 -temp_dem=$prfx"temp_dem" + elif [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 -a "$GIS_FLAG_f" -eq 0 ] + then + + r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, x)))" -r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($elev + $smoothdz))))))))), (if(isnull(x), $elev, x)))" + #set colors for maps + r.colors --quiet map=$netchange rules=$TMP1 + fi -r.patch --quiet input=$temp_dem,$elev output=$new_dem + + if [ $GIS_FLAG_b -eq 1 ]; then + echo "" + echo "Calculating new soil depths keeping bedrock elevations static" -g.remove --quiet rast=$temp_dem + r.mapcalc "$new_soil=if (($new_dem - $initbdrk) < 0, 0, ($new_dem - $initbdrk))" + else + echo "" + echo "step 8.5: Calculating new soil depths from landscape curvature" -else + r.mapcalc "$meancurv=(($pc + $tc) / 2)" -r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($elev + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($elev + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($elev + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($elev + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($elev + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($elev + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($elev + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($elev + $smoothdz[1,1]), ($elev + $smoothdz))))))))), (if(isnull(x), $elev, x)))" + # create temporary file to clip the max and min to + TMP5=`g.tempfile pid=$$` + max=`eval r.info -r map=$meancurv | grep "max=" | cut -d"=" -f2` + min=`eval r.info -r map=$meancurv | grep "min=" | cut -d"=" -f2` + echo "" + echo "The raw max ($max) and min ($min) curvature will be rescaled from 2 to 0 " + echo "" -fi + r.mapcalc "$rate=$kappa*(2-($meancurv*(2/($max)-($min))))" + #rate is actually the net change in bedrock elevation due to soil production, so lets use it to find the new bedrock elev, and the new soil depth! + r.mapcalc "$new_bdrk=$old_bdrk - $rate" + r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" -#make $netchange if asked -if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 0 -o "$GIS_FLAG_t" -eq 0 ]; then + #these are the old soil equations that I failed to be able to implement... I leave them in for documentation purposes + #r.mapcalc "$new_bdrk=$initbdrk - ($Ba * ($Bb*($smoothdz - $initbdrk)))" + #r.mapcalc "$new_soil=if (($smoothdz - $initbdrk) < 0, 0, ($smoothdz - $initbdrk))" + g.remove --quiet rast=$rate,$meancurv + fi -r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, x)))" + #setting colors for new soil depth map + r.colors --quiet map=$new_soil rules=$TMP4 -#set colors to $elev -r.colors --quiet map=$new_dem rast=$elev + #grabsomestats + tmperosion=$prfx"tmperosion"$iter + tmpdep=$prfx"tmpdep"$iter -# create temporary file to code colors for $netchange + r.mapcalc "$tmperosion=if($smoothdz < 0, $smoothdz, null())" + r.mapcalc "$tmpdep=if($smoothdz > 0, $smoothdz, null())" -TMP1=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP1" ] ; then - echo "ERROR: unable to create temporary file for netchange colors" 1>&2 - exit 1 -fi + soilstats=`eval r.univar -g -e map=$new_soil percentile=99` + maxsoil=`echo "$soilstats" | grep "max=" | cut -d'=' -f2` + minsoil=`echo "$soilstats" | grep "min=" | cut -d'=' -f2` + avesoil=`echo "$soilstats" | grep "mean=" | cut -d'=' -f2` + nnthsoil=`echo "$soilstats" | grep "percentile_99=" | cut -d'=' -f2` + erosstats=`eval r.univar -g -e map=$tmperosion percentile=99` + maxeros=`echo "$erosstats" | grep "max=" | cut -d'=' -f2` + mineros=`echo "$erosstats" | grep "min=" | cut -d'=' -f2` + aveeros=`echo "$erosstats" | grep "mean=" | cut -d'=' -f2` + nntheros=`echo "$erosstats" | grep "percentile_99=" | cut -d'=' -f2` -echo "100% 0 0 100" > $TMP1 -echo "1 blue" >> $TMP1 -echo "0.5 indigo" >> $TMP1 -echo "0.01 green" >> $TMP1 -echo "0 white" >> $TMP1 -echo "-0.01 yellow" >> $TMP1 -echo "-0.5 orange" >> $TMP1 -echo "-1 red" >> $TMP1 -echo "0% 150 0 50" >> $TMP1 + depostats=`eval r.univar -g -e map=$tmpdep percentile=99` + maxdepo=`echo "$depostats" | grep "max=" | cut -d'=' -f2` + mindepo=`echo "$depostats" | grep "min=" | cut -d'=' -f2` + avedepo=`echo "$depostats" | grep "mean=" | cut -d'=' -f2` + nnthdepo=`echo "$depostats" | grep "percentile_99=" | cut -d'=' -f2` + g.remove --quiet rast=$tmperosion,$tmpdep -r.colors --quiet map=$netchange rules=$TMP1 + mapset=`eval g.gisenv get=MAPSET` + txtout=$mapset"_"$prefx"_lsevol_stats.txt" -fi + echo "outputing stats to textfile: $txtout" -# create temporary file to code colors for $soildepth + if [ $iter -eq 1 ]; then + echo "Stats for erosion and deposition simulation with starting map: $elev" > $txtout + echo "" >> $txtout + echo "Year,,Mean Erosion,Max Erosion,Min Erosion,99th Percentile Erosion,,Mean Deposition,Min Deposition,Max Deposition,99th Percentile Deposition,,Mean Soil Depth,Min Soil Depth,Max Soil Depth,99th Percentile Soil Depth" >> $txtout + fi + echo "$iter,,$aveeros,$mineros,$maxeros,$nntheros,,$avedepo,$mindepo,$maxdepo,$nnthdepo,,$avesoil,$minsoil,$maxsoil,$nnthsoil" >> $txtout + echo "" + echo "*************************" + echo "Done with this iteration" + echo "*************************" -if [ $GIS_FLAG_b -eq 1 ]; then + if [ $num_iters -eq 1 ]; then + if [ "$GIS_FLAG_e" -eq 1 ]; then + echo "" + echo "keeping initial soil depths map $new_soil" + else + g.remove --quiet rast=$new_tsoil + fi + fi -echo "" -echo "Calculating new soil depths keeping bedrock elevations static" + echo "" + echo "If made, raster map $netchange shows filtered net erosion/deposition" + echo "" + echo "If made, raster map $soildepth shows soildpeths" + echo "" + echo "Raster map $new_dem shows new landscape (new elevations) after net erosion/depostion" + echo "*************************" + echo "" +done - -r.mapcalc "$new_soil=if (($new_dem - $initbdrk) < 0, 0, ($new_dem - $initbdrk))" - -else - -echo "" -echo "step 8.5: Calculating new soil depths from landscape curvature" - -r.mapcalc "$meancurv=(($pc + $tc) / 2)" - - -max=`eval r.info -r map=$meancurv | grep "max=" | cut -d"=" -f2` -min=`eval r.info -r map=$meancurv | grep "min=" | cut -d"=" -f2` - -echo "" -echo "The raw max ($max) and min ($min) curvature will be rescaled from 2 to 0 " -echo "" - - -r.mapcalc "$rate=$kappa*(2-($meancurv*(2/($max)-($min))))" - -#rate is actually the net change in bedrock elevation due to soil production, so lets use it to find the new bedrock elev, and the new soil depth! - -r.mapcalc "$new_bdrk=$initbdrk - $rate" - -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -#these are the old soil equations that I failed to be able to implement... I leave them in for documentation purposes -#r.mapcalc "$new_bdrk=$initbdrk - ($Ba * ($Bb*($smoothdz - $initbdrk)))" -#r.mapcalc "$new_soil=if (($smoothdz - $initbdrk) < 0, 0, ($smoothdz - $initbdrk))" - -fi - - -# create temporary file to code colors for $soildepth - -TMP4=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP4" ] ; then - echo "ERROR: unable to create temporary file for soil colors" 1>&2 - exit 1 -fi - - - -echo "100% 0 0 100" > $TMP4 -echo "10 blue" >> $TMP4 -echo "5 indigo" >> $TMP4 -echo "1 green" >> $TMP4 -echo "0.1 yellow" >> $TMP4 -echo "0.03 orange" >> $TMP4 -echo "0.01 red" >> $TMP4 -echo "0.001 150 0 50" >> $TMP4 -echo "0 white" >> $TMP4 - -r.colors --quiet map=$new_soil rules=$TMP4 - - - - -#grabsomestats -tmperosion=$prfx"tmperosion"$num -tmpdep=$prfx"tmpdep"$num - -r.mapcalc "$tmperosion=if($smoothdz < 0, $smoothdz, null())" -r.mapcalc "$tmpdep=if($smoothdz > 0, $smoothdz, null())" - -avesoil=`eval r.univar -g map=$new_soil percentile=90 | grep "mean=" | cut -d'=' -f2` -aveeros=`eval r.univar -g map=$tmperosion percentile=90 | grep "mean=" | cut -d'=' -f2` -avedep=`eval r.univar -g map=$tmpdep percentile=90 | grep "mean=" | cut -d'=' -f2` - -g.remove --quiet rast=$tmperosion,$tmpdep - -mapset=`eval g.gisenv get=MAPSET` -txtout=$mapset$prefx"erdep_stats.txt" - -echo "outputing stats to textfile: $txtout" - -echo "Stats for erosion and deposition simulation with starting map: $elev" > $txtout -echo "" >> $txtout -echo "Year,Mean Erosion, Mean Deposition,Mean Soil Depth" >> $txtout -echo "1,$aveeros,$avedep,$avesoil" >> $txtout - - -echo "" -echo "*************************" -echo "Done with this iteration" -echo "*************************" - -if [ "$GIS_FLAG_e" -eq 1 ]; then - -echo "" -echo "keeping initial soil depths map $initsoil" - -else - -g.remove --quiet rast=$initsoil - -fi - - -echo "" -echo "If made, raster map $netchange shows filtered net erosion/deposition" -echo "" -echo "If made, raster map $soildepth shows soildpeths" -echo "" -echo "Raster map $new_dem shows new landscape (new elevations) after net erosion/depostion" -echo "*************************" -echo "" - - #This is replaced by the large g.mremove process at the end of the script. I leave it commented because one might like to have the files for each iteration cleaned up as the process runs instead of one batch process at the end. #if [ "$GIS_FLAG_k" -eq 1 ]; then # echo "" @@ -845,594 +815,142 @@ #remove the temp files to avoid confusion...\rm -f $TMP1 $TMP1.sort - - -step=1 - -# now we must go into a loop to get the rest of the dem's - -while [ "$step" -lt "$number" ] -do - laststep=$step - step=$(($step+1)) # here is how we are controlling the iteration loop - - -old_dem=$prefx$outdem$laststep - -echo "The following temporary files will be created:" -echo "" -tempsmoothdz=$prefx"tempsmoothdz"$step -echo "tempsmoothdz=$tempsmoothdz" -temp2smoothdz=$prefx"temp2smoothdz"$step -echo "temp2smoothdz=$temp2smoothdz" -flowacc=$prefx"flowacc"$step -echo "flowacc=$flowacc" -slope=$prefx"slope"$step -echo "slope=$slope" -aspect=$prefx"aspect"$step -echo "aspect=$aspect" -pc=$prefx"pc"$step -echo "pc=$pc" -tc=$prefx"tc"$step -echo "tc=$tc" -meancurv=$prefx"meancurv"$step -echo "meancurv=$meancurv" -rate=$prefx"rate"$step -echo "rate=$rate" -sflowtopo=$prefx"sflowtopo"$step -echo "sflowtopo=$sflowtopo" -qsx=$prefx"qsx"$step -echo "qsx=$qsx" -qsy=$prefx"qsy"$step -echo "qsy=$qsy" -qsxdx=$prefx"qsx_dx"$step -echo "qsxdx=$qsxdx" -qsydy=$prefx"qsy_dy"$step -echo "qsydy=$qsydy" -m=$prefx"mexp"$step -echo "m=$m" -n=$prefx"nexp"$step -echo "n=$n" -erdep=$prefx"erosdep"$step -echo "erdep=$erdep" - -old_bdrk=$prefx$outbdrk$laststep -echo "old_bdrk=$old_bdrk" -old_soil=$prefx$outsoil$laststep -echo "old_soil=$old_soil" -echo "" - -smoothdz=$prefx"smoothdz"$step -netchange=$prefx"netchange"$step -new_soil=$prefx$outsoil$step -new_dem=$prefx$outdem$step - -echo "The new net ersoion/deposition map for this iteration will be called $netchange" -echo "The new dem for this iteration will be called $new_dem" -echo "The new soil depth map for this iteration will be called $new_soil" - -if [ "$GIS_FLAG_b" -eq 1 ]; then - -echo "" - -else - -new_bdrk=$prefx$outbdrk$step -echo "The new bedrock elevation map for this iteration will be called $new_bdrk" - -fi - - - -echo "" -echo "##################################################" -echo "##################################################" -echo "" -echo "ITERATION $step" -echo "" -echo "##################################################" -echo "" -echo "*************************" -echo "step 1 of 8: calculating slope and aspect" -echo "*************************" -echo "" - - - - - -r.slope.aspect --q elevation=$old_dem slope=$slope aspect=$aspect pcurv=$pc tcurv=$tc - - -echo "" -echo "*************************" -echo "step 2 of 8: calculating upslope accumulated flow" -echo "*************************" -echo "" - - - -if [ "$GIS_FLAG_f" -eq 1 ]; then - -echo "using r.terraflow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" -echo "" - -#First we need to grab the amount of free RAM for r.terraflow - -mem=`eval free -mo | grep "Mem" | tr -s /[:blank:] /[:] | cut -d":" -f4` - -#r.terraflow can't handle it if you tell it to use more than 2 Gigs of RAM, so if you have more than that, we have to tell r.terraflow to only use up to 2 Gigs of the free RAM... - -if [ "$mem" -lt "2000" ]; then - -mem=$mem - -else - -mem="2000" - -fi - - -echo "Amount of free RAM being allocated for this step: $mem Megabites" - -tmpflacc=$prefx".tmpflacc" - -r.terraflow --q elev=$old_dem filled=$prefx".filled" direction=$prefx".direct" swatershed=$prefx".sink" accumulation=$tmpflacc tci=$prefx".tci" d8cut=infinity memory=$mem STREAM_DIR=/var/tmp - -r.mapcalc "$flowacc=$tmpflacc/$res" - - -g.remove --quiet rast=$prefx".filled",$prefx".direct",$prefx".sink",$prefx".tci",$tmpflacc,$tmpdirection -rm -f /var/tmp/STREAM* - -else - -echo "using r.flow to calculate overland flow accumulation per cell (number of cells uplsope from each cell)" - -tmpfilled=$prefx"tmpfilled"$step -tmpdirection=$prefx"tmpdirection" - -tmpflacc=$prefx"tmpflacc" - -r.fill.dir --quiet input=$old_dem elevation=$tmpfilled direction=$tmpdirection type=grass - -r.flow -3 --quiet elevin=$tmpfilled aspin=$aspect dsout=$tmpflacc - -r.mapcalc "$flowacc=$tmpflacc*$res" - -g.remove --quiet rast=$tmpflacc,$tmpdirection - -fi - - - -echo "" -echo "*************************" -echo "step 3 of 8: calculating basic sediment transport rates" -echo "*************************" -echo "" - - -if [ "$GIS_FLAG_w" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 0 ]; then - -echo "" -echo "calculating for sheetwash across the entire map" - r.mapcalc "$sflowtopo=$flowacc * sin($slope)" - -elif [ "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_w" -eq 0 ] -then - -echo "" -echo "calculating for channelzed flow across the entire map" - r.mapcalc "$sflowtopo=exp(($flowacc),1.6) * exp(sin($slope),1.3)" - - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 0 ] -then - -echo "" -echo "calculating for diffusive flow across the entire map" - r.mapcalc "$sflowtopo=$kappa * exp(($res),2) * sin($slope)" - - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 0 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 0 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 0 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -elif [ "$GIS_FLAG_d" -eq 1 -a "$GIS_FLAG_r" -eq 1 -a "$GIS_FLAG_w" -eq 1 ] -then - -echo "" -echo "############################################################" -echo "!!!!!!!!!YOU MUST SELECT ONLY ONE TYPE OF EROSION!!!!!!!!!!!" -echo "############################################################" -echo "" - -else - -maxflow=`eval r.info -r map=$flowacc | grep "max=" | cut -d"=" -f2` - - -echo "" -echo "The raw max ($maxflow) flow accumulation, min cutoff $cutoff1, and middle cutoff $cutoff2 will be used to scale flow exponents 'm' and 'n' as flow progresses in the drainage network" -echo "" - -echo "" -echo "calculating with appropriate flow types on different landforms" - -r.mapcalc "$m=if($flowacc > $cutoff2, 1.6, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.6/($cutoff2 - $cutoff1)))), 1))" - -r.mapcalc "$n=if($flowacc > $cutoff2,1.3, if($flowacc > $cutoff1 && $flowacc < $cutoff2, (1+($flowacc * (0.3/($cutoff2 - $cutoff1)))), 1))" - -r.mapcalc "$sflowtopo=if ($flowacc >= $cutoff1, exp(($flowacc),$m) * exp(sin($slope),$n), ($kappa * exp(($res),2) *sin($slope)))" - -fi - - - -echo "" -echo "*************************" -echo "step 4 of 8: calculating sediment transport capacity in x and y directions" -echo "*************************" -echo "" - - -r.mapcalc "$qsx= if ($old_soil <= 0, 0, ($R * $K * $C * $sflowtopo * cos($aspect)))" -r.mapcalc "$qsy= if ($old_soil <= 0, 0, ($R * $K * $C * $sflowtopo * sin($aspect)))" - - -echo "" -echo "*************************" -echo "step 5 of 8: calculating partial derivatives for sediment transport" -echo "*************************" -echo "" - - -r.slope.aspect --q $qsx dx=$qsxdx -r.slope.aspect --q $qsy dy=$qsydy - - -echo "" -echo "*************************" -echo "step 6 of 8: calculating net erosion and deposition" -echo "*************************" -echo "" - - - - r.mapcalc "$erdep=$qsxdx + $qsydy" - - -echo "" -echo "*************************" -echo "step 7 of 8: running despeckling filter" -echo "*************************" -echo "" - -lastsmooth=$prefx"smoothdz"$laststep - -if [ "$GIS_FLAG_y" -eq 1 ]; then -echo "" -echo "You have selected not to smooth your files... Oh Well!" -echo "" - -r.mapcalc "$temp2smoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" - -else - -#commenting out the sigma-based truncation because it was causeing deletarious amplification of cell edges. Leaving it commented for posterity only... -#r.mapcalc "$temp2smoothdz=if((abs($tempsmoothdz-$neighbors)) > $GIS_OPT_sigma , $neighbors , $tempsmoothdz)" - -r.mapcalc "$tempsmoothdz=if((-1 * $erdep) >= $old_soil, (-1 * $old_soil), $erdep)" - -r.neighbors --q input=$tempsmoothdz output=$temp2smoothdz method=$GIS_OPT_method size=$GIS_OPT_nbhood - - -fi - -#now we must correct for the incredible edge shrinking effect by patching the last smoothdz underneath the new smoothdz -r.patch input=$temp2smoothdz,$lastsmooth output=$smoothdz - - -echo "" -echo "*************************" -echo "step 8 of 8: calculating terrain evolution and new soil depths/bedrock elevations" -echo "*************************" -echo "" - - -#put the net dz back where it is upposed to go and then subtract it from dem to make new dem -r.mapcalc "$new_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, x)))" - -#make $netchange if asked -if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 0 -o "$GIS_FLAG_t" -eq 0 ]; then - -r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, x)))" - -#set the colors to our rules -r.colors --quiet map=$netchange rules=$TMP1 - -fi - -#set new dem colors to match $elev -r.colors --q map=$new_dem rast=$elev - -if [ $GIS_FLAG_b -eq 1 ]; then - -echo "" -echo "Calculating new soil depths keeping bedrock elevations static" - - -r.mapcalc "$new_soil=if (($new_dem - $initbdrk) < 0, 0, ($new_dem - $initbdrk))" - -else - -echo "" -echo "step 8.5: Calculating new soil depths from landscape curvature" - -r.mapcalc "$meancurv=($pc+$tc/2)" - -# create temporary file to clip the max and min to -TMP5=`g.tempfile pid=$$` - - -max=`eval r.info -r map=$meancurv | grep "max=" | cut -d"=" -f2` -min=`eval r.info -r map=$meancurv | grep "min=" | cut -d"=" -f2` - -echo "" -echo "The raw max ($max) and min ($min) will be rescaled from 2 to 0 " -echo "" - -r.mapcalc "$rate=$kappa*(2-($meancurv*(2/($max)-($min))))" - -#rate is actually the net change in bedrock elevation due to soil production, so lets use it to find the new bedrock elev, and the new soil depth! - -r.mapcalc "$new_bdrk=$old_bdrk - $rate" -r.mapcalc "$new_soil=if (($new_dem - $new_bdrk) < 0, 0, ($new_dem - $new_bdrk))" - -#these are the old soil equations that I failed to be able to implement... I leave them in for documentation purposes -#r.mapcalc "$new_bdrk= $old_bdrk - ($Ba * (exp(($smoothdz - $old_bdrk),$Bb)))" -#r.mapcalc "$new_soil=if (($smoothdz - $old_bdrk) < 0, 0, ($smoothdz - $old_bdrk))" - -fi - -#setting colors to our rules -r.colors --quiet map=$new_soil rules=$TMP4 - - -#grabsomestats -tmperosion=$prfx"_tmperosion"$step -tmpdep=$prfx"_tmpdep"$step - -r.mapcalc "$tmperosion=if($smoothdz < 0, $smoothdz, null())" -r.mapcalc "$tmpdep=if($smoothdz > 0, $smoothdz, null())" - -avesoil=`eval r.univar -g map=$new_soil percentile=90 | grep "mean=" | cut -d'=' -f2` -aveeros=`eval r.univar -g map=$tmperosion percentile=90 | grep "mean=" | cut -d'=' -f2` -avedep=`eval r.univar -g map=$tmpdep percentile=90 | grep "mean=" | cut -d'=' -f2` - -g.remove --quiet rast=$tmperosion,$tmpdep - -echo "outputing stats to textfile: $txtout" - -echo "$step,$aveeros,$avedep,$avesoil" >> $txtout - - -echo "" -echo "*************************" -echo "Done with this iteration" -echo "*************************" - - - - -echo "" -echo "If made, raster map $netchange shows filtered net erosion/deposition" -echo "" -echo "If made, raster map $new_soil shows soildpeths" -echo "" -echo "Raster map $new_dem shows new landscape (new elevations) after net erosion/depostion" -echo "*************************" -echo "########################################################" -echo "" - - - -done - # now we have met the loop critereon set by us above, so we have broken out. - if [ "$GIS_FLAG_c" -eq 1 ]; then - -r.mapcalc "$prefx"cum_erdep"=$new_dem-$elev" - - -#set the colors to our rules -r.colors --quiet map=$prefx"cum_erdep" rules=$TMP1 - + r.mapcalc "$prefx"cum_erdep"=$new_dem-$elev" + + #set the colors to our rules + r.colors --quiet map=$prefx"cum_erdep" rules=$TMP1 fi if [ "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 ]; then + + liststring=`eval g.mlist type=rast sep=, pattern=$prefx"netchange*"` + + echo "Any selected statistics will be performed using the following netchange files: $liststring" -# create temporary file to list all the smoothdz files for statistics -TMP2=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP2" ] ; then - echo "ERROR: unable to create temporary file to list all the netchange files for statistics" 1>&2 - exit 1 fi - -g.mlist type=rast sep=, pattern=$prefx"netchange*" > $TMP2 -liststring=`cat $TMP2` - -echo "Any selected statistics will be performed using the following netchange files: $liststring" - if [ "$GIS_FLAG_m" -eq 1 ]; then -r.series --q input=$liststring output=$prefx"ave_erdep" method=average + r.series --q input=$liststring output=$prefx"ave_erdep" method=average + + #set the colors to our rules + r.colors --quiet map=$prefx"ave_erdep" rules=$TMP1 -#set the colors to our rules -r.colors --quiet map=$prefx"ave_erdep" rules=$TMP1 - fi if [ "$GIS_FLAG_t" -eq 1 ]; then + + r.series --q input=$liststring output=$prefx"sdev_erdep" method=stddev + + #set the colors to our rules + r.colors --quiet map=$prefx"sdev_erdep" rules=$TMP1 -r.series --q input=$liststring output=$prefx"sdev_erdep" method=stddev - -#set the colors to our rules -r.colors --quiet map=$prefx"sdev_erdep" rules=$TMP1 - fi -\rm -f $TMP2 $TMP2.sort - -fi - if [ "$GIS_FLAG_s" -eq 1 -o "$GIS_FLAG_v" -eq 1 -o "$GIS_FLAG_a" -eq 1 -o "$GIS_FLAG_u" -eq 1 ]; then -# create temporary file to list all the soil depth files for statistics -TMP3=`g.tempfile pid=$$` -if [ $? -ne 0 ] || [ -z "$TMP3" ] ; then - echo "ERROR: unable to create temporary file to list all the soil depth files for statistics" 1>&2 - exit 1 + liststring2=`eval g.mlist type=rast sep=, pattern=$prefx$outsoil"*"` + + echo "Any selected statistics will be performed using the following soil depth files: $liststring2" + fi -g.mlist type=rast sep=, pattern=$prefx$outsoil"*" > $TMP3 - -liststring2=`cat $TMP3` - -echo "Any selected statistics will be performed using the following soil depth files: $liststring2" - if [ "$GIS_FLAG_s" -eq 1 ]; then -r.series --q input=$liststring2 output=$prefx"ave_"$outsoil method=average + r.series --q input=$liststring2 output=$prefx"ave_"$outsoil method=average fi if [ "$GIS_FLAG_v" -eq 1 ]; then -r.series --q input=$liststring2 output=$prefx"sdev_"$outsoil method=stddev + r.series --q input=$liststring2 output=$prefx"sdev_"$outsoil method=stddev fi if [ "$GIS_FLAG_a" -eq 1 ]; then -r.series --q input=$liststring2 output=$prefx"max_"$outsoil method=maximum + r.series --q input=$liststring2 output=$prefx"max_"$outsoil method=maximum fi - if [ "$GIS_FLAG_u" -eq 1 ]; then -r.series --q input=$liststring2 output=$prefx"min_"$outsoil method=minimum + r.series --q input=$liststring2 output=$prefx"min_"$outsoil method=minimum fi -\rm -f $TMP3 $TMP3.sort +echo "************************" +echo "" +if [ "$GIS_FLAG_n" -ne 1 ]; then + g.mremove -f --q rast=$prefx"netchange*" fi +#if [ "$GIS_FLAG_n" -eq 1 ]; then +# echo "" +#else +# echo "" +# g.mremove -f --q rast=$prefx"netchange*" +#fi -echo "************************" +if [ "$GIS_FLAG_l" -eq 1 ]; then + g.mremove --q rast=$prefx$outsoil"*" +fi -if [ "$GIS_FLAG_n" -eq 1 ]; then - -echo "" - +if [ "$GIS_FLAG_k" -eq 1 ]; then + echo "" + echo "Done" + echo "" else + echo "" + echo "Cleaning up..." + g.mremove -f --quiet rast=$prefx"flowacc*" -echo "" -g.mremove -f --q rast=$prfx"netchange*" + g.mremove -f --quiet rast=$prefx"slope*" -fi + g.mremove -f --quiet rast=$prefx"aspect*" + g.mremove -f --quiet rast=$prefx"sflowtopo*" -if [ "$GIS_FLAG_l" -eq 1 ]; then + g.mremove -f --quiet rast=$prefx"qsx*" - g.mremove --q rast=$prefx$outsoil"*" -fi + g.mremove -f --quiet rast=$prefx"qsy*" + g.mremove -f --quiet rast=$prefx"erosdep*" -if [ "$GIS_FLAG_k" -eq 1 ]; then + g.mremove -f --quiet rast=$prefx"pc*" -echo "" -echo "Done" -echo "" + g.mremove -f --quiet rast=$prefx"tc*" -else + g.mremove -f --quiet rast=$prefx"mexp*" -echo "" -echo "Cleaning up..." + g.mremove -f --quiet rast=$prefx"nexp*" + g.mremove -f --quiet rast=$prefx"smoothdz*" -g.mremove -f --q rast=$prefx"tmpfilled*" -g.mremove -f --q rast=$prefx"flowacc*" -g.mremove -f --q rast=$prefx"slope*" -g.mremove -f --q rast=$prefx"aspect*" -g.mremove -f --q rast=$prefx"sflowtopo*" -g.mremove -f --q rast=$prefx"flowaspect*" -g.mremove -f --q rast=$prefx"qsx*" -g.mremove -f --q rast=$prefx"qsy*" -g.mremove -f --q rast=$prefx"qsx_dx*" -g.mremove -f --q rast=$prefx"qsy_dy*" -g.mremove -f --q rast=$prefx"erosdep*" -g.mremove -f --q rast=$prefx"pc*" -g.mremove -f --q rast=$prefx"tc*" -g.mremove -f --q rast=$prefx"meancurv*" -g.mremove -f --q rast=$prefx"rate*" -g.mremove -f --q rast=$prefx"tempsmoothdz*" -g.mremove -f --q rast=$prefx"temp2smoothdz*" -g.mremove -f --q rast=$prefx"mexp*" -g.mremove -f --q rast=$prefx"nexp*" -g.mremove -f --q rast=$prefx"smoothdz*" - echo "" - echo "Done" - + echo "" + echo "Done" fi - #remove temporary color rule files \rm -f $TMP1 \rm -f $TMP4 - if [ "$GIS_FLAG_z" -eq 1 ]; then -echo "" -echo "Iterations complete, keeping region set to output maps" -echo "" + echo "" + echo "Iterations complete, keeping region set to output maps" + echo "" else -echo "" -echo "Iterations complete, restoring default region settings" -echo "" + echo "" + echo "Iterations complete, restoring default region settings" + echo "" -g.region -d -g + g.region -d -g -echo "" + echo "" fi + echo "###################################################" echo "###################################################" echo "___________________________________________________" From barton at grass.itc.it Tue Sep 25 08:44:58 2007 From: barton at grass.itc.it (barton@grass.itc.it) Date: Tue Sep 25 08:44:59 2007 Subject: [grass-addons] r1101 - trunk/grassaddons/gui/gui_modules Message-ID: <200709250644.l8P6iw6n024208@grass.itc.it> Author: barton Date: 2007-09-25 08:44:49 +0200 (Tue, 25 Sep 2007) New Revision: 1101 Modified: trunk/grassaddons/gui/gui_modules/georect.py Log: Finally back to working on the georectify module. Changed GCP manager from grid to check list control (with mixin). Buttons to add and delete GCP lines work. Modified: trunk/grassaddons/gui/gui_modules/georect.py =================================================================== --- trunk/grassaddons/gui/gui_modules/georect.py 2007-09-24 20:17:05 UTC (rev 1100) +++ trunk/grassaddons/gui/gui_modules/georect.py 2007-09-25 06:44:49 UTC (rev 1101) @@ -37,6 +37,7 @@ import wx import wx.aui import wx.lib.filebrowsebutton as filebrowse +from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin import wx.wizard as wiz import wx.grid as gridlib @@ -505,6 +506,7 @@ wx.Frame.__init__(self, parent, id , title, size=(500,400)) toolbar = self.__createToolBar() + self.selected = 0 p = wx.Panel(self, -1, style=0) @@ -517,28 +519,35 @@ box.Add(self.rb_grmethod, 0, wx.ALIGN_CENTER|wx.ALL, 5) self.sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.grid = GCPGrid(p) - self.sizer.Add(self.grid, 1, wx.GROW|wx.ALL, 5) +# self.grid = GCPGrid(p) + self.list = CheckListCtrl(p) + self.sizer.Add(self.list, 1, wx.GROW|wx.ALL, 5) + self.list.InsertColumn(0, 'use| X coord', width=120) + self.list.InsertColumn(1, 'Y coord') + self.list.InsertColumn(2, 'N coord') + self.list.InsertColumn(3, 'E coord') + self.list.InsertColumn(4, 'Forward error') + self.list.InsertColumn(5, 'Backward error') - box = wx.BoxSizer(wx.HORIZONTAL) - self.btn_newGCP = wx.Button(p, -1, "Add GCP") - self.btn_newGCP.SetDefault() - box.Add(self.btn_newGCP, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.btn_deleteGCP = wx.Button(p, -1, "Delete selected GCP") - box.Add(self.btn_deleteGCP, 0, wx.ALIGN_LEFT|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5) - self.sizer.Add(box) + initlist = [('0000000.00','0000000.00','0000000.00','0000000.00','0000.00','0000.00'), \ + ('0000000.00','0000000.00','0000000.00','0000000.00','0000.00','0000.00'), \ + ('0000000.00','0000000.00','0000000.00','0000000.00','0000.00','0000.00'), \ + ('0000000.00','0000000.00','0000000.00','0000000.00','0000.00','0000.00')] + for i in initlist: + index = self.list.InsertStringItem(4, i[0]) + self.list.SetStringItem(index, 1, i[1]) + self.list.SetStringItem(index, 2, i[2]) + self.list.SetStringItem(index, 3, i[3]) + self.list.SetStringItem(index, 4, i[4]) + self.list.SetStringItem(index, 5, i[5]) + + p.SetSizer(self.sizer) self.Bind(wx.EVT_RADIOBOX, self.OnGRMethod, self.rb_grmethod) - self.Bind(wx.EVT_BUTTON, self.OnButton, self.btn_newGCP) - self.btn_newGCP.Bind(wx.EVT_SET_FOCUS, self.OnButtonFocus) + self.list.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected) - def OnButton(self, evt): - print "button selected" - def OnButtonFocus(self, evt): - print "button focus" - def __createToolBar(self): """Creates toolbar""" @@ -560,15 +569,24 @@ return ( ('savegcp', Icons["savefile"].GetBitmap(), Icons["savefile"].GetLabel(), self.SaveGCP), + ('addgcp', wx.ArtProvider.GetBitmap(wx.ART_NEW, wx.ART_TOOLBAR, (16,16)), 'Add new GCP', self.AddGCP), + ('deletegcp', wx.ArtProvider.GetBitmap(wx.ART_DELETE, wx.ART_TOOLBAR, (16,16)), 'Delete selected GCP', self.DeleteGCP), ('cleargcp', Icons["cleargcp"].GetBitmap(), Icons["cleargcp"].GetLabel(), self.ClearGCP), ('rms', Icons["rms"].GetBitmap(), Icons["rms"].GetLabel(), self.OnRMS), ('georect', Icons["georect"].GetBitmap(), Icons["georect"].GetLabel(), self.OnGeorect), - ('quit', Icons["quit"].GetBitmap(), Icons["quit"].GetLabel(), self.OnQuit) + ('quit', wx.ArtProvider.GetBitmap(wx.ART_QUIT, wx.ART_TOOLBAR, (16,16)), 'Quit georectification module', self.OnQuit) ) def SaveGCP(self, event): pass + def DeleteGCP(self, event): + self.list.DeleteItem(self.selected) + pass + + def AddGCP(self, event): + self.list.Append(['0000000.00','0000000.00','0000000.00','0000000.00','0000.00','0000.00']) + def ClearGCP(self, event): pass @@ -584,7 +602,17 @@ def OnGRMethod(self, event): pass + def OnItemSelected(self, event): + self.selected = event.GetIndex() + +class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): + def __init__(self, parent): + wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT | wx.SUNKEN_BORDER) + CheckListCtrlMixin.__init__(self) + ListCtrlAutoWidthMixin.__init__(self) + + class GCPGrid(gridlib.Grid): def __init__(self, parent): gridlib.Grid.__init__(self, parent, -1) @@ -617,9 +645,9 @@ gridlib.GRID_VALUE_FLOAT + ':7,2', ] self.data = [ - [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00], - [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00], - [1, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00, 0000000.00] + [1, '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00'], + [1, '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00'], + [1, '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00', '0000000.00'] ] #-------------------------------------------------- # required methods for the wxPyGridTableBase interface From landa at grass.itc.it Tue Sep 25 09:48:14 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Tue Sep 25 09:48:18 2007 Subject: [grass-addons] r1102 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709250748.l8P7mEWn025347@grass.itc.it> Author: landa Date: 2007-09-25 09:48:05 +0200 (Tue, 25 Sep 2007) New Revision: 1102 Added: trunk/grassaddons/gui/display_driver/driver.cpp Removed: trunk/grassaddons/gui/display_driver/driver.cc Modified: trunk/grassaddons/gui/display_driver/Makefile trunk/grassaddons/gui/display_driver/driver.h trunk/grassaddons/gui/display_driver/driver.i trunk/grassaddons/gui/gui_modules/dbm.py trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Various fixes for digitization tool. driver.cc renamed to driver.cpp. Modified: trunk/grassaddons/gui/display_driver/Makefile =================================================================== --- trunk/grassaddons/gui/display_driver/Makefile 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/display_driver/Makefile 2007-09-25 07:48:05 UTC (rev 1102) @@ -27,7 +27,7 @@ grass6_wxdriver_wrap.o: grass6_wxdriver_wrap.cxx $(CXX) $(CFLAGS) $(INCLUDE_DIRS) $< -driver.o: driver.cc +driver.o: driver.cpp $(CXX) $(CFLAGS) $(INCLUDE_DIRS) $< pseudodc.o: pseudodc.cpp Deleted: trunk/grassaddons/gui/display_driver/driver.cc =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cc 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/display_driver/driver.cc 2007-09-25 07:48:05 UTC (rev 1102) @@ -1,848 +0,0 @@ -/** - \file driver.cc - - \brief Experimental C++ wxWidgets display driver - - This driver is designed for wxPython GRASS GUI (digitization tool). - Draw vector map layer to PseudoDC. - - \author Martin Landa - - (C) 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. -*/ - -#include "driver.h" - -/** - \brief Initialize driver - - Allocate given structures. - - \param[in,out] PseudoDC device where to draw vector objects - - \return -*/ -DisplayDriver::DisplayDriver(void *device) -{ - G_gisinit(""); /* GRASS functions */ - - mapInfo = NULL; - dcId = 1; - - dc = (wxPseudoDC *) device; - - points = Vect_new_line_struct(); - pointsScreen = new wxList(); - cats = Vect_new_cats_struct(); - -} - -/** - \brief Destroy driver - - Close the map, deallocate given structures. - - \param - - \return -*/ -DisplayDriver::~DisplayDriver() -{ - if (mapInfo) - CloseMap(); - - Vect_destroy_line_struct(points); - delete pointsScreen; - Vect_destroy_cats_struct(cats); -} - -/** - \brief Set device for drawing - - \param[in,out] PseudoDC device where to draw vector objects - - \return -*/ -void DisplayDriver::SetDevice(void *device) -{ - dc = (wxPseudoDC *) device; - - return; -} - -/** - \brief Draw content of the vector map to device - - \return number of lines which were drawn - \return -1 on error - */ -int DisplayDriver::DrawMap() -{ - if (!mapInfo || !dc) - return -1; - - int nlines; - BOUND_BOX mapBox; - struct ilist *listLines; - - // initialize - dcId = 1; - ids.clear(); - listLines = Vect_new_list(); - - /* nlines = Vect_get_num_lines(mapInfo); */ - - //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); - //Vect_build(mapInfo, stderr); - - // draw lines inside of current display region - // nlines = Vect_select_lines_by_box(mapInfo, &(region.box), - // GV_POINTS | GV_LINES, // fixme - // listLines); - - Vect_get_map_box(mapInfo, &mapBox); - nlines = Vect_select_lines_by_box(mapInfo, &mapBox, - GV_POINTS | GV_LINES, // fixme - listLines); - - for (int i = 0; i < listLines->n_values; i++) { - DrawLine(listLines->value[i]); - } - -#ifdef DEBUG - std::cout << "region: W=" << region.box.W - << "; E=" << region.box.E - << "; S=" << region.box.S - << "; N=" << region.box.N << std::endl; - - std::cout << "-> nlines=" << nlines << std::endl; -#endif - - /* - nlines = Vect_get_num_lines(mapInfo); - for (int line = 1; line <= nlines; line++) { - DrawLine(line); - } - */ -#ifdef DEBUG - PrintIds(); -#endif - - Vect_destroy_list(listLines); - - return listLines->n_values; -} - -/** - \brief Draw selected vector objects to the device - - \param[in] line id - - \return 1 on success - \return -1 on failure (vector object is dead, etc.) -*/ -int DisplayDriver::DrawLine(int line) -{ - if (!dc || !Vect_line_alive (mapInfo, line)) - return -1; - - int type; // line type - int x, y, z; // screen coordinates - bool draw; // draw object ? - - // read line - type = Vect_read_line (mapInfo, points, cats, line); - - // clear screen points & convert EN -> xy - pointsScreen->Clear(); - for (int i = 0; i < points->n_points; i++) { - Cell2Pixel(points->x[i], points->y[i], points->z[i], - &x, &y, &z); - pointsScreen->Append((wxObject*) new wxPoint(x, y)); /* TODO: 3D */ - } - - // add ids - // -> node1, line1, vertex1, line2, ..., node2 - struct lineDesc desc = {points->n_points, dcId}; - ids[line] = desc; - // update id for next line - dcId += points->n_points * 2 - 1; - - // determine color of vector object - if (IsSelected(line)) { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); - draw = true; - } - else { - if (type & GV_LINES) { - switch (type) { - case GV_LINE: - dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID)); - draw = settings.line.enabled; - break; - case GV_BOUNDARY: - int left, right; - Vect_get_line_areas(mapInfo, line, - &left, &right); - if (left == 0 && right == 0) { - dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryNo.enabled; - } - else if (left > 0 && right > 0) { - dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryTwo.enabled; - } - else { - dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID)); - draw = settings.boundaryOne.enabled; - } - break; - default: - draw = false; - break; - } - } - else if (type & GV_POINTS) { - if (type == GV_POINT && settings.point.enabled) { - dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID)); - draw = true; - } - 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)); - } - else if (cret == 0) { - draw = settings.centroidOut.enabled; - dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID)); - } - else { - draw = settings.centroidDup.enabled; - dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID)); - } - } - } - } - - // draw object - if (draw) { - 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) { - 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->DrawLine(point_beg->x, point_beg->y, - point_end->x, point_end->y); - } - DrawLineVerteces(line); // draw vertices - DrawLineNodes(line); // draw nodes - } - } - - return 1; -} - -/** - \brief Draw line verteces to the device - - Except of first and last vertex, see DrawLineNodes(). - - \param line id - - \return number of verteces which were drawn - \return -1 if drawing vertices is disabled -*/ -int DisplayDriver::DrawLineVerteces(int line) -{ - long int id; - wxPoint *point; - - if (!settings.vertex.enabled) - return -1; - - // determine color - if (!IsSelected(line)) { - dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID)); - } - else { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); - } - - // set id - id = ids[line].startId + 2; - for (int i = 1; i < pointsScreen->GetCount() - 1; i++, id += 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()); - } - - return pointsScreen->GetCount() - 2; -} - -/** - \brief Draw line nodes to the device - - \param line id - - \return 1 - \return -1 if no nodes were drawn -*/ -int DisplayDriver::DrawLineNodes(int line) -{ - int node; - long int id; - double east, north, depth; - int x, y, z; - int nodes [2]; - bool draw; - - // draw nodes?? - if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled) - return -1; - - // get nodes - Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1])); - - for (int i = 0; i < sizeof(nodes) / sizeof(int); i++) { - node = nodes[i]; - // get coordinates - Vect_get_node_coor(mapInfo, node, - &east, &north, &depth); - - // convert EN->xy - Cell2Pixel(east, north, depth, - &x, &y, &z); - - // determine color - if (IsSelected(line)) { - dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); - draw = true; - } - else { - if (Vect_get_node_n_lines(mapInfo, node) == 1) { - dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID)); - draw = settings.nodeOne.enabled; - } - else { - dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID)); - 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); - - // draw node if needed - if (draw) { - dc->SetId(id); - DrawCross(line, &point); - } - } - - return 1; -} - - -/* - \brief Close vector map layer - - \param - - \return -*/ -void DisplayDriver::CloseMap() -{ - if (mapInfo) { - Vect_close(mapInfo); - G_free ((void *) mapInfo); - mapInfo = NULL; - } - - return; -} - -/** - \brief Open vector map layer - - \param[in] mapname name of vector map - \param[in] mapset name of mapset where the vector map layer is stored - - \return -*/ -void DisplayDriver::OpenMap(const char* mapname, const char *mapset) -{ - if (!mapInfo) - mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info)); - - // define open level (level 2: topology) - Vect_set_open_level(2); - - // open existing map - Vect_open_old(mapInfo, (char*) mapname, (char *) mapset); - - return; -} - -/** - \brief Reload vector map layer - - Close and open again. Needed for modification using v.edit. - - TODO: Get rid of that... - - \param - - \return -*/ -void DisplayDriver::ReloadMap() -{ - // char* name = G_store(Vect_get_map_name(mapInfo)); ??? - char* name = G_store(mapInfo->name); - char* mapset = G_store(Vect_get_mapset(mapInfo)); - - Vect_close(mapInfo); - mapInfo = NULL; - - OpenMap(name, mapset); - //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); - //Vect_build(mapInfo, stderr); - - return; -} - -/* - \brief Conversion from geographic coordinates (east, north) - to screen (x, y) - - TODO: 3D stuff... - - \param[in] east,north,depth geographical coordinates - \param[out] x, y, z screen coordinates - - \return -*/ -void DisplayDriver::Cell2Pixel(double east, double north, double depth, - int *x, int *y, int *z) -{ - *x = int((east - region.map_west) / region.map_res); - *y = int((region.map_north - north) / region.map_res); - *z = 0; - - return; -} - -/** - \brief Set geographical region - - Region must be upgraded because of Cell2Pixel(). - - \param[in] north,south,east,west,ns_res,ew_res region settings - - \return -*/ -void DisplayDriver::SetRegion(double north, double south, double east, double west, - double ns_res, double ew_res, - double center_easting, double center_northing, - double map_width, double map_height) -{ - region.box.N = north; - region.box.S = south; - region.box.E = east; - region.box.W = west; - region.ns_res = ns_res; - region.ew_res = ew_res; - - region.center_easting = center_easting; - region.center_northing = center_northing; - - region.map_width = map_width; - region.map_height = map_height; - - // calculate real region - region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res; - - region.map_west = region.center_easting - (region.map_width / 2.) * region.map_res; - region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res; - - return; -} - -/** - \brief Draw cross symbol of given size to device content - - Used for points, nodes, vertices - - \param[in] point coordinates of center - \param[in] size size of the cross symbol - - \return 1 on success - \return -1 on failure -*/ -int DisplayDriver::DrawCross(int line, const wxPoint* point, int size) -{ - if (!dc || !point) - return -1; - - 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; -} - -/* - \brief Set settings for displaying vector feature - - E.g. line width, color, ... - - \param[in] lineWidth,... settgings - - \return -*/ -void DisplayDriver::SetSettings(unsigned long highlight, - bool ePoint, unsigned long cPoint, /* enabled, color */ - bool eLine, unsigned long cLine, - bool eBoundaryNo, unsigned long cBoundaryNo, - bool eBoundaryOne, unsigned long cBoundaryOne, - bool eBoundaryTwo, unsigned long cBoundaryTwo, - bool eCentroidIn, unsigned long cCentroidIn, - bool eCentroidOut, unsigned long cCentroidOut, - bool eCentroidDup, unsigned long cCentroidDup, - bool eNodeOne, unsigned long cNodeOne, - bool eNodeTwo, unsigned long cNodeTwo, - bool eVertex, unsigned long cVertex, - int lineWidth) -{ - settings.highlight.Set(highlight); - - settings.point.enabled = ePoint; - settings.point.color.Set(cPoint); - - settings.line.enabled = eLine; - settings.line.color.Set(cLine); - - settings.boundaryNo.enabled = eBoundaryNo; - settings.boundaryNo.color.Set(cBoundaryNo); - settings.boundaryOne.enabled = eBoundaryOne; - settings.boundaryOne.color.Set(cBoundaryOne); - settings.boundaryTwo.enabled = eBoundaryTwo; - settings.boundaryTwo.color.Set(cBoundaryTwo); - - - settings.centroidIn.enabled = eCentroidIn; - settings.centroidIn.color.Set(cCentroidIn); - settings.centroidOut.enabled = eCentroidOut; - settings.centroidOut.color.Set(cCentroidOut); - settings.centroidDup.enabled = eCentroidDup; - settings.centroidDup.color.Set(cCentroidDup); - - settings.nodeOne.enabled = eNodeOne; - settings.nodeOne.color.Set(cNodeOne); - settings.nodeTwo.enabled = eNodeTwo; - settings.nodeTwo.color.Set(cNodeTwo); - - settings.vertex.enabled = eVertex; - settings.vertex.color.Set(cVertex); - - - settings.lineWidth = lineWidth; - -} - -/** - \brief Prints gId: dcIds - - Useful for debugging purposes. - - \param - - \return -*/ -void DisplayDriver::PrintIds() -{ - for (ids_map::const_iterator i = ids.begin(), e = ids.end(); - i != e; ++i) { - std::cout << "line=" << i->first << ": " - << "npoints=" << i->second.npoints - << " startId=" << i->second.startId - << std::endl; - } - - for (std::vector::const_iterator i = selected.begin(), e = selected.end(); - i != e; ++i) - std::cout << "selected: " << *i << " "; - std::cout << std::endl; - - return; -} - -/** - \brief Select vector objects by given bounding box - - \param[in] x1,y1,x2,y2 corners coordinates of bounding box - - \return number of selected features - \return -1 on error -*/ -int DisplayDriver::SelectLinesByBox(double x1, double y1, double x2, double y2) -{ - if (!mapInfo) - return -1; - - int type, line; - double dx, dy; - - struct ilist *list; - struct line_pnts *bbox; - - type = -1; // all types - - list = Vect_new_list(); - bbox = Vect_new_line_struct(); - - 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_select_lines_by_polygon(mapInfo, bbox, - 0, NULL, - type, list); - - for (int i = 0; i < list->n_values; i++) { - line = list->value[i]; - selected.push_back(line); - } - - // remove all duplicate ids - sort(selected.begin(), selected.end()); - selected.erase(unique(selected.begin(), selected.end()), selected.end()); - - Vect_destroy_line_struct(bbox); - Vect_destroy_list(list); - - return selected.size(); -} - -/** - \brief Select vector feature by given point in given - threshold - - Only one vector object can be selected. - - \param[in] x,y point of searching - \param[in] thresh threshold value where to search - \param[in] onlyType select vector object of given type - - \return 1 vector object found - \return 0 no vector object found -*/ -int DisplayDriver::SelectLinesByPoint(double x, double y, double thresh, - int onlyType) -{ - int line; - - line = Vect_find_line(mapInfo, x, y, 0.0, - GV_POINTS | GV_LINES, thresh, 0, 0); - - std::cout << x << " " << y << " " << thresh << "->" << line << std::endl; - - if (line > 0) { - selected.push_back(line); - return 1; - } - - return 0; -} - -/** - \brief Is vector object selected? - - \param[in] line id - - \return true if vector object is selected - \return false if vector object is not selected -*/ -bool DisplayDriver::IsSelected(int line) -{ - for(std::vector::const_iterator i = selected.begin(), e = selected.end(); - i != e; ++i) { - if (line == *i) - return true; - } - - return false; -} - -/** - \brief Unselect selected features by user - - Clear list of ids of selected vector objects - - \param - - \return -*/ -void DisplayDriver::Unselect() -{ - selected.clear(); - - return; -} - -/** - \brief Get ids of selected objects - - \param[in] grassId if true return GRASS line ids - if false return PseudoDC ids - - \return list of ids of selected vector objects -*/ -std::vector DisplayDriver::GetSelected(bool grassId) -{ - if (grassId) - return selected; - - std::vector dc_ids; - - for(std::vector::const_iterator i = selected.begin(), e = selected.end(); - i != e; ++i) { - ids_map::const_iterator ii = ids.find(*i); - if (ii != ids.end()) { // line found - long int endId = ii->second.npoints * 2 - 1 + ii->second.startId; - for (long int id = ii->second.startId; id < endId; id++) { - dc_ids.push_back(id); - } - } - } - - return dc_ids; -} - -/** - \brief Set selected vector objects - - \param[in] list of GRASS ids to be set - - \return 1 -*/ -int DisplayDriver::SetSelected(std::vector id) -{ - selected = id; - - return 1; -} - -/** - \brief Get PseudoDC vertex id of selected line - - \param[in] x,y coordinates of click - - \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) -{ - struct lineDesc *desc; // line desription - - int line, type; - int Gid, DCid; - int vx, vy, vz; // vertex screen coordinates - - double dist, minDist; - - std::vector returnId; - - // only one object can be selected - if (selected.size() != 1) - return returnId; - - line = selected[0]; - - type = Vect_read_line (mapInfo, points, cats, line); - - // find the closest vertex (x, y) - 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); - - if (idx == 0) { - minDist = dist; - Gid = idx; - } - else { - if (minDist > dist) { - minDist = dist; - Gid = idx; - } - } - } - - desc = &(ids[line]); - - // translate id - DCid = Gid * 2 + desc->startId; - - // add selected vertex - returnId.push_back(DCid); - Cell2Pixel(points->x[Gid], points->y[Gid], points->z[Gid], - &vx, &vy, &vz); - wxRect rect (vx, vy, 0, 0); - dc->SetIdBounds(DCid, rect); - - // left vertex - if (DCid == desc->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 (vx, vy, 0, 0); - dc->SetIdBounds(DCid-2, rect); - } - - // right vertex - if (DCid == (desc->npoints - 1) * 2 + desc->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 (vx, vy, 0, 0); - dc->SetIdBounds(DCid + 2, rect); - } - - return returnId; -} Copied: trunk/grassaddons/gui/display_driver/driver.cpp (from rev 1100, trunk/grassaddons/gui/display_driver/driver.cc) =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cpp (rev 0) +++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-25 07:48:05 UTC (rev 1102) @@ -0,0 +1,857 @@ +/** + \file driver.cpp + + \brief Experimental C++ wxWidgets display driver + + This driver is designed for wxPython GRASS GUI (digitization tool). + Draw vector map layer to PseudoDC. + + \author Martin Landa + + (C) 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. +*/ + +#include "driver.h" + +/** + \brief Initialize driver + + Allocate given structures. + + \param[in,out] PseudoDC device where to draw vector objects + + \return +*/ +DisplayDriver::DisplayDriver(void *device) +{ + G_gisinit(""); /* GRASS functions */ + + mapInfo = NULL; + dcId = 1; + + dc = (wxPseudoDC *) device; + + points = Vect_new_line_struct(); + pointsScreen = new wxList(); + cats = Vect_new_cats_struct(); + +} + +/** + \brief Destroy driver + + Close the map, deallocate given structures. + + \param + + \return +*/ +DisplayDriver::~DisplayDriver() +{ + if (mapInfo) + CloseMap(); + + Vect_destroy_line_struct(points); + delete pointsScreen; + Vect_destroy_cats_struct(cats); +} + +/** + \brief Set device for drawing + + \param[in,out] PseudoDC device where to draw vector objects + + \return +*/ +void DisplayDriver::SetDevice(void *device) +{ + dc = (wxPseudoDC *) device; + + return; +} + +/** + \brief Draw content of the vector map to device + + \return number of lines which were drawn + \return -1 on error + */ +int DisplayDriver::DrawMap() +{ + if (!mapInfo || !dc) + return -1; + + int nlines; + BOUND_BOX mapBox; + struct ilist *listLines; + + // initialize + dcId = 1; + ids.clear(); + listLines = Vect_new_list(); + + /* nlines = Vect_get_num_lines(mapInfo); */ + + //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); + //Vect_build(mapInfo, stderr); + + // draw lines inside of current display region + /* + nlines = Vect_select_lines_by_box(mapInfo, &(region.box), + GV_POINTS | GV_LINES, // fixme + listLines); + */ + Vect_get_map_box(mapInfo, &mapBox); + nlines = Vect_select_lines_by_box(mapInfo, &mapBox, + GV_POINTS | GV_LINES, // fixme + listLines); + + for (int i = 0; i < listLines->n_values; i++) { + DrawLine(listLines->value[i]); + } + +#ifdef DEBUG + std::cout << "region: W=" << region.box.W + << "; E=" << region.box.E + << "; S=" << region.box.S + << "; N=" << region.box.N << std::endl; + + std::cout << "-> nlines=" << nlines << std::endl; +#endif + + /* + nlines = Vect_get_num_lines(mapInfo); + for (int line = 1; line <= nlines; line++) { + DrawLine(line); + } + */ + +#ifdef DEBUG + PrintIds(); +#endif + + Vect_destroy_list(listLines); + + return listLines->n_values; +} + +/** + \brief Draw selected vector objects to the device + + \param[in] line id + + \return 1 on success + \return -1 on failure (vector object is dead, etc.) +*/ +int DisplayDriver::DrawLine(int line) +{ + if (!dc || !Vect_line_alive (mapInfo, line)) + return -1; + + int type; // line type + int x, y, z; // screen coordinates + bool draw; // draw object ? + + // read line + type = Vect_read_line (mapInfo, points, cats, line); + + // clear screen points & convert EN -> xy + pointsScreen->Clear(); + for (int i = 0; i < points->n_points; i++) { + Cell2Pixel(points->x[i], points->y[i], points->z[i], + &x, &y, &z); + pointsScreen->Append((wxObject*) new wxPoint(x, y)); /* TODO: 3D */ + } + + // add ids + // -> node1, line1, vertex1, line2, ..., node2 + struct lineDesc desc = {points->n_points, dcId}; + ids[line] = desc; + // update id for next line + dcId += points->n_points * 2 - 1; + + // determine color of vector object + if (IsSelected(line)) { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + draw = true; + } + else { + if (type & GV_LINES) { + switch (type) { + case GV_LINE: + dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID)); + draw = settings.line.enabled; + break; + case GV_BOUNDARY: + int left, right; + Vect_get_line_areas(mapInfo, line, + &left, &right); + if (left == 0 && right == 0) { + dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryNo.enabled; + } + else if (left > 0 && right > 0) { + dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryTwo.enabled; + } + else { + dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID)); + draw = settings.boundaryOne.enabled; + } + break; + default: + draw = false; + break; + } + } + else if (type & GV_POINTS) { + if (type == GV_POINT && settings.point.enabled) { + dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID)); + draw = true; + } + 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)); + } + else if (cret == 0) { + draw = settings.centroidOut.enabled; + dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID)); + } + else { + draw = settings.centroidDup.enabled; + dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID)); + } + } + } + } + + // draw object + if (draw) { + 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) { + 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->DrawLine(point_beg->x, point_beg->y, + point_end->x, point_end->y); + } + DrawLineVerteces(line); // draw vertices + DrawLineNodes(line); // draw nodes + } + } + + return 1; +} + +/** + \brief Draw line verteces to the device + + Except of first and last vertex, see DrawLineNodes(). + + \param line id + + \return number of verteces which were drawn + \return -1 if drawing vertices is disabled +*/ +int DisplayDriver::DrawLineVerteces(int line) +{ + long int id; + wxPoint *point; + + if (!settings.vertex.enabled) + return -1; + + // determine color + if (!IsSelected(line)) { + dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID)); + } + else { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + } + + // set id + id = ids[line].startId + 2; + for (int i = 1; i < pointsScreen->GetCount() - 1; i++, id += 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()); + } + + return pointsScreen->GetCount() - 2; +} + +/** + \brief Draw line nodes to the device + + \param line id + + \return 1 + \return -1 if no nodes were drawn +*/ +int DisplayDriver::DrawLineNodes(int line) +{ + int node; + long int id; + double east, north, depth; + int x, y, z; + int nodes [2]; + bool draw; + + // draw nodes?? + if (!settings.nodeOne.enabled && !settings.nodeTwo.enabled) + return -1; + + // get nodes + Vect_get_line_nodes(mapInfo, line, &(nodes[0]), &(nodes[1])); + + for (int i = 0; i < sizeof(nodes) / sizeof(int); i++) { + node = nodes[i]; + // get coordinates + Vect_get_node_coor(mapInfo, node, + &east, &north, &depth); + + // convert EN->xy + Cell2Pixel(east, north, depth, + &x, &y, &z); + + // determine color + if (IsSelected(line)) { + dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); + draw = true; + } + else { + if (Vect_get_node_n_lines(mapInfo, node) == 1) { + dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID)); + draw = settings.nodeOne.enabled; + } + else { + dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID)); + 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); + + // draw node if needed + if (draw) { + dc->SetId(id); + DrawCross(line, &point); + } + } + + return 1; +} + + +/* + \brief Close vector map layer + + \param + + \return +*/ +void DisplayDriver::CloseMap() +{ + if (mapInfo) { + Vect_close(mapInfo); + G_free ((void *) mapInfo); + mapInfo = NULL; + } + + return; +} + +/** + \brief Open vector map layer + + \param[in] mapname name of vector map + \param[in] mapset name of mapset where the vector map layer is stored + + \return +*/ +void DisplayDriver::OpenMap(const char* mapname, const char *mapset) +{ + if (!mapInfo) + mapInfo = (struct Map_info *) G_malloc (sizeof (struct Map_info)); + + // define open level (level 2: topology) + Vect_set_open_level(2); + + // open existing map + Vect_open_old(mapInfo, (char*) mapname, (char *) mapset); + + return; +} + +/** + \brief Reload vector map layer + + Close and open again. Needed for modification using v.edit. + + TODO: Get rid of that... + + \param + + \return +*/ +void DisplayDriver::ReloadMap() +{ + // char* name = G_store(Vect_get_map_name(mapInfo)); ??? + char* name = G_store(mapInfo->name); + char* mapset = G_store(Vect_get_mapset(mapInfo)); + + Vect_close(mapInfo); + mapInfo = NULL; + + OpenMap(name, mapset); + //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); + //Vect_build(mapInfo, stderr); + + return; +} + +/* + \brief Conversion from geographic coordinates (east, north) + to screen (x, y) + + TODO: 3D stuff... + + \param[in] east,north,depth geographical coordinates + \param[out] x, y, z screen coordinates + + \return +*/ +void DisplayDriver::Cell2Pixel(double east, double north, double depth, + int *x, int *y, int *z) +{ + *x = int((east - region.map_west) / region.map_res); + *y = int((region.map_north - north) / region.map_res); + *z = 0; + + return; +} + +/** + \brief Set geographical region + + Region must be upgraded because of Cell2Pixel(). + + \param[in] north,south,east,west,ns_res,ew_res region settings + + \return +*/ +void DisplayDriver::SetRegion(double north, double south, double east, double west, + double ns_res, double ew_res, + double center_easting, double center_northing, + double map_width, double map_height) +{ + region.box.N = north; + region.box.S = south; + region.box.E = east; + region.box.W = west; + region.ns_res = ns_res; + region.ew_res = ew_res; + + region.center_easting = center_easting; + region.center_northing = center_northing; + + region.map_width = map_width; + region.map_height = map_height; + + // calculate real region + region.map_res = (region.ew_res > region.ns_res) ? region.ew_res : region.ns_res; + + region.map_west = region.center_easting - (region.map_width / 2.) * region.map_res; + region.map_north = region.center_northing + (region.map_height / 2.) * region.map_res; + + return; +} + +/** + \brief Draw cross symbol of given size to device content + + Used for points, nodes, vertices + + \param[in] point coordinates of center + \param[in] size size of the cross symbol + + \return 1 on success + \return -1 on failure +*/ +int DisplayDriver::DrawCross(int line, const wxPoint* point, int size) +{ + if (!dc || !point) + return -1; + + 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; +} + +/* + \brief Set settings for displaying vector feature + + E.g. line width, color, ... + + \param[in] lineWidth,... settgings + + \return +*/ +void DisplayDriver::SetSettings(unsigned long highlight, + bool ePoint, unsigned long cPoint, /* enabled, color */ + bool eLine, unsigned long cLine, + bool eBoundaryNo, unsigned long cBoundaryNo, + bool eBoundaryOne, unsigned long cBoundaryOne, + bool eBoundaryTwo, unsigned long cBoundaryTwo, + bool eCentroidIn, unsigned long cCentroidIn, + bool eCentroidOut, unsigned long cCentroidOut, + bool eCentroidDup, unsigned long cCentroidDup, + bool eNodeOne, unsigned long cNodeOne, + bool eNodeTwo, unsigned long cNodeTwo, + bool eVertex, unsigned long cVertex, + int lineWidth) +{ + settings.highlight.Set(highlight); + + settings.point.enabled = ePoint; + settings.point.color.Set(cPoint); + + settings.line.enabled = eLine; + settings.line.color.Set(cLine); + + settings.boundaryNo.enabled = eBoundaryNo; + settings.boundaryNo.color.Set(cBoundaryNo); + settings.boundaryOne.enabled = eBoundaryOne; + settings.boundaryOne.color.Set(cBoundaryOne); + settings.boundaryTwo.enabled = eBoundaryTwo; + settings.boundaryTwo.color.Set(cBoundaryTwo); + + + settings.centroidIn.enabled = eCentroidIn; + settings.centroidIn.color.Set(cCentroidIn); + settings.centroidOut.enabled = eCentroidOut; + settings.centroidOut.color.Set(cCentroidOut); + settings.centroidDup.enabled = eCentroidDup; + settings.centroidDup.color.Set(cCentroidDup); + + settings.nodeOne.enabled = eNodeOne; + settings.nodeOne.color.Set(cNodeOne); + settings.nodeTwo.enabled = eNodeTwo; + settings.nodeTwo.color.Set(cNodeTwo); + + settings.vertex.enabled = eVertex; + settings.vertex.color.Set(cVertex); + + + settings.lineWidth = lineWidth; + +} + +/** + \brief Prints gId: dcIds + + Useful for debugging purposes. + + \param + + \return +*/ +void DisplayDriver::PrintIds() +{ + for (ids_map::const_iterator i = ids.begin(), e = ids.end(); + i != e; ++i) { + std::cout << "line=" << i->first << ": " + << "npoints=" << i->second.npoints + << " startId=" << i->second.startId + << std::endl; + } + + for (std::vector::const_iterator i = selected.begin(), e = selected.end(); + i != e; ++i) + std::cout << "selected: " << *i << " "; + std::cout << std::endl; + + return; +} + +/** + \brief Select vector objects by given bounding box + + \param[in] x1,y1,x2,y2 corners coordinates of bounding box + + \return number of selected features + \return -1 on error +*/ +int DisplayDriver::SelectLinesByBox(double x1, double y1, double x2, double y2) +{ + if (!mapInfo) + return -1; + + int type, line; + double dx, dy; + + struct ilist *list; + struct line_pnts *bbox; + + type = -1; // all types + + list = Vect_new_list(); + bbox = Vect_new_line_struct(); + + 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_select_lines_by_polygon(mapInfo, bbox, + 0, NULL, + type, list); + + for (int i = 0; i < list->n_values; i++) { + line = list->value[i]; + selected.push_back(line); + } + + // remove all duplicate ids + sort(selected.begin(), selected.end()); + selected.erase(unique(selected.begin(), selected.end()), selected.end()); + + Vect_destroy_line_struct(bbox); + Vect_destroy_list(list); + + return selected.size(); +} + +/** + \brief Select vector feature by given point in given + threshold + + Only one vector object can be selected. + + \param[in] x,y point of searching + \param[in] thresh threshold value where to search + \param[in] onlyType select vector object of given type + + \return point on line if line found +*/ +std::vector DisplayDriver::SelectLineByPoint(double x, double y, double thresh, + int onlyType) +{ + long int line; + int type; + double px, py, pz; + + std::vector p; + line = Vect_find_line(mapInfo, x, y, 0.0, + GV_POINTS | GV_LINES, thresh, 0, 0); + + std::cout << x << " " << y << " " << thresh << "->" << line << std::endl; + + if (line > 0) { + selected.push_back(line); + type = Vect_read_line (mapInfo, points, cats, line); + Vect_line_distance (points, x, y, 0.0, WITHOUT_Z, + &px, &py, &pz, + NULL, NULL, NULL); + p.push_back(px); + p.push_back(py); + } + + return p; +} + +/** + \brief Is vector object selected? + + \param[in] line id + + \return true if vector object is selected + \return false if vector object is not selected +*/ +bool DisplayDriver::IsSelected(int line) +{ + for(std::vector::const_iterator i = selected.begin(), e = selected.end(); + i != e; ++i) { + if (line == *i) + return true; + } + + return false; +} + +/** + \brief Unselect selected features by user + + Clear list of ids of selected vector objects + + \param + + \return +*/ +void DisplayDriver::Unselect() +{ + selected.clear(); + + return; +} + +/** + \brief Get ids of selected objects + + \param[in] grassId if true return GRASS line ids + if false return PseudoDC ids + + \return list of ids of selected vector objects +*/ +std::vector DisplayDriver::GetSelected(bool grassId) +{ + if (grassId) + return selected; + + std::vector dc_ids; + + for(std::vector::const_iterator i = selected.begin(), e = selected.end(); + i != e; ++i) { + ids_map::const_iterator ii = ids.find(*i); + if (ii != ids.end()) { // line found + long int endId = ii->second.npoints * 2 - 1 + ii->second.startId; + for (long int id = ii->second.startId; id < endId; id++) { + dc_ids.push_back(id); + } + } + } + + return dc_ids; +} + +/** + \brief Set selected vector objects + + \param[in] list of GRASS ids to be set + + \return 1 +*/ +int DisplayDriver::SetSelected(std::vector id) +{ + selected = id; + + return 1; +} + +/** + \brief Get PseudoDC vertex id of selected line + + \param[in] x,y coordinates of click + + \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) +{ + struct lineDesc *desc; // line desription + + int line, type; + int Gid, DCid; + int vx, vy, vz; // vertex screen coordinates + + double dist, minDist; + + std::vector returnId; + + // only one object can be selected + if (selected.size() != 1) + return returnId; + + line = selected[0]; + + type = Vect_read_line (mapInfo, points, cats, line); + + // find the closest vertex (x, y) + 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); + + if (idx == 0) { + minDist = dist; + Gid = idx; + } + else { + if (minDist > dist) { + minDist = dist; + Gid = idx; + } + } + } + + desc = &(ids[line]); + + // translate id + DCid = Gid * 2 + desc->startId; + + // add selected vertex + returnId.push_back(DCid); + Cell2Pixel(points->x[Gid], points->y[Gid], points->z[Gid], + &vx, &vy, &vz); + wxRect rect (vx, vy, 0, 0); + dc->SetIdBounds(DCid, rect); + + // left vertex + if (DCid == desc->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 (vx, vy, 0, 0); + dc->SetIdBounds(DCid-2, rect); + } + + // right vertex + if (DCid == (desc->npoints - 1) * 2 + desc->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 (vx, vy, 0, 0); + dc->SetIdBounds(DCid + 2, rect); + } + + return returnId; +} Modified: trunk/grassaddons/gui/display_driver/driver.h =================================================================== --- trunk/grassaddons/gui/display_driver/driver.h 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/display_driver/driver.h 2007-09-25 07:48:05 UTC (rev 1102) @@ -121,8 +121,8 @@ /* select */ int SelectLinesByBox(double x1, double y1, double x2, double y2); - int SelectLinesByPoint(double x, double y, double thresh, - int onlyType); + std::vector SelectLineByPoint(double x, double y, double thresh, + int onlyType); void Unselect(); std::vector GetSelected(bool grassId); Modified: trunk/grassaddons/gui/display_driver/driver.i =================================================================== --- trunk/grassaddons/gui/display_driver/driver.i 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/display_driver/driver.i 2007-09-25 07:48:05 UTC (rev 1102) @@ -12,4 +12,5 @@ %include "std_vector.i" namespace std { %template(IntVector) vector; + %template(DoubleVector) vector; } Modified: trunk/grassaddons/gui/gui_modules/dbm.py =================================================================== --- trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/gui_modules/dbm.py 2007-09-25 07:48:05 UTC (rev 1102) @@ -677,6 +677,17 @@ table = self.mapInfo.layers[layer]["table"] columns = self.mapInfo.tables[table] # value + if len(columns["cat"][1]) == 0: # no cats + sizer = wx.BoxSizer(wx.VERTICAL) + txt = wx.StaticText(parent=panel, id=wx.ID_ANY, + label=_("No categories available.")) + sizer.Add(txt, proportion=1, + flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER | wx.EXPAND) + border.Add(item=sizer, proportion=1, + flag=wx.ALL | wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER, + border=10) + panel.SetSizer(border) + continue for idx in range(len(columns["cat"][1])): flexSizer = wx.FlexGridSizer (cols=4, hgap=3, vgap=3) flexSizer.AddGrowableCol(0) Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-25 07:48:05 UTC (rev 1102) @@ -483,20 +483,22 @@ return nselected - def SelectLinesByPoint(self, point, onlyType=None): - """Select vector features by coordinates of click point. + 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)""" - nselected = self.__display.SelectLinesByPoint(point[0], point[1], - float(self.parent.threshold), - -1); + pointOnLine = self.__display.SelectLineByPoint(point[0], point[1], + float(self.parent.threshold), + -1); - Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): selected=%d" % \ - nselected) - - return nselected - + if len(pointOnLine) > 0: + Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): pointOnLine=%s") + return pointOnLine + else: + Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): no line found") + return None + def GetSelected(self, grassId=True): """Return ids of selected vector features Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-25 06:44:49 UTC (rev 1101) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-25 07:48:05 UTC (rev 1102) @@ -822,11 +822,11 @@ posWindow = self.ClientToScreen((self.mouse['begin'][0] + offset, self.mouse['begin'][1] + offset)) - # set pen - self.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) - self.polypen = wx.Pen(colour='dark green', width=2, style=wx.SOLID) - if digitToolbar.action == "addLine": + # set pen + self.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) + self.polypen = wx.Pen(colour='dark green', width=2, style=wx.SOLID) + if digitToolbar.type in ["point", "centroid"]: # add new point self.parent.digit.AddPoint(map=map, @@ -847,7 +847,7 @@ addRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") for sql in addRecordDlg.GetSQLString(): - sqlfile.file.write(sql) + sqlfile.file.write(sql + ";\n") sqlfile.file.flush() executeCommand = cmd.Command(cmd=["db.execute", "--q", @@ -860,7 +860,8 @@ self.DrawLines() elif digitToolbar.action == "deleteLine": pass - elif digitToolbar.action in ["moveLine", "moveVertex"]: + elif digitToolbar.action in ["moveLine", "moveVertex"] and \ + not hasattr(self, "moveBegin"): self.moveBegin = [0, 0] self.moveCoords = self.mouse['begin'] self.moveIds = [] @@ -969,13 +970,14 @@ pos1 = self.Pixel2Cell(self.mouse['begin']) pos2 = self.Pixel2Cell(self.mouse['end']) - if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex"]: + if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex"] and \ + len(self.parent.digit.driver.GetSelected()) == 0: nselected = 0 driver = self.parent.digit.driver # -> delete line || move line || move vertex if digitToolbar.action == "moveVertex": # -> move vertex (select by point) - nselected = driver.SelectLinesByPoint(pos1, onlyType="line") + nselected = driver.SelectLineByPoint(pos1, onlyType="line") self.moveIds = driver.GetSelectedVertex(pos1) else: # -> moveLine || deleteLine (select by box) @@ -997,8 +999,13 @@ else: self.UpdateMap(render=False, renderVector=False) elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]: - self.parent.digit.driver.SelectLinesByPoint(pos1, onlyType="line") - self.UpdateMap(render=False) + pointOnLine = self.parent.digit.driver.SelectLineByPoint(pos1, + onlyType="line") + if pointOnLine: + self.UpdateMap(render=False) # highlight object + self.DrawCross(pdc=self.pdcVector, coords=self.Cell2Pixel(pointOnLine), + size=5) + elif self.dragid != None: # end drag of overlay decoration self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid) @@ -1131,7 +1138,8 @@ if addRecordDlg.mapInfo and \ addRecordDlg.ShowModal() == wx.ID_OK: sqlfile = tempfile.NamedTemporaryFile(mode="w") - sqlfile.file.write(addRecordDlg.GetSQLString()) + for sql in addRecordDlg.GetSQLString(): + sqlfile.file.write(sql + ";\n") sqlfile.file.flush() executeCommand = cmd.Command(cmd=["db.execute", "--q", @@ -1241,19 +1249,20 @@ # draw polyline self.pdcVector.TranslateId(self.moveIds[0], dx, dy) - #self.pdcVector.RemoveId(self.moveIds[0]) - #self.pdcVector.RemoveId(self.moveIds[-1]) - #self.pdcVector.RemoveId(self.moveIds[-2]) + # self.pdcVector.RemoveId(self.moveIds[0]) + # do not draw static lines self.polycoords = [] if self.moveIds[1] > 0: # left vertex x1, y1 = self.pdcVector.GetIdBounds(self.moveIds[1])[0:2] + self.pdcVector.RemoveId(self.moveIds[1]+1) self.polycoords.append((x1, y1)) x2, y2 = self.mouse['end'] self.polycoords.append((x2, y2)) if self.moveIds[2] > 0: # right line x3, y3 = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2] + self.pdcVector.RemoveId(self.moveIds[2]-1) self.polycoords.append((x3, y3)) - + self.ClearLines() self.DrawLines() From ullah at grass.itc.it Tue Sep 25 20:48:18 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Tue Sep 25 20:48:20 2007 Subject: [grass-addons] r1103 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709251848.l8PImIi8004120@grass.itc.it> Author: ullah Date: 2007-09-25 20:48:12 +0200 (Tue, 25 Sep 2007) New Revision: 1103 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: changed 99th percentile to 1st percentile in erosion stats output textfile Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-25 07:48:05 UTC (rev 1102) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-25 18:48:12 UTC (rev 1103) @@ -748,11 +748,11 @@ avesoil=`echo "$soilstats" | grep "mean=" | cut -d'=' -f2` nnthsoil=`echo "$soilstats" | grep "percentile_99=" | cut -d'=' -f2` - erosstats=`eval r.univar -g -e map=$tmperosion percentile=99` + erosstats=`eval r.univar -g -e map=$tmperosion percentile=1` maxeros=`echo "$erosstats" | grep "max=" | cut -d'=' -f2` mineros=`echo "$erosstats" | grep "min=" | cut -d'=' -f2` aveeros=`echo "$erosstats" | grep "mean=" | cut -d'=' -f2` - nntheros=`echo "$erosstats" | grep "percentile_99=" | cut -d'=' -f2` + nntheros=`echo "$erosstats" | grep "percentile_1=" | cut -d'=' -f2` depostats=`eval r.univar -g -e map=$tmpdep percentile=99` maxdepo=`echo "$depostats" | grep "max=" | cut -d'=' -f2` From landa at grass.itc.it Wed Sep 26 21:19:56 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Wed Sep 26 21:19:59 2007 Subject: [grass-addons] r1104 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709261919.l8QJJu5q020325@grass.itc.it> Author: landa Date: 2007-09-26 21:19:50 +0200 (Wed, 26 Sep 2007) New Revision: 1104 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: Copy Categories implemented. Modified: trunk/grassaddons/gui/display_driver/driver.cpp =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-25 18:48:12 UTC (rev 1103) +++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-26 19:19:50 UTC (rev 1104) @@ -99,22 +99,27 @@ //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); //Vect_build(mapInfo, stderr); + Vect_get_map_box(mapInfo, &mapBox); + // draw lines inside of current display region - /* nlines = Vect_select_lines_by_box(mapInfo, &(region.box), GV_POINTS | GV_LINES, // fixme listLines); - */ - Vect_get_map_box(mapInfo, &mapBox); + /* nlines = Vect_select_lines_by_box(mapInfo, &mapBox, GV_POINTS | GV_LINES, // fixme listLines); - + */ for (int i = 0; i < listLines->n_values; i++) { DrawLine(listLines->value[i]); } #ifdef DEBUG + std::cout.flags(std::ios_base::fixed); + std::cout << "region: W=" << mapBox.W + << "; E=" << mapBox.E + << "; S=" << mapBox.S + << "; N=" << mapBox.N << std::endl; std::cout << "region: W=" << region.box.W << "; E=" << region.box.E << "; S=" << region.box.S @@ -476,6 +481,8 @@ region.box.S = south; region.box.E = east; region.box.W = west; + region.box.T = PORT_DOUBLE_MAX; + region.box.B = -PORT_DOUBLE_MAX; region.ns_res = ns_res; region.ew_res = ew_res; @@ -658,7 +665,8 @@ \brief Select vector feature by given point in given threshold - Only one vector object can be selected. + Only one vector object can be selected. Bounding boxes of + all segments are stores. \param[in] x,y point of searching \param[in] thresh threshold value where to search @@ -677,8 +685,6 @@ line = Vect_find_line(mapInfo, x, y, 0.0, GV_POINTS | GV_LINES, thresh, 0, 0); - std::cout << x << " " << y << " " << thresh << "->" << line << std::endl; - if (line > 0) { selected.push_back(line); type = Vect_read_line (mapInfo, points, cats, line); @@ -687,6 +693,16 @@ NULL, NULL, NULL); p.push_back(px); p.push_back(py); + + // set bounding boxes for all segments + long int id = ids[line].startId; + int vx, vy, vz; + for (int i = 0; i < points->n_points; i++, id += 2) { + Cell2Pixel(points->x[i], points->y[i], points->z[i], + &vx, &vy, &vz); + wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); + dc->SetIdBounds(id, rect); + } } return p; @@ -826,7 +842,7 @@ returnId.push_back(DCid); Cell2Pixel(points->x[Gid], points->y[Gid], points->z[Gid], &vx, &vy, &vz); - wxRect rect (vx, vy, 0, 0); + wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); dc->SetIdBounds(DCid, rect); // left vertex @@ -837,7 +853,7 @@ returnId.push_back(DCid - 2); Cell2Pixel(points->x[Gid-1], points->y[Gid-1], points->z[Gid-1], &vx, &vy, &vz); - wxRect rect (vx, vy, 0, 0); + wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); dc->SetIdBounds(DCid-2, rect); } @@ -849,7 +865,7 @@ returnId.push_back(DCid + 2); Cell2Pixel(points->x[Gid+1], points->y[Gid+1], points->z[Gid+1], &vx, &vy, &vz); - wxRect rect (vx, vy, 0, 0); + wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); dc->SetIdBounds(DCid + 2, rect); } Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-25 18:48:12 UTC (rev 1103) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-26 19:19:50 UTC (rev 1104) @@ -371,7 +371,21 @@ self.driver.ReloadMap() return True - + + def CopyCats(self, cats, ids): + """Copy given categories to objects with id listed in ids""" + if len(cats) == 0 or len(ids) == 0: + return False + + # collect cats + cmd.Command(['v.edit', + '--q', + 'map=%s' % self.map, + 'tool=catadd', + 'cats=%s' % ",".join(["%d" % v for v in cats]), + 'ids=%s' % ",".join(["%d" % v for v in ids])]) + + return True class VDigit(AbstractDigit): """ Prototype of digitization class based on v.digit reimplementation @@ -493,10 +507,11 @@ -1); if len(pointOnLine) > 0: - Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): pointOnLine=%s") + Debug.msg(4, "CDisplayDriver.SelectLineByPoint(): pointOnLine=%f,%f" % \ + (pointOnLine[0], pointOnLine[1])) return pointOnLine else: - Debug.msg(4, "CDisplayDriver.SelectLinesByPoint(): no line found") + Debug.msg(4, "CDisplayDriver.SelectLineByPoint(): no line found") return None def GetSelected(self, grassId=True): Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-25 18:48:12 UTC (rev 1103) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-26 19:19:50 UTC (rev 1104) @@ -822,11 +822,12 @@ posWindow = self.ClientToScreen((self.mouse['begin'][0] + offset, self.mouse['begin'][1] + offset)) - if digitToolbar.action == "addLine": + if digitToolbar.action not in ["moveVertex", "addVertex", "removeVertex"]: # set pen self.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) self.polypen = wx.Pen(colour='dark green', width=2, style=wx.SOLID) - + + if digitToolbar.action == "addLine": if digitToolbar.type in ["point", "centroid"]: # add new point self.parent.digit.AddPoint(map=map, @@ -860,7 +861,7 @@ self.DrawLines() elif digitToolbar.action == "deleteLine": pass - elif digitToolbar.action in ["moveLine", "moveVertex"] and \ + elif digitToolbar.action in ["moveLine", "moveVertex", "editLine"] and \ not hasattr(self, "moveBegin"): self.moveBegin = [0, 0] self.moveCoords = self.mouse['begin'] @@ -904,7 +905,7 @@ queryCoords=(east, north), qdist=qdist, pos=posWindow, - title=_("Display categories")) + title=_("Update categories")) if categoryDlg.GetLine(): # highlight feature & re-draw map @@ -919,7 +920,12 @@ # PyDisplayDriver: Digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() self.UpdateMap(render=False) - + elif digitToolbar.action == "copyCats": + if not hasattr(self, "copyCatsList"): + self.copyCatsList = [] + else: + self.copyCatsIds = [] + self.mouse['box'] = 'box' else: # get decoration id self.lastpos = self.mouse['begin'] @@ -966,19 +972,48 @@ elif self.mouse["use"] == "pointer" and self.parent.digittoolbar: # digitization tool active digitToolbar = self.parent.digittoolbar + driver = self.parent.digit.driver self.mouse['end'] = event.GetPositionTuple()[:] pos1 = self.Pixel2Cell(self.mouse['begin']) pos2 = self.Pixel2Cell(self.mouse['end']) - if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex"] and \ - len(self.parent.digit.driver.GetSelected()) == 0: + if digitToolbar.action in ["deleteLine", "moveLine", "moveVertex", + "copyCats", "editLine"]: nselected = 0 - driver = self.parent.digit.driver # -> delete line || move line || move vertex - if digitToolbar.action == "moveVertex": - # -> move vertex (select by point) - nselected = driver.SelectLineByPoint(pos1, onlyType="line") - self.moveIds = driver.GetSelectedVertex(pos1) + if digitToolbar.action in ["moveVertex", "editLine"]: + if len(driver.GetSelected()) == 0: + # -> move vertex (select by point) + nselected = driver.SelectLineByPoint(pos1, onlyType="line") + ids = driver.GetSelected(grassId=False) + print "#", self.pdcVector.GetIdBounds(ids[-1]), self.pdcVector.GetIdBounds(ids[-3]) + self.moveIds.append(ids[-1]) # last vertex + self.moveIds.append(ids[-3]) # previous vertex + elif digitToolbar.action == "copyCats": + if not hasattr(self, "copyCatsIds"): + # collect categories + nselected = driver.SelectLineByPoint(pos1, onlyType="line") + if nselected: + qdist = 10.0 * ((self.Map.region['e'] - self.Map.region['w']) / \ + self.Map.width) + vWhat = cmd.Command(['v.what', + '--q', + 'map=%s' % self.parent.digit.map, + 'east_north=%f,%f' % \ + (float(pos1[0]), float(pos1[1])), + 'distance=%f' % qdist]) + + for line in vWhat.ReadStdOutput(): + if "Category:" in line: + cat = int(line.split(':')[1].strip()) + self.copyCatsList.append(cat) + else: + # collect ids + driver.Unselect() + nselected = driver.SelectLinesByBox(pos1, pos2) + if nselected > 0: + self.copyCatsIds = driver.GetSelected() + else: # -> moveLine || deleteLine (select by box) nselected = driver.SelectLinesByBox(pos1, pos2) @@ -986,26 +1021,39 @@ if nselected > 0: # highlight selected features self.UpdateMap(render=False) - if digitToolbar.action in ["moveLine", "moveVertex"]: + if digitToolbar.action in ["moveLine", "moveVertex", "copyCats"]: # -> 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) - else: + elif digitToolbar.action == "moveVertex": # -> move vertex self.moveIds = driver.GetSelectedVertex(pos1) else: self.UpdateMap(render=False, renderVector=False) elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]: - pointOnLine = self.parent.digit.driver.SelectLineByPoint(pos1, + pointOnLine = driver.SelectLineByPoint(pos1, onlyType="line") if pointOnLine: self.UpdateMap(render=False) # highlight object - self.DrawCross(pdc=self.pdcVector, coords=self.Cell2Pixel(pointOnLine), - size=5) - + if digitToolbar.action in ["splitLine", "addVertex"]: + self.DrawCross(pdc=self.pdcVector, coords=self.Cell2Pixel(pointOnLine), + size=5) + elif digitToolbar.action == "removeVertex": + # get only id of vertex + id = 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 == "editLine": + if len(self.moveIds) > 0: + #self.pdcVector.RemoveId(ids[-1]) + #self.pdcVector.RemoveId(ids[-2]) + self.UpdateMap(render=False, renderVector=False) + elif self.dragid != None: # end drag of overlay decoration self.ovlcoords[self.dragid] = self.pdc.GetIdBounds(self.dragid) @@ -1149,7 +1197,8 @@ elif digit.action == "deleteLine": # -> delete selected vector features self.parent.digit.DeleteSelectedLines() - elif digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): + elif digit.action in ["moveLine", "moveVertex", "editLine"] 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 @@ -1162,10 +1211,12 @@ if digit.action == "moveLine": # move line self.parent.digit.MoveSelectedLines(move) - else: + elif digit.action == "moveVertex": # move vertex self.parent.digit.MoveSelectedVertex(self.Pixel2Cell(self.moveCoords), move) + else: # edit line + pass del self.moveBegin del self.moveCoords @@ -1179,7 +1230,14 @@ elif digit.action == "removeVertex": # remove vertex self.parent.digit.RemoveVertex(self.Pixel2Cell(self.mouse['begin'])) - + elif digit.action == "copyCats": + try: + self.parent.digit.CopyCats(self.copyCatsList, + self.copyCatsIds) + del self.copyCatsList + del self.copyCatsIds + except: + pass if digit.action != "addLine": # PyDisplayDriver: self.parent.digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() @@ -1208,15 +1266,23 @@ self.UpdateMap(render=False) self.DrawLines() elif digit.action in ["deleteLine", "moveLine", "splitLine", - "addVertex", "removeVertex", "moveVertex"]: + "addVertex", "removeVertex", "moveVertex", + "copyCats"]: # varios tools -> unselected selected features # PyDisplayDriver: self.parent.digit.driver.SetSelect([]) self.parent.digit.driver.Unselect() - if digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): + if digit.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": + try: + del self.copyCatsList + del self.copyCatsIds + except: + pass self.UpdateMap(render=False) # render map def OnMouseMoving(self, event): @@ -1231,7 +1297,8 @@ if len(self.polycoords) > 0: # draw mouse moving self.MouseDraw() - elif digit.action in ["moveLine", "moveVertex"] and hasattr(self, "moveBegin"): + elif digit.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] self.moveBegin[0] += dx @@ -1242,26 +1309,32 @@ # move line for id in self.moveIds: self.pdcVector.TranslateId(id, dx, dy) - else: + elif digit.action in ["moveVertex", "editLine"]: # move vertex -> # (vertex, left vertex, left line, # right vertex, right line) - # draw polyline self.pdcVector.TranslateId(self.moveIds[0], dx, dy) # self.pdcVector.RemoveId(self.moveIds[0]) + self.polycoords = [] # do not draw static lines - self.polycoords = [] - if self.moveIds[1] > 0: # left vertex - x1, y1 = self.pdcVector.GetIdBounds(self.moveIds[1])[0:2] - self.pdcVector.RemoveId(self.moveIds[1]+1) - self.polycoords.append((x1, y1)) - x2, y2 = self.mouse['end'] - self.polycoords.append((x2, y2)) - if self.moveIds[2] > 0: # right line - x3, y3 = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2] - self.pdcVector.RemoveId(self.moveIds[2]-1) - self.polycoords.append((x3, y3)) + if digit.action == "moveVertex": + if self.moveIds[1] > 0: # left vertex + 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']) + if self.moveIds[2] > 0: # right vertex + x, y = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2] + self.pdcVector.RemoveId(self.moveIds[2]-1) + self.polycoords.append((x, y)) + else: # edit line + print "@", self.moveIds, self.pdcVector.GetIdBounds(self.moveIds[1])[0:2] + if self.moveIds[1] > 0: # left vertex + 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.ClearLines() self.DrawLines() Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-25 18:48:12 UTC (rev 1103) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-26 19:19:50 UTC (rev 1104) @@ -391,7 +391,9 @@ def OnEditLine(self, event): """Edit line""" - pass + Debug.msg(2, "Digittoolbar.OnEditLine():") + self.action="editLine" + self.parent.MapWindow.mouse['box'] = 'point' def OnMoveLine(self, event): """Move line""" @@ -419,7 +421,9 @@ def OnCopyCats(self, event): """Copy categories""" - pass + Debug.msg(2, "Digittoolbar.OnCopyCats():") + self.action="copyCats" + self.parent.MapWindow.mouse['box'] = 'point' def OnSettings(self, event): """Show settings dialog""" From ullah at grass.itc.it Wed Sep 26 22:20:42 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Wed Sep 26 22:20:44 2007 Subject: [grass-addons] r1105 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709262020.l8QKKgto020888@grass.itc.it> Author: ullah Date: 2007-09-26 22:20:36 +0200 (Wed, 26 Sep 2007) New Revision: 1105 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: changed error trap for huge spikes in r.terraflow version to be more sensitive to even small spikes. This is important because r.terraflow will error out if spikes get too big. Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-26 19:19:50 UTC (rev 1104) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-26 20:20:36 UTC (rev 1105) @@ -663,7 +663,7 @@ if [ "$GIS_FLAG_f" -eq 1 ]; then - r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, if(x > ($old_dem + 25), ($old_dem + 25), x))))" + r.mapcalc "$temp_dem=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($old_dem + $smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($old_dem + $smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($old_dem + $smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($old_dem + $smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($old_dem + $smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($old_dem + $smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($old_dem + $smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($old_dem + $smoothdz[1,1]), ($old_dem + $smoothdz))))))))), (if(isnull(x), $old_dem, if(x > ($old_dem + 5), ($old_dem + 1), x))))" else @@ -683,7 +683,7 @@ #make $netchange if asked if [ "$GIS_FLAG_n" -eq 1 -o "$GIS_FLAG_m" -eq 1 -o "$GIS_FLAG_t" -eq 1 -a "$GIS_FLAG_f" -eq 1 ]; then - r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, if(x > 25, 25, x))))" + r.mapcalc "$netchange=eval(x=if(($aspect < 22.5 || $aspect >= 337.5) && $aspect != 0, ($smoothdz[1,0]), if ($aspect >= 22.5 && $aspect < 67.5, ($smoothdz[1,-1]), if ($aspect >= 67.5 && $aspect < 112.5, ($smoothdz[0,-1]), if ($aspect >= 112.5 && $aspect < 157.5, ($smoothdz[-1,-1]), if ($aspect >= 157.5 && $aspect < 202.5, ($smoothdz[-1,0]), if ($aspect >= 202.5 && $aspect < 247.5, ($smoothdz[-1,1]), if ($aspect >= 247.5 && $aspect < 292.5, ($smoothdz[0,1]), if ($aspect >= 292.5 && $aspect < 337.5, ($smoothdz[1,1]), ($smoothdz))))))))), (if(isnull(x), $smoothdz, if(x > 5, 1, x))))" #set colors for maps r.colors --quiet map=$netchange rules=$TMP1 From landa at grass.itc.it Thu Sep 27 12:50:19 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Thu Sep 27 12:50:21 2007 Subject: [grass-addons] r1106 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709271050.l8RAoJwh031691@grass.itc.it> Author: landa Date: 2007-09-27 12:50:18 +0200 (Thu, 27 Sep 2007) New Revision: 1106 Modified: trunk/grassaddons/gui/display_driver/driver.cpp trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Digitization tool: Edit line implemented, Copy cats fixed. Functionality of v.digit almost implemented. Display driver needs optimalization. Modified: trunk/grassaddons/gui/display_driver/driver.cpp =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-26 20:20:36 UTC (rev 1105) +++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-27 10:50:18 UTC (rev 1106) @@ -693,16 +693,6 @@ NULL, NULL, NULL); p.push_back(px); p.push_back(py); - - // set bounding boxes for all segments - long int id = ids[line].startId; - int vx, vy, vz; - for (int i = 0; i < points->n_points; i++, id += 2) { - Cell2Pixel(points->x[i], points->y[i], points->z[i], - &vx, &vy, &vz); - wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); - dc->SetIdBounds(id, rect); - } } return p; @@ -757,14 +747,29 @@ return selected; std::vector dc_ids; - + long int line; for(std::vector::const_iterator i = selected.begin(), e = selected.end(); i != e; ++i) { - ids_map::const_iterator ii = ids.find(*i); + line = *i; + ids_map::const_iterator ii = ids.find(line); if (ii != ids.end()) { // line found long int endId = ii->second.npoints * 2 - 1 + ii->second.startId; - for (long int id = ii->second.startId; id < endId; id++) { + int type, i; + int vx, vy, vz; + type = Vect_read_line (mapInfo, points, cats, line); + i = 0; + for (long int id = ii->second.startId; id < endId; id++) { dc_ids.push_back(id); + // set bounding boxes for all selected objects (only nodes) + if (id % 2) { + Cell2Pixel(points->x[i], points->y[i], points->z[i], + &vx, &vy, &vz); + wxRect rect (wxPoint (vx, vy), wxPoint (vx, vy)); + dc->SetIdBounds(id, rect); + + i++; + } + } } } Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-26 20:20:36 UTC (rev 1105) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-27 10:50:18 UTC (rev 1106) @@ -386,6 +386,19 @@ 'ids=%s' % ",".join(["%d" % v for v in ids])]) return True + + def EditLine(self, line, coords): + """Edit existing line""" + # remove line + vEditDelete = cmd.Command(['v.edit', + '--q', + 'map=%s' % self.map, + 'tool=delete', + 'ids=%s' % line]) + + # add line + self.AddLine(self.map, "line", coords) + class VDigit(AbstractDigit): """ Prototype of digitization class based on v.digit reimplementation Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-26 20:20:36 UTC (rev 1105) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-27 10:50:18 UTC (rev 1106) @@ -822,7 +822,8 @@ posWindow = self.ClientToScreen((self.mouse['begin'][0] + offset, self.mouse['begin'][1] + offset)) - if digitToolbar.action not in ["moveVertex", "addVertex", "removeVertex"]: + if digitToolbar.action not in ["moveVertex", "addVertex", + "removeVertex", "editLine"]: # set pen self.pen = wx.Pen(colour='Red', width=2, style=wx.SHORT_DASH) self.polypen = wx.Pen(colour='dark green', width=2, style=wx.SOLID) @@ -859,14 +860,27 @@ self.polycoords.append(event.GetPositionTuple()[:]) self.mouse['begin'] = self.polycoords[-1] self.DrawLines() + + elif digitToolbar.action == "editLine" and hasattr(self, "moveIds"): + coords=self.polycoords[-2:] + idLine = wx.NewId() + self.pdcVector.SetId(idLine) + self.pdcVector.DrawLine(coords[0][0], coords[0][1], + coords[1][0], coords[1][1]) + idNode = wx.NewId() + self.pdcVector.SetIdBounds(idNode, (coords[1][0], coords[1][1], + coords[1][0], coords[1][1])) + self.moveIds.insert(-1, idNode) + elif digitToolbar.action == "deleteLine": pass + elif digitToolbar.action in ["moveLine", "moveVertex", "editLine"] and \ not hasattr(self, "moveBegin"): self.moveBegin = [0, 0] self.moveCoords = self.mouse['begin'] self.moveIds = [] - if digitToolbar.action == "moveVertex": + if digitToolbar.action in ["moveVertex", "editLine"]: # set pen self.polypen = wx.Pen(colour=self.parent.digit.settings["symbolHighlight"][1], width=2, style=wx.SHORT_DASH) @@ -985,10 +999,7 @@ if len(driver.GetSelected()) == 0: # -> move vertex (select by point) nselected = driver.SelectLineByPoint(pos1, onlyType="line") - ids = driver.GetSelected(grassId=False) - print "#", self.pdcVector.GetIdBounds(ids[-1]), self.pdcVector.GetIdBounds(ids[-3]) - self.moveIds.append(ids[-1]) # last vertex - self.moveIds.append(ids[-3]) # previous vertex + elif digitToolbar.action == "copyCats": if not hasattr(self, "copyCatsIds"): # collect categories @@ -1021,7 +1032,8 @@ if nselected > 0: # highlight selected features self.UpdateMap(render=False) - if digitToolbar.action in ["moveLine", "moveVertex", "copyCats"]: + 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 @@ -1031,6 +1043,13 @@ 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) + else: self.UpdateMap(render=False, renderVector=False) elif digitToolbar.action in ["splitLine", "addVertex", "removeVertex"]: @@ -1048,11 +1067,6 @@ self.pdcVector.RemoveId(id) self.DrawCross(pdc=self.pdcVector, coords=(x, y), size=5) - elif digitToolbar.action == "editLine": - if len(self.moveIds) > 0: - #self.pdcVector.RemoveId(ids[-1]) - #self.pdcVector.RemoveId(ids[-2]) - self.UpdateMap(render=False, renderVector=False) elif self.dragid != None: # end drag of overlay decoration @@ -1197,7 +1211,7 @@ elif digit.action == "deleteLine": # -> delete selected vector features self.parent.digit.DeleteSelectedLines() - elif digit.action in ["moveLine", "moveVertex", "editLine"] and \ + elif digit.action in ["moveLine", "moveVertex"] and \ hasattr(self, "moveBegin"): # move vector feature move = [self.Distance((0,0), (self.moveBegin[0], 0))[0], @@ -1238,6 +1252,17 @@ del self.copyCatsIds except: pass + elif digit.action == "editLine" and hasattr(self, "moveBegin"): + line = self.parent.digit.driver.GetSelected() + coords = [] + for id in self.moveIds[0:-1]: + 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 + if digit.action != "addLine": # PyDisplayDriver: self.parent.digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() @@ -1250,8 +1275,8 @@ digit = self.parent.digittoolbar # digitization tool if self.mouse["use"] == "pointer" and digit: - if digit.action == "addLine" and \ - digit.type in ["line", "boundary"]: + if (digit.action == "addLine" and digit.type in ["line", "boundary"]) or \ + digit.action == "editLine": # add line or boundary -> remove last point from the line try: removed = self.polycoords.pop() @@ -1262,8 +1287,14 @@ except: pass + if digit.action == "editLine" and len(self.moveIds) > 0: + # remove last vertex & line + self.pdcVector.RemoveId(self.moveIds[-1]) + self.moveIds.pop() + self.pdcVector.RemoveId(self.moveIds[-1] -1) + self.ClearLines() - self.UpdateMap(render=False) + self.UpdateMap(render=False, renderVector=False) self.DrawLines() elif digit.action in ["deleteLine", "moveLine", "splitLine", "addVertex", "removeVertex", "moveVertex", @@ -1314,27 +1345,32 @@ # (vertex, left vertex, left line, # right vertex, right line) - self.pdcVector.TranslateId(self.moveIds[0], dx, dy) # self.pdcVector.RemoveId(self.moveIds[0]) + # do not draw static lines self.polycoords = [] - # do not draw static lines if digit.action == "moveVertex": - if self.moveIds[1] > 0: # left vertex + 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] self.pdcVector.RemoveId(self.moveIds[1]+1) self.polycoords.append((x, y)) self.polycoords.append(self.mouse['end']) - if self.moveIds[2] > 0: # right vertex + if self.moveIds[2] > 0: # next vertex x, y = self.pdcVector.GetIdBounds(self.moveIds[2])[0:2] self.pdcVector.RemoveId(self.moveIds[2]-1) self.polycoords.append((x, y)) else: # edit line - print "@", self.moveIds, self.pdcVector.GetIdBounds(self.moveIds[1])[0:2] - if self.moveIds[1] > 0: # left vertex - 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.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[-2] > 0: # previous vertex + x, y = self.pdcVector.GetIdBounds(self.moveIds[-2])[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() From ullah at grass.itc.it Thu Sep 27 21:38:04 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Sep 27 21:38:06 2007 Subject: [grass-addons] r1107 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709271938.l8RJc4CP004882@grass.itc.it> Author: ullah Date: 2007-09-27 21:37:58 +0200 (Thu, 27 Sep 2007) New Revision: 1107 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: added two options for naming and formtting statsout text file, especially useful if the script is being controlled and iterated by an external program. Also fixed minor but important bug in the RUSLE portion of the equation. Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-27 10:50:18 UTC (rev 1106) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-27 19:37:58 UTC (rev 1107) @@ -75,7 +75,19 @@ #% required: no #% guisection: Input #%end +#% key: statsout +#% type: string +#% gisprompt: string +#% description: Name for the statsout text file (optional, if none provided, a default name will be used) +#% required: no +#% guisection: Input +#%end #%flag +#% key: g +#% description: -g do not put header on statsout text file and always append data, even if file already exists (useful if script is being run by an outside program) +#% guisection: Input +#%end +#%flag #% key: l #% description: -l Do not output maps of soil depths #% guisection: Input @@ -598,7 +610,7 @@ #if the old soil is 0 or negative(could happen i suppose) then we make k-factor really really small to simulate erosion on bedrock r.mapcalc "$qsx=if ($old_soil <= 0, ($R * 0.001 * $C * $sflowtopo * cos($aspect)), ($R * $K * $C * $sflowtopo * cos($aspect)))" - r.mapcalc "$qsy=if ($old_soil <= 0, ($R * 0.001 * $C * $sflowtopo * cos($aspect)), ($R * $K * $C * $sflowtopo * sin($aspect)))" + r.mapcalc "$qsy=if ($old_soil <= 0, ($R * 0.001 * $C * $sflowtopo * sin($aspect)), ($R * $K * $C * $sflowtopo * sin($aspect)))" echo "" echo "*************************" @@ -762,19 +774,31 @@ g.remove --quiet rast=$tmperosion,$tmpdep - mapset=`eval g.gisenv get=MAPSET` - txtout=$mapset"_"$prefx"_lsevol_stats.txt" - + if [ -e $GIS_OPT_statsout ]; then + + txtout=$GIS_OPT_statsout + + else + + mapset=`eval g.gisenv get=MAPSET` + txtout=$mapset"_"$prefx"_lsevol_stats.txt" + + fi + echo "outputing stats to textfile: $txtout" + if [ $GIS_FLAG_g -eq 1 ]; then + + if [ $iter -eq 1 ]; then + echo "Stats for erosion and deposition simulation with starting map: $elev" > $txtout + echo "" >> $txtout + echo "Year,,Mean Erosion,Max Erosion,Min Erosion,99th Percentile Erosion,,Mean Deposition,Min Deposition,Max Deposition,99th Percentile Deposition,,Mean Soil Depth,Min Soil Depth,Max Soil Depth,99th Percentile Soil Depth" >> $txtout + fi + + echo "$iter,,$aveeros,$mineros,$maxeros,$nntheros,,$avedepo,$mindepo,$maxdepo,$nnthdepo,,$avesoil,$minsoil,$maxsoil,$nnthsoil" >> $txtout + else + echo "$iter,,$aveeros,$mineros,$maxeros,$nntheros,,$avedepo,$mindepo,$maxdepo,$nnthdepo,,$avesoil,$minsoil,$maxsoil,$nnthsoil" >> $txtout - if [ $iter -eq 1 ]; then - echo "Stats for erosion and deposition simulation with starting map: $elev" > $txtout - echo "" >> $txtout - echo "Year,,Mean Erosion,Max Erosion,Min Erosion,99th Percentile Erosion,,Mean Deposition,Min Deposition,Max Deposition,99th Percentile Deposition,,Mean Soil Depth,Min Soil Depth,Max Soil Depth,99th Percentile Soil Depth" >> $txtout fi - - echo "$iter,,$aveeros,$mineros,$maxeros,$nntheros,,$avedepo,$mindepo,$maxdepo,$nnthdepo,,$avesoil,$minsoil,$maxsoil,$nnthsoil" >> $txtout - echo "" echo "*************************" echo "Done with this iteration" From ullah at grass.itc.it Thu Sep 27 21:42:52 2007 From: ullah at grass.itc.it (ullah@grass.itc.it) Date: Thu Sep 27 21:42:53 2007 Subject: [grass-addons] r1108 - trunk/grassaddons/LandDyn/r.landscape.evol Message-ID: <200709271942.l8RJgq96004903@grass.itc.it> Author: ullah Date: 2007-09-27 21:42:46 +0200 (Thu, 27 Sep 2007) New Revision: 1108 Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol Log: minor bugfix Modified: trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol =================================================================== --- trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-27 19:37:58 UTC (rev 1107) +++ trunk/grassaddons/LandDyn/r.landscape.evol/r.landscape.evol 2007-09-27 19:42:46 UTC (rev 1108) @@ -75,6 +75,7 @@ #% required: no #% guisection: Input #%end +#%Option #% key: statsout #% type: string #% gisprompt: string From landa at grass.itc.it Fri Sep 28 09:56:00 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Sep 28 09:56:02 2007 Subject: [grass-addons] r1109 - in trunk/grassaddons/gui: display_driver gui_modules Message-ID: <200709280756.l8S7u0lM019318@grass.itc.it> Author: landa Date: 2007-09-28 09:55:59 +0200 (Fri, 28 Sep 2007) New Revision: 1109 Modified: trunk/grassaddons/gui/display_driver/Makefile trunk/grassaddons/gui/display_driver/driver.cpp trunk/grassaddons/gui/display_driver/driver.h trunk/grassaddons/gui/gui_modules/digit.py Log: Minor changes in display driver. Need to speed up! (to use floatcanvas?) Modified: trunk/grassaddons/gui/display_driver/Makefile =================================================================== --- trunk/grassaddons/gui/display_driver/Makefile 2007-09-27 19:42:46 UTC (rev 1108) +++ trunk/grassaddons/gui/display_driver/Makefile 2007-09-28 07:55:59 UTC (rev 1109) @@ -27,7 +27,7 @@ grass6_wxdriver_wrap.o: grass6_wxdriver_wrap.cxx $(CXX) $(CFLAGS) $(INCLUDE_DIRS) $< -driver.o: driver.cpp +driver.o: driver.cpp driver.h $(CXX) $(CFLAGS) $(INCLUDE_DIRS) $< pseudodc.o: pseudodc.cpp Modified: trunk/grassaddons/gui/display_driver/driver.cpp =================================================================== --- trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-27 19:42:46 UTC (rev 1108) +++ trunk/grassaddons/gui/display_driver/driver.cpp 2007-09-28 07:55:59 UTC (rev 1109) @@ -39,6 +39,7 @@ pointsScreen = new wxList(); cats = Vect_new_cats_struct(); + topology.recorded = true; } /** @@ -80,7 +81,7 @@ \return number of lines which were drawn \return -1 on error */ -int DisplayDriver::DrawMap() +int DisplayDriver::DrawMap(bool force) { if (!mapInfo || !dc) return -1; @@ -94,6 +95,10 @@ ids.clear(); listLines = Vect_new_list(); + if (force) { + ResetTopology(); + } + /* nlines = Vect_get_num_lines(mapInfo); */ //Vect_build_partial(mapInfo, GV_BUILD_NONE, stderr); @@ -109,36 +114,39 @@ nlines = Vect_select_lines_by_box(mapInfo, &mapBox, GV_POINTS | GV_LINES, // fixme listLines); - */ + for (int i = 0; i < listLines->n_values; i++) { DrawLine(listLines->value[i]); } + */ #ifdef DEBUG - std::cout.flags(std::ios_base::fixed); - std::cout << "region: W=" << mapBox.W - << "; E=" << mapBox.E - << "; S=" << mapBox.S - << "; N=" << mapBox.N << std::endl; - std::cout << "region: W=" << region.box.W + std::cerr.flags(std::ios_base::fixed); + std::cerr << "region: W=" << region.box.W << "; E=" << region.box.E << "; S=" << region.box.S << "; N=" << region.box.N << std::endl; - std::cout << "-> nlines=" << nlines << std::endl; + std::cerr << "-> nlines=" << nlines << std::endl; #endif - /* - nlines = Vect_get_num_lines(mapInfo); - for (int line = 1; line <= nlines; line++) { - DrawLine(line); + 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); } - */ #ifdef DEBUG PrintIds(); #endif + if (force) { + topology.recorded = true; + } + Vect_destroy_list(listLines); return listLines->n_values; @@ -148,11 +156,11 @@ \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) +int DisplayDriver::DrawLine(int line, bool inBox) { if (!dc || !Vect_line_alive (mapInfo, line)) return -1; @@ -164,14 +172,6 @@ // read line type = Vect_read_line (mapInfo, points, cats, line); - // clear screen points & convert EN -> xy - pointsScreen->Clear(); - for (int i = 0; i < points->n_points; i++) { - Cell2Pixel(points->x[i], points->y[i], points->z[i], - &x, &y, &z); - pointsScreen->Append((wxObject*) new wxPoint(x, y)); /* TODO: 3D */ - } - // add ids // -> node1, line1, vertex1, line2, ..., node2 struct lineDesc desc = {points->n_points, dcId}; @@ -179,16 +179,16 @@ // update id for next line dcId += points->n_points * 2 - 1; - // determine color of vector object - if (IsSelected(line)) { + if (IsSelected(line)) { // line selected ? dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); draw = true; } - else { + else if (!topology.recorded) { // determine color of vector object if (type & GV_LINES) { switch (type) { case GV_LINE: dc->SetPen(wxPen(settings.line.color, settings.lineWidth, wxSOLID)); + topology.line.push_back(line); draw = settings.line.enabled; break; case GV_BOUNDARY: @@ -197,14 +197,17 @@ &left, &right); if (left == 0 && right == 0) { dc->SetPen(wxPen(settings.boundaryNo.color, settings.lineWidth, wxSOLID)); + topology.boundaryNo.push_back(line); draw = settings.boundaryNo.enabled; } else if (left > 0 && right > 0) { dc->SetPen(wxPen(settings.boundaryTwo.color, settings.lineWidth, wxSOLID)); + topology.boundaryTwo.push_back(line); draw = settings.boundaryTwo.enabled; } else { dc->SetPen(wxPen(settings.boundaryOne.color, settings.lineWidth, wxSOLID)); + topology.boundaryOne.push_back(line); draw = settings.boundaryOne.enabled; } break; @@ -216,28 +219,40 @@ else if (type & GV_POINTS) { if (type == GV_POINT && settings.point.enabled) { dc->SetPen(wxPen(settings.point.color, settings.lineWidth, wxSOLID)); - draw = true; + topology.point.push_back(line); + 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); } else if (cret == 0) { draw = settings.centroidOut.enabled; dc->SetPen(wxPen(settings.centroidOut.color, settings.lineWidth, wxSOLID)); + topology.centroidOut.push_back(line); } else { draw = settings.centroidDup.enabled; dc->SetPen(wxPen(settings.centroidDup.color, settings.lineWidth, wxSOLID)); + topology.centroidDup.push_back(line); } } } } // draw object - if (draw) { + if (inBox && draw) { + // clear screen points & convert EN -> xy + pointsScreen->Clear(); + for (int i = 0; i < points->n_points; i++) { + Cell2Pixel(points->x[i], points->y[i], points->z[i], + &x, &y, &z); + pointsScreen->Append((wxObject*) new wxPoint(x, y)); /* TODO: 3D */ + } + if (type & GV_POINTS) { DrawCross(line, (const wxPoint *) pointsScreen->GetFirst()->GetData()); } @@ -286,6 +301,7 @@ // determine color if (!IsSelected(line)) { dc->SetPen(wxPen(settings.vertex.color, settings.lineWidth, wxSOLID)); + topology.vertex.push_back(line); } else { dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); @@ -343,13 +359,15 @@ dc->SetPen(wxPen(settings.highlight, settings.lineWidth, wxSOLID)); draw = true; } - else { + else if (!topology.recorded) { if (Vect_get_node_n_lines(mapInfo, node) == 1) { dc->SetPen(wxPen(settings.nodeOne.color, settings.lineWidth, wxSOLID)); + topology.nodeOne.push_back(line); draw = settings.nodeOne.enabled; } else { dc->SetPen(wxPen(settings.nodeTwo.color, settings.lineWidth, wxSOLID)); + topology.nodeTwo.push_back(line); draw = settings.nodeTwo.enabled; } } @@ -595,16 +613,46 @@ { for (ids_map::const_iterator i = ids.begin(), e = ids.end(); i != e; ++i) { - std::cout << "line=" << i->first << ": " + 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.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.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.nodeOne: " << topology.nodeOne.size() << std::endl; + std::cerr << "topology.nodeTwo: " << topology.nodeTwo.size() << std::endl; + + std::cerr << "topology.vertex: " << topology.vertex.size() << 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; + for (std::vector::const_iterator i = selected.begin(), e = selected.end(); i != e; ++i) - std::cout << "selected: " << *i << " "; - std::cout << std::endl; + std::cerr << "selected: " << *i << " "; + std::cerr << std::endl; return; } @@ -876,3 +924,31 @@ return returnId; } + +/** + \brief Reset topology structure. + + \return +*/ +void DisplayDriver::ResetTopology() +{ + topology.recorded = false; + + topology.point.clear(); + topology.line.clear(); + + topology.boundaryNo.clear(); + topology.boundaryOne.clear(); + topology.boundaryTwo.clear(); + + topology.centroidIn.clear(); + topology.centroidOut.clear(); + topology.centroidDup.clear(); + + topology.nodeOne.clear(); + topology.nodeTwo.clear(); + + topology.vertex.clear(); + + return; +} Modified: trunk/grassaddons/gui/display_driver/driver.h =================================================================== --- trunk/grassaddons/gui/display_driver/driver.h 2007-09-27 19:42:46 UTC (rev 1108) +++ trunk/grassaddons/gui/display_driver/driver.h 2007-09-28 07:55:59 UTC (rev 1109) @@ -27,7 +27,7 @@ #include } -//#define DEBUG +#define DEBUG class DisplayDriver { @@ -95,12 +95,32 @@ } settings; + struct _topology { + std::vector point; + std::vector line; + + std::vector boundaryNo; + std::vector boundaryOne; + std::vector boundaryTwo; + + std::vector centroidIn; + std::vector centroidOut; + std::vector centroidDup; + + std::vector nodeOne; + std::vector nodeTwo; + + std::vector vertex; + + bool recorded; // topology already recorded + } topology; + void Cell2Pixel (double east, double north, double depth, int *x, int *y, int *z); int DrawCross(int line, const wxPoint *point, int size=5); - int DrawLine(int line); + int DrawLine(int line, bool inBox); int DrawLineVerteces(int line); int DrawLineNodes(int line); @@ -110,6 +130,8 @@ /* select feature */ bool IsSelected(int line); + void ResetTopology(); + public: /* constructor */ DisplayDriver(void *device); @@ -117,7 +139,7 @@ ~DisplayDriver(); /* display */ - int DrawMap(); + int DrawMap(bool force); /* select */ int SelectLinesByBox(double x1, double y1, double x2, double y2); Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-27 19:42:46 UTC (rev 1108) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-28 07:55:59 UTC (rev 1109) @@ -488,12 +488,13 @@ """ import time start = time.clock() - nlines = self.__display.DrawMap() + nlines = self.__display.DrawMap(True) # force stop = time.clock() Debug.msg(3, "CDisplayDriver.DrawMap(): nlines=%d, sec=%f" % \ (nlines, stop-start)) return nlines + def SelectLinesByBox(self, begin, end, onlyType=None): """Select vector features by given bounding box. From landa at grass.itc.it Fri Sep 28 10:06:42 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Sep 28 10:06:43 2007 Subject: [grass-addons] r1110 - trunk/grassaddons/gui/gui_modules Message-ID: <200709280806.l8S86gsS020049@grass.itc.it> Author: landa Date: 2007-09-28 10:06:42 +0200 (Fri, 28 Sep 2007) New Revision: 1110 Modified: trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/mapdisp.py Log: Remove dead PyDisplayDriver (replaced by CDisplayDriver) class. Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-28 07:55:59 UTC (rev 1109) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-28 08:06:42 UTC (rev 1110) @@ -6,7 +6,6 @@ * VEdit * VDigit * AbstractDisplayDriver - * PyDisplayDriver * CDisplayDriver * DigitSettingsDialog * DigitCategoryDialog @@ -44,27 +43,13 @@ import dbm from debug import Debug as Debug -usePyDisplayDriver = False - -if usePyDisplayDriver: - try: - # replace with the path to the GRASS SWIG-Python interface - g6libPath = "/hardmnt/schiele0/ssi/landa/src/grass6/swig/python" - # g6libPath = "/usr/src/gis/grass6/swig/python" - sys.path.append(g6libPath) - import python_grass6 as g6lib - except: - print >> sys.stderr, "For running digitization tool you need to enable GRASS SWIG-Python interface.\n" \ - "This only TEMPORARY solution (display driver based on SWIG-Python interface is EXTREMELY SLOW!\n" \ - "Will be replaced by C/C++ display driver." -else: - try: - driverPath = os.path.join( os.getenv("GISBASE"), "etc","wx", "display_driver") - sys.path.append(driverPath) - from grass6_wxdriver import DisplayDriver - except: - print >> sys.stderr, "Digitization tool is disabled.\n" \ - "Under development..." +try: + driverPath = os.path.join( os.getenv("GISBASE"), "etc","wx", "display_driver") + sys.path.append(driverPath) + from grass6_wxdriver import DisplayDriver +except: + print >> sys.stderr, "Digitization tool is disabled.\n" \ + "Under development..." class AbstractDigit: """ @@ -111,10 +96,7 @@ else: self.settings = settings - if usePyDisplayDriver: - self.driver = PyDisplayDriver(self, mapwindow) - else: - self.driver = CDisplayDriver(self, mapwindow) + self.driver = CDisplayDriver(self, mapwindow) self.threshold = self.driver.GetThreshold() @@ -656,330 +638,6 @@ 255).GetRGB(), settings['lineWidth'][0]) - -class PyDisplayDriver(AbstractDisplayDriver): - """ - Experimental display driver implemented in Python using - GRASS-Python SWIG interface - - Note: This will be in the future rewritten in C/C++ - """ - def __init__(self, parent, mapwindow): - AbstractDisplayDriver.__init__(self, parent, mapwindow) - self.mapInfo = None - - def __del__(self): - if self.points: - g6lib.Vect_destroy_line_struct(self.points) - if self.cats: - g6lib.Vect_destroy_cats_struct(self.cats) - - def Reset(self, map): - g6lib.G_gisinit('') - - if map == None: - if self.mapInfo: - g6lib.Vect_close(self.mapInfo) - - self.mapInfo = None - return - - name, mapset = map.split('@') - - Debug.msg(4, "DisplayDriver.__init__(): name=%s, mapset=%s" % \ - (name, mapset)) - - # define map structure - self.mapInfo = g6lib.Map_info() - # define open level (level 2: topology) - g6lib.Vect_set_open_level(2) - - # open existing map - # python 2.5 (unicode) -> str() - g6lib.Vect_open_old(self.mapInfo, str(name), str(mapset)) - - # auxilary structures - self.points = g6lib.Vect_new_line_struct(); - self.cats = g6lib.Vect_new_cats_struct(); - - def GetSelectedVertex(self, coords): - """Return PseudoDC id(s) of vertex (of selected line) - on position 'coords'""" - - selectedId = [] - - try: - line = self.selected[0] - except: - return selectedId - - idx = 0 - - type = g6lib.Vect_read_line (self.mapInfo, self.points, self.cats, line) - - npoints = self.points.n_points - - for idx in range(npoints): - x = g6lib.doubleArray_getitem(self.points.x, idx) - y = g6lib.doubleArray_getitem(self.points.y, idx) - z = g6lib.doubleArray_getitem(self.points.z, idx) - - dist = g6lib.Vect_points_distance(coords[0], coords[1], 0, - x, y, z, 0) - - if idx == 0: - minDist = dist - minIdx = idx - else: - if minDist > dist: - minDist = dist - minIdx = idx - - # [line, vertex1, ..., node1, node2] - if minIdx == 0: - selectedId.append(self.ids[line][-2]) - elif minIdx == npoints - 1: - selectedId.append(self.ids[line][-1]) - else: - selectedId.append(self.ids[line][minIdx]) - - return selectedId - - def SelectLinesByBox(self, rect, onlyType=None): - """Select vector features by given bounding box. - - rect = ((x1, y1), (x2, y2)) - Number of selected features can be decreased by 'onlyType' - ('None' for no types) - """ - - type = 0 - if not onlyType: - type = -1 # all types (see include/vect/dig_defines.h) - elif onlyType == "line": - type = g6lib.GV_LINES - elif onlyType == "point": - type = g6lib.GV_POINTS - - list = g6lib.Vect_new_list() - bbox = g6lib.Vect_new_line_struct() - - x1, y1 = rect[0] - x2, y2 = rect[1] - dx = abs(x2 - x1) - dy = abs(y2 - y1) - - g6lib.Vect_append_point(bbox, x1, y1, 0) - g6lib.Vect_append_point(bbox, x2, y1, 0) - g6lib.Vect_append_point(bbox, x2, y2, 0) - g6lib.Vect_append_point(bbox, x1, y2, 0) - g6lib.Vect_append_point(bbox, x1, y1, 0) - - g6lib.Vect_select_lines_by_polygon(self.mapInfo, bbox, - 0, None, - type, list) - - for idx in range(list.n_values): - line = g6lib.intArray_getitem(list.value, idx) - if line not in self.selected: - self.selected.append(line) - - Debug.msg(4, "DisplayDriver.SelectLinesByBox(%s): n=%d, ids=%s" % \ - (rect, list.n_values, self.selected)) - - g6lib.Vect_destroy_line_struct(bbox) - g6lib.Vect_destroy_list(list) - - return self.selected - - def SelectLinesByPoint(self, point, onlyType=""): - """Select vector features by the box given by its center and thresh (size/2) - Number of selected features can be decreased by 'onlyType' - ('None' for all types)""" - - type = 0 - if not onlyType: - type = -1 # all types (see include/vect/dig_defines.h) - elif onlyType == "line": - type = g6lib.GV_LINES - elif onlyType == "point": - type = g6lib.GV_POINTS - - - line = g6lib.Vect_find_line(self.mapInfo, point[0], point[1], 0, - type, self.parent.threshold, 0, 0) - - self.selected = [] - if line > 0: - self.selected.append(line) - - return self.selected - - def ReDrawMap(self, map): - """Reopen map and draw its content in PseudoDC""" - # close map - if self.mapInfo: - g6lib.Vect_close(self.mapInfo) - - # re-open map - name, mapset = map.split('@') - g6lib.Vect_open_old(self.mapInfo, str(name), str(mapset)) - - self.DrawMap() - - def DrawMap(self): - """Display content of the map in PseudoDC""" - if not self.mapInfo: - return - nlines = g6lib.Vect_get_num_lines(self.mapInfo) - Debug.msg(4, "PyDisplayDriver.DrawMap(): nlines=%d" % nlines) - - for line in range(1, nlines + 1): - self.DisplayLine(line) - - return nlines - - def DisplayLine(self, line): - """Display line (defined by id) in PseudoDC""" - Debug.msg(4, "DisplayDriver.DisplayLine(): line=%d" % line) - - if not g6lib.Vect_line_alive (self.mapInfo, line): - return - - type = g6lib.Vect_read_line (self.mapInfo, self.points, self.cats, line) - - Debug.msg (4, "DisplayDriver.DisplayLine(): line=%d type=%d" % \ - (line, type)) - - # add id - self.ids[line] = [] - self.DisplayPoints(line, type, self.points) - - def DisplayNodes(self, line): - """Display nodes of the given line""" - Debug.msg(4, "DisplayDriver.DisplayNodes(): line=%d" % line) - - n1 = g6lib.new_intp() - n2 = g6lib.new_intp() - x = g6lib.new_doublep() - y = g6lib.new_doublep() - z = g6lib.new_doublep() - - nodes = [n1, n2] - g6lib.Vect_get_line_nodes(self.mapInfo, line, n1, n2) - - for nodep in nodes: - node = g6lib.intp_value(nodep) - g6lib.Vect_get_node_coor(self.mapInfo, node, - x, y, z) - coords = (self.mapwindow.Cell2Pixel(g6lib.doublep_value(x), - g6lib.doublep_value(y))) - - if g6lib.Vect_get_node_n_lines(self.mapInfo, node) == 1: - self.SetPen(line, "symbolNodeOne") # one line - else: - self.SetPen(line, "symbolNodeTwo") # two lines - - self.ids[line].append(self.mapwindow.DrawCross(coords, size=5)) - - g6lib.delete_doublep(x) - g6lib.delete_doublep(y) - g6lib.delete_doublep(z) - g6lib.delete_intp(n1) - g6lib.delete_intp(n2) - - def DisplayPoints(self, line, type, points): - """Draw points in PseudoDC""" - - coords = [] - npoints = points.n_points - Debug.msg(4, "DisplayDriver.DisplayPoints() npoints=%d" % npoints); - - for idx in range(npoints): - x = g6lib.doubleArray_getitem(self.points.x, idx) - y = g6lib.doubleArray_getitem(self.points.y, idx) - z = g6lib.doubleArray_getitem(self.points.z, idx) - coords.append(self.mapwindow.Cell2Pixel(x, y)) - - if len(coords) > 1: # -> line - # draw line - if type == g6lib.GV_BOUNDARY: - leftp = g6lib.new_intp() - rightp = g6lib.new_intp() - g6lib.Vect_get_line_areas(self.mapInfo, line, - leftp, rightp) - left, right = g6lib.intp_value(leftp), g6lib.intp_value(rightp) - if left == 0 and right == 0: - self.SetPen(line, "symbolBoundaryNo") - elif left > 0 and right > 0: - self.SetPen(line, "symbolBoundaryTwo") - else: - self.SetPen(line, "symbolBoundaryOne") - g6lib.delete_intp(leftp) - g6lib.delete_intp(rightp) - else: # GV_LINE - self.SetPen(line, "symbolLine") - self.ids[line].append(self.mapwindow.DrawLines(coords)) - # draw verteces - self.SetPen(line, "symbolVertex") - for idx in range(1, npoints-1): - self.ids[line].append(self.mapwindow.DrawCross(coords[idx], size=4)) - # draw nodes - self.DisplayNodes(line) - else: - if type == g6lib.GV_CENTROID: - cret = g6lib.Vect_get_centroid_area(self.mapInfo, line) - if cret > 0: # -> area - self.SetPen(line, "symbolCentroidIn") - elif cret == 0: - self.SetPen(line, "symbolCentroidOut") - else: - self.SetPen(line, "symbolCentroidDup") - else: - self.SetPen(line, "symbolPoint") - self.ids[line].append(self.mapwindow.DrawCross(coords[0], size=5)) - - def SetPen(self, line, symbol): - """Set Pen for PseudoDC according vector feature status""" - - if line in self.selected: - symbol = "symbolHighlight" - - width = self.parent.settings["lineWidth"][0] - - if self.parent.settings[symbol][0] in [True, None]: - self.mapwindow.pen = self.mapwindow.polypen = wx.Pen(colour=self.parent.settings[symbol][1], - width=width, style=wx.SOLID) - else: - self.mapwindow.pen = self.mapwindow.polypen = None - - def SetSelected(self, pdcId): - """Set selected objects (their ids) in PseudoDC - - For deseleids=[] - """ - # reset - self.selected = [] - - for line in pdcId: - self.selected.append(line) - - Debug.msg(4, "DisplayDriver.SetSelected(): pdcId=%s, grassId=%s" % \ - (pdcId, self.selected)) - - def GetSelected(self, grassId=True): - """Get ids of selected objects in PseudoDC - - If grassId=True return GRASS line id otherwise PseudoDC id""" - if grassId: - return self.selected - else: - pdcId = [] - for line in self.selected: - for id in self.ids[line]: - pdcId.append(id) - return pdcId - class DigitSettingsDialog(wx.Dialog): """ Standard settings dialog for digitization purposes @@ -1286,8 +944,7 @@ pass # update driver settings - if not usePyDisplayDriver: - self.parent.digit.driver.UpdateSettings() + self.parent.digit.driver.UpdateSettings() # redraw map if auto-rendering is enabled if self.parent.autoRender.GetValue(): Modified: trunk/grassaddons/gui/gui_modules/mapdisp.py =================================================================== --- trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-28 07:55:59 UTC (rev 1109) +++ trunk/grassaddons/gui/gui_modules/mapdisp.py 2007-09-28 08:06:42 UTC (rev 1110) @@ -931,7 +931,6 @@ pass # unselect & re-draw if redraw: - # PyDisplayDriver: Digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() self.UpdateMap(render=False) elif digitToolbar.action == "copyCats": @@ -1264,7 +1263,6 @@ del self.moveIds if digit.action != "addLine": - # PyDisplayDriver: self.parent.digit.driver.SetSelected([]) self.parent.digit.driver.Unselect() self.UpdateMap(render=False) @@ -1300,7 +1298,6 @@ "addVertex", "removeVertex", "moveVertex", "copyCats"]: # varios tools -> unselected selected features - # PyDisplayDriver: self.parent.digit.driver.SetSelect([]) self.parent.digit.driver.Unselect() if digit.action in ["moveLine", "moveVertex", "editLine"] and \ hasattr(self, "moveBegin"): From landa at grass.itc.it Fri Sep 28 20:14:06 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Fri Sep 28 20:14:07 2007 Subject: [grass-addons] r1111 - in trunk/grassaddons/gui: . gui_modules Message-ID: <200709281814.l8SIE6ww000554@grass.itc.it> Author: landa Date: 2007-09-28 20:14:02 +0200 (Fri, 28 Sep 2007) New Revision: 1111 Modified: trunk/grassaddons/gui/gui_modules/menudata.py trunk/grassaddons/gui/wxgui.py Log: About GRASS dialog added. Modified: trunk/grassaddons/gui/gui_modules/menudata.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menudata.py 2007-09-28 08:06:42 UTC (rev 1110) +++ trunk/grassaddons/gui/gui_modules/menudata.py 2007-09-28 18:14:02 UTC (rev 1111) @@ -334,7 +334,7 @@ ("Linear regression", "Linear regression between 2 maps", "self.OnMenuCmd", "r.regression.line"), ("Mutual category occurrences", "Mutual category occurrences (coincidence)", "self.OnMenuCmd", "r.coin"), )), - ("","","", "") +# ("","","", "") )), ("Vector", ( ("Develop map", ( @@ -437,7 +437,7 @@ ("Quadrat indices", "Indices of point counts in quadrats", "self.OnMenuCmd", "v.qcount"), ("Test normality", "Test normality of point distribution", "self.OnMenuCmd", "v.normal"), )), - ("","","", "") +# ("","","", "") )), ("Imagery", ( ("Develop images and groups", ( @@ -488,7 +488,7 @@ ("Kappa analysis", "Kappa classification accuracy assessment", "self.OnMenuCmd", "r.kappa"), ("OIF for LandSat TM", "Optimum index factor for LandSat TM", "self.OnMenuCmd", "i.oif"), )), - ("","","", "") +# ("","","", "") )), ("Volumes", ( ("Develop grid3D volumes", ( @@ -504,7 +504,7 @@ ("Report and Statistics", ( ("Basic volume information", "Report basic information about grid3D volume", "self.OnMenuCmd", "r3.info"), )), - ("","","", "") +# ("","","", "") )), ("Database", ( ("Database information", ( @@ -539,12 +539,12 @@ ("Reconnect vector to database", "Reconnect vector map to attribute database", "self.OnMenuCmd", "v.db.reconnect.all"), ("Set vector - database connection", "Set database connection for vector attributes", "self.OnMenuCmd", "v.db.connect"), )), - ("","","", "") +# ("","","", "") )), ("Help", ( ("GRASS help", "GRASS help", "self.RunMenuCmd", ['g.manual', '-i']), ("GIS Manager help", "GIS Manager help", "self.RunMenuCmd", ['g.manual', 'gis.m']), - ("About GRASS (not functional)", "About GRASS", "self.OnMenuCmd", ""), - ("About system (not functional)", "About system", "self.OnMenuCmd", ""), - ("","","", "") + ("About GRASS", "About GRASS", "self.OnAboutGRASS", ""), +# ("About system (not functional)", "About system", "self.OnMenuCmd", ""), +# ("","","", "") )))] Modified: trunk/grassaddons/gui/wxgui.py =================================================================== --- trunk/grassaddons/gui/wxgui.py 2007-09-28 08:06:42 UTC (rev 1110) +++ trunk/grassaddons/gui/wxgui.py 2007-09-28 18:14:02 UTC (rev 1111) @@ -13,7 +13,7 @@ command console. AUTHORS: The GRASS Development Team - Michael Barton (Arizona State University) & + Michael Barton (Arizona State University) Jachym Cepicky (Mendel University of Agriculture) Martin Landa @@ -37,6 +37,7 @@ import wx.stc import wx.lib.customtreectrl as CT import wx.lib.flatnotebook as FN +from wx.lib.wordwrap import wordwrap try: import subprocess except: @@ -317,7 +318,7 @@ # run g.mapsets with string of accessible mapsets cmdlist = ['g.mapsets', 'mapset=%s' % ms_string] - cmd.Command(cmdlist) + gcmd.Command(cmdlist) def OnRDigit(self, event): """ @@ -375,6 +376,34 @@ global gmpath menuform.GUI().ParseCommand(cmd, parentframe=self) + def OnAboutGRASS(self, event): + """Display 'About GRASS' dialog""" + info = wx.AboutDialogInfo() + # name + info.SetName("GRASS GIS") + # version + versionCmd = gcmd.Command(['g.version']) + info.SetVersion(versionCmd.ReadStdOutput()[0].replace('GRASS', '').strip()) + # description + copyrightFile = open(os.path.join(os.getenv("GISBASE"), "COPYING"), 'r') + copyrightOut = [] + copyright = copyrightFile.readlines() + info.SetCopyright(wordwrap(''.join(copyright[:11] + copyright[26:-3]), + 550, wx.ClientDC(self))) + copyrightFile.close() + # website + info.SetWebSite(("http://grass.itc.it", "The official GRASS site")) + # licence + licenceFile = open(os.path.join(os.getenv("GISBASE"), "GPL.TXT"), 'r') + info.SetLicence(''.join(licenceFile.readlines())) + licenceFile.close() + # credits + authorsFile = open(os.path.join(os.getenv("GISBASE"), "AUTHORS"), 'r') + info.SetDevelopers([''.join(authorsFile.readlines())]) + authorsFile.close() + + wx.AboutBox(info) + def RulesCmd(self, event): """ Launches dialog for commands that need rules @@ -398,7 +427,7 @@ cmdlist.append('--verbose') - cmd.Command(cmdlist) + gcmd.Command(cmdlist) dlg.Destroy() @@ -417,7 +446,7 @@ # make list of xmons that are not running cmdlist = ['d.mon', '-L'] - p = cmd.Command(cmdlist) + p = gcmd.Command(cmdlist) output = p.module_stdout.read().split('\n') for outline in output: outline = outline.strip() @@ -435,7 +464,7 @@ cmdlist = ['cmd.exe', '/c', 'start', os.path.join(gisbase,'etc','grass-run.bat'), command] else: cmdlist = [os.path.join(gisbase,'etc','grass-xterm-wrapper'), '-name', 'xterm-grass', '-e', os.path.join(gisbase,'etc','grass-run.sh'), command] - cmd.Command(cmdlist) + gcmd.Command(cmdlist) # reset display mode os.environ['GRASS_RENDER_IMMEDIATE'] = 'TRUE' @@ -837,19 +866,19 @@ wx.Dialog.__init__(self, parent, id, title, pos, size, style) cmdlist = ['g.mapsets', '-l'] - self.all_mapsets = cmd.Command(cmdlist).module_stdout.read().strip().split(' ') + self.all_mapsets = gcmd.Command(cmdlist).module_stdout.read().strip().split(' ') for mset in self.all_mapsets: indx = self.all_mapsets.index(mset) self.all_mapsets[indx] = mset.strip('\n') cmdlist = ['g.mapsets', '-p'] - self.accessible_mapsets = cmd.Command(cmdlist).module_stdout.read().strip().split(' ') + self.accessible_mapsets = gcmd.Command(cmdlist).module_stdout.read().strip().split(' ') for mset in self.accessible_mapsets: indx = self.accessible_mapsets.index(mset) self.accessible_mapsets[indx] = mset.strip('\n') cmdlist = ['g.gisenv', 'get=MAPSET'] - self.curr_mapset = cmd.Command(cmdlist).module_stdout.read().strip() + self.curr_mapset = gcmd.Command(cmdlist).module_stdout.read().strip() # remove PERMANENT and current mapset from list because they are always accessible From landa at grass.itc.it Sat Sep 29 22:56:50 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sat Sep 29 22:56:52 2007 Subject: [grass-addons] r1112 - in trunk/grassaddons/gui: gui_modules images Message-ID: <200709292056.l8TKuoO1032126@grass.itc.it> Author: landa Date: 2007-09-29 22:56:46 +0200 (Sat, 29 Sep 2007) New Revision: 1112 Modified: trunk/grassaddons/gui/gui_modules/menuform.py trunk/grassaddons/gui/images/grass-tiny-logo.png Log: Wrap text description of module. Cosmetics in layout. Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-28 18:14:02 UTC (rev 1111) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 20:56:46 UTC (rev 1112) @@ -52,7 +52,6 @@ import re import string import textwrap -import select import wx.lib.flatnotebook as FN import wx.lib.colourselect as csel import wx.lib.filebrowsebutton as filebrowse @@ -69,7 +68,6 @@ import gettext gettext.install("wxgrass") - gisbase = os.getenv("GISBASE") if gisbase is None: print >>sys.stderr, "We don't seem to be properly installed, or we are being run outside GRASS. Expect glitches." @@ -82,12 +80,12 @@ imagepath = os.path.join(wxbase,"images") sys.path.append(imagepath) +import select try: import subprocess except: from compat import subprocess - def reexec_with_pythonw(): if sys.platform == 'darwin' and\ not sys.executable.endswith('MacOS/Python'): @@ -100,9 +98,9 @@ VSPACE = 4 HSPACE = 4 -MENU_HEIGHT = 30 +MENU_HEIGHT = 25 STATUSBAR_HEIGHT = 30 -ENTRY_HEIGHT = 20 +ENTRY_HEIGHT = 25 STRING_ENTRY_WIDTH = 300 BUTTON_HEIGHT = 44 BUTTON_WIDTH = 100 @@ -495,7 +493,7 @@ # statusbar self.CreateStatusBar() # icon - self.SetIcon(wx.Icon(os.path.join(imagepath, 'grass.form.gif'), wx.BITMAP_TYPE_ANY)) + self.SetIcon(wx.Icon(os.path.join(imagepath, 'grass.form.gif'), wx.BITMAP_TYPE_GIF)) # menu # menu = wx.Menu() @@ -522,13 +520,14 @@ # logo+description topsizer = wx.BoxSizer(wx.HORIZONTAL) + # GRASS logo - self.logo = wx.StaticBitmap (parent=self, bitmap=wx.Bitmap(name=os.path.join(imagepath, 'grass-tiny-logo.png'), type=wx.BITMAP_TYPE_ANY)) - topsizer.Add (item=self.logo, proportion=0, border=1, flag=wx.ALL) - # module description - self.description = wx.StaticText (parent=self, label=self.task.description) - topsizer.Add (item=self.description, proportion=0, border=5, flag=wx.ALL) - guisizer.Add (item=topsizer, proportion=0, flag=wx.ALIGN_BOTTOM) + self.logo = wx.StaticBitmap(parent=self, + bitmap=wx.Bitmap(name=os.path.join(imagepath, + 'grass-tiny-logo.png'), + type=wx.BITMAP_TYPE_PNG)) + topsizer.Add (item=self.logo, proportion=0, border=3, flag=wx.ALL) + guisizer.Add (item=topsizer, proportion=0, flag=wx.ALIGN_BOTTOM | wx.EXPAND) # notebooks self.notebookpanel = cmdPanel (parent=self, task=self.task, standalone=standalone) @@ -585,6 +584,11 @@ 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, + flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) + guisizer.SetSizeHints(self) self.SetAutoLayout(True) self.SetSizer(guisizer) @@ -686,7 +690,6 @@ """Create command string (python list)""" return self.notebookpanel.createCmd(ignoreErrors=ignoreErrors) - class cmdPanel(wx.Panel): """ A panel containing a notebook dividing in tabs the different guisections of the GRASS cmd. @@ -865,7 +868,8 @@ if p.get('type','string') == 'string' and p.get('gisprompt',False) == True: txt = wx.StaticText(parent=which_panel, label = title + ':') - which_sizer.Add(item=txt, proportion=0, flag=wx.ADJUST_MINSIZE | wx.TOP | wx.LEFT, border=5) + which_sizer.Add(item=txt, proportion=0, + flag=wx.ADJUST_MINSIZE | wx.TOP | wx.LEFT, border=5) # element selection tree combobox (maps, icons, regions, etc.) if p.get('prompt','') != 'color' and p.get('element', '') != 'file': selection = select.Select(parent=which_panel, id=wx.ID_ANY, size=(300,-1), @@ -915,14 +919,19 @@ p['wxId'].append(None) # file selector elif p.get('prompt','') != 'color' and p.get('element', '') == 'file': - fbb = filebrowse.FileBrowseButton(parent=which_panel, id=wx.ID_ANY, size=(350, -1), labelText='', - dialogTitle=_( 'Choose %s' ) % p.get('description',_('File')), buttonText=_( 'Browse' ), + fbb = filebrowse.FileBrowseButton(parent=which_panel, id=wx.ID_ANY, + size=(350, -1), labelText='', + dialogTitle=_( 'Choose %s' ) % \ + p.get('description',_('File')), + buttonText=_( 'Browse' ), startDirectory=os.getcwd(), fileMode=0, changeCallback=self.OnSetValue) if p.get('value','') != '': fbb.SetValue(p['value']) # parameter previously set - which_sizer.Add(item=fbb, proportion=0, flag=wx.ADJUST_MINSIZE| wx.BOTTOM | wx.LEFT, border=5) - # A file browse button is a combobox with two children: a textctl and a button; + which_sizer.Add(item=fbb, proportion=0, + flag=wx.ADJUST_MINSIZE | wx.LEFT | wx.TOP, border=-3) + # A file browse button is a combobox with two children: + # a textctl and a button; # we have to target the button here p['wxId'] = fbb.GetChildren()[1].GetId() @@ -1121,6 +1130,33 @@ self.mf.MakeModal(modal) +class StaticWrapText(wx.StaticText): + """ + A Static Text field that wraps its text to fit its width, enlarging its height if necessary. + """ + def __init__(self, parent, id=wx.ID_ANY, label=u'', *args, **kwds): + self.originalLabel = label + wx.StaticText.__init__(self, parent, id, u'', *args, **kwds) + self.SetLabel(label) + self.Bind(wx.EVT_SIZE, self.onResize) + + def SetLabel(self, label): + self.originalLabel = label + self.wrappedSize = None + #self.onResize(None) + + def onResize(self, event): + if not getattr(self, "resizing", False): + self.resizing = True + newSize = self.GetSize() + if self.wrappedSize != newSize: + wx.StaticText.SetLabel(self, self.originalLabel) + self.Wrap(newSize.width) + self.wrappedSize = self.GetMinSize() + + self.SetSize(self.wrappedSize) + del self.resizing + if __name__ == "__main__": if len(sys.argv) == 1: @@ -1218,3 +1254,4 @@ } ] GrassGUIApp( task ).MainLoop() + Modified: trunk/grassaddons/gui/images/grass-tiny-logo.png =================================================================== (Binary files differ) From landa at grass.itc.it Sat Sep 29 22:59:30 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sat Sep 29 22:59:31 2007 Subject: [grass-addons] r1113 - trunk/grassaddons/gui/gui_modules Message-ID: <200709292059.l8TKxU8u032156@grass.itc.it> Author: landa Date: 2007-09-29 22:59:25 +0200 (Sat, 29 Sep 2007) New Revision: 1113 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: Also center vertically the GRASS logo. Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 20:56:46 UTC (rev 1112) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 20:59:25 UTC (rev 1113) @@ -526,7 +526,8 @@ bitmap=wx.Bitmap(name=os.path.join(imagepath, 'grass-tiny-logo.png'), type=wx.BITMAP_TYPE_PNG)) - topsizer.Add (item=self.logo, proportion=0, border=3, flag=wx.ALL) + topsizer.Add (item=self.logo, proportion=0, border=3, + flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL) guisizer.Add (item=topsizer, proportion=0, flag=wx.ALIGN_BOTTOM | wx.EXPAND) # notebooks From landa at grass.itc.it Sun Sep 30 00:28:01 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 30 00:28:02 2007 Subject: [grass-addons] r1114 - trunk/grassaddons/gui/gui_modules Message-ID: <200709292228.l8TMS1K4032270@grass.itc.it> Author: landa Date: 2007-09-30 00:27:58 +0200 (Sun, 30 Sep 2007) New Revision: 1114 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: helpPanel: set absolute patch also for img Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 20:59:25 UTC (rev 1113) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 22:27:58 UTC (rev 1114) @@ -417,46 +417,62 @@ The SYNOPSIS section is skipped, since this Panel is supposed to be integrated into the cmdPanel and options are obvious there. """ - def __init__(self, grass_command = "index", text = None, skip_description=False, *args, **kwargs): - """ - If grass_command is given, the corresponding HTML help file will be presented, with all links - pointing to absolute paths of local files. + def __init__(self, grass_command = "index", text = None, + skip_description=False, *args, **kwargs): + """ If grass_command is given, the corresponding HTML help file will + be presented, with all links pointing to absolute paths of + local files. - If 'skip_description' is True, the HTML corresponding to SYNOPSIS will be skipped, thus only - presenting the help file from the DESCRIPTION section onwards. + If 'skip_description' is True, the HTML corresponding to + SYNOPSIS will be skipped, thus only presenting the help file + from the DESCRIPTION section onwards. If 'text' is given, it must be the HTML text to be presented in the Panel. """ wx.html.HtmlWindow.__init__(self, *args, **kwargs) self.fspath = gisbase + "/docs/html/" self.SetStandardFonts ( size = 10 ) + self.SetBorders(10) + wx.InitAllImageHandlers() + if text is None: - self.fillContentsFromFile ( self.fspath + grass_command + ".html", skip_description=skip_description ) + self.fillContentsFromFile ( self.fspath + grass_command + ".html", + skip_description=skip_description ) else: self.SetPage( text ) self.Ok = True def fillContentsFromFile( self, htmlFile, skip_description=True ): aLink = re.compile( r'()', re.IGNORECASE ) + imgLink = re.compile( r'(' % self.fspath ] + # contents = [ '' % self.fspath ] + contents = [] skip = False for l in file( htmlFile, "rb" ).readlines(): - if "DESCRIPTION" in l: skip = False + if "DESCRIPTION" in l: + skip = False if not skip: - if "SYNOPSIS" in l: skip = skip_description # do skip the options description if requested + # do skip the options description if requested + if "SYNOPSIS" in l: + skip = skip_description else: - findLink = aLink.search( l ) - if findLink is not None: # change URLs to file paths - contents.append( aLink.sub(findLink.group(1)+self.fspath+findLink.group(2),l) ) - else: + findALink = aLink.search( l ) + if findALink is not None: + contents.append( aLink.sub(findALink.group(1)+ + self.fspath+findALink.group(2),l) ) + findImgLink = imgLink.search( l ) + if findImgLink is not None: + contents.append( imgLink.sub(findImgLink.group(1)+ + self.fspath+findImgLink.group(2),l) ) + + if findALink is None and findImgLink is None: contents.append( l ) self.SetPage( "".join( contents ) ) self.Ok = True except: # The Manual file was not found self.Ok = False - class mainFrame(wx.Frame): """ This is the Frame containing the dialog for options input. From landa at grass.itc.it Sun Sep 30 00:36:34 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 30 00:36:35 2007 Subject: [grass-addons] r1115 - trunk/grassaddons/gui/gui_modules Message-ID: <200709292236.l8TMaY7f032296@grass.itc.it> Author: landa Date: 2007-09-30 00:36:31 +0200 (Sun, 30 Sep 2007) New Revision: 1115 Modified: trunk/grassaddons/gui/gui_modules/menuform.py Log: helpPanel: use LoadPage if skip_description=False Modified: trunk/grassaddons/gui/gui_modules/menuform.py =================================================================== --- trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 22:27:58 UTC (rev 1114) +++ trunk/grassaddons/gui/gui_modules/menuform.py 2007-09-29 22:36:31 UTC (rev 1115) @@ -436,8 +436,12 @@ wx.InitAllImageHandlers() if text is None: - self.fillContentsFromFile ( self.fspath + grass_command + ".html", - skip_description=skip_description ) + if skip_description: + self.fillContentsFromFile ( self.fspath + grass_command + ".html", + skip_description=skip_description ) + else: + self.LoadPage(self.fspath + grass_command + ".html") + self.Ok = True else: self.SetPage( text ) self.Ok = True @@ -457,10 +461,11 @@ if "SYNOPSIS" in l: skip = skip_description else: + # FIXME: find only first item findALink = aLink.search( l ) if findALink is not None: contents.append( aLink.sub(findALink.group(1)+ - self.fspath+findALink.group(2),l) ) + self.fspath+findALink.group(2),l) ) findImgLink = imgLink.search( l ) if findImgLink is not None: contents.append( imgLink.sub(findImgLink.group(1)+ @@ -469,6 +474,7 @@ 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 From landa at grass.itc.it Sun Sep 30 22:20:02 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 30 22:20:03 2007 Subject: [grass-addons] r1116 - trunk/grassaddons/gui/icons/silk Message-ID: <200709302020.l8UKK2O1004135@grass.itc.it> Author: landa Date: 2007-09-30 22:18:26 +0200 (Sun, 30 Sep 2007) New Revision: 1116 Added: trunk/grassaddons/gui/icons/silk/application_view_icons.png trunk/grassaddons/gui/icons/silk/arrow_inout.png trunk/grassaddons/gui/icons/silk/bullet_go.png trunk/grassaddons/gui/icons/silk/chart_line.png trunk/grassaddons/gui/icons/silk/chart_line_add.png trunk/grassaddons/gui/icons/silk/chart_line_delete.png trunk/grassaddons/gui/icons/silk/chart_line_edit.png trunk/grassaddons/gui/icons/silk/chart_line_link.png trunk/grassaddons/gui/icons/silk/chart_organisation.png trunk/grassaddons/gui/icons/silk/chart_organisation_add.png trunk/grassaddons/gui/icons/silk/color_swatch.png trunk/grassaddons/gui/icons/silk/page_green.png trunk/grassaddons/gui/icons/silk/page_white_picture.png trunk/grassaddons/gui/icons/silk/picture_empty.png trunk/grassaddons/gui/icons/silk/shape_handles.png trunk/grassaddons/gui/icons/silk/sum.png trunk/grassaddons/gui/icons/silk/table.png trunk/grassaddons/gui/icons/silk/tag_blue_add.png trunk/grassaddons/gui/icons/silk/textfield_add.png trunk/grassaddons/gui/icons/silk/vector_delete.png trunk/grassaddons/gui/icons/silk/wand.png Modified: trunk/grassaddons/gui/icons/silk/__init__.py Log: Add new silk icons Modified: trunk/grassaddons/gui/icons/silk/__init__.py =================================================================== --- trunk/grassaddons/gui/icons/silk/__init__.py 2007-09-29 22:36:31 UTC (rev 1115) +++ trunk/grassaddons/gui/icons/silk/__init__.py 2007-09-30 20:18:26 UTC (rev 1116) @@ -12,30 +12,61 @@ "rendermap" : 'arrow_refresh.png', "erase" : 'cross.png', "pointer" : 'cursor.png', + "query" : 'information.png', + "savefile" : 'picture_save.png', + "printmap" : 'printer.png', + "pan" : 'mouse.png', # should be changed, not nice icon + # zoom (mapdisplay) "zoom_in" : 'zoom_in.png', "zoom_out" : 'zoom_out.png', "zoom_back" : 'zoom_back.png', "zoommenu" : 'zoom.png', - "query" : 'information.png', - "savefile" : 'picture_save.png', - "printmap" : 'printer.png', - "dec" : 'overlays.png', - "pan" : 'mouse.png', # should be changed, not nice icon + # analyze raster (mapdisplay) + "analyze" : 'application_lightning.png', + "measure" : 'sum.png', + "profile" : 'wand.png', + "histogram" : 'chart_bar.png', + # overlay (mapdisplay) + "overlay" : 'overlays.png', + "addtext" : 'textfield_add.png', + "addbarscale": 'page_white_picture.png', + "addlegend" : 'page_green.png', # digit - "digaddpoint": 'bullet_add.png', - "digaddline" : 'vector_add.png', - "digaddbound": 'plugin_add.png', - "digaddcentr": 'shape_square_add.png', - "digexit" : 'door_in.png', + ## add feature + "digAddPoint": 'bullet_add.png', + "digAddLine" : 'vector_add.png', + "digAddBoundary": 'shape_handles.png', + "digAddCentroid": 'shape_square_add.png', + ## vertex + "digAddVertex" : 'chart_line_add.png', + "digMoveVertex" : 'chart_line.png', + "digRemoveVertex" : 'chart_line_delete.png', + "digSplitLine" : 'chart_line_link.png', + ## edit feature + "digEditLine" : 'chart_line_edit.png', + "digMoveLine" : 'bullet_go.png', + "digDeleteLine" : 'vector_delete.png', + ## cats + "digDispCats" : 'chart_organisation.png', + "digCopyCats" : 'chart_organisation_add.png', + ## attributes + "digDispAttr" : 'table.png', + ## general + "digSettings" : 'color_swatch.png', + "digExit" : 'door_in.png', # gis manager "newdisplay" : 'application_add.png', "addrast" : 'image_add.png', + "addshaded" : 'picture_empty.png', + "addrarrow" : 'arrow_inout.png', "addvect" : 'map_add.png', "addcmd" : 'cog_add.png', "addgrp" : 'folder_add.png', "addovl" : 'images.png', + "addgrid" : 'application_view_icons.png', + "addlabels" : 'tag_blue_add.png', "delcmd" : 'cross.png', - "attrtable" : 'application_view_columns.png', + "attrtable" : 'application_view_columns.png', "addrgb" : 'rgb.png', "addhis" : 'his.png', "addthematic": 'thematic.png', Added: trunk/grassaddons/gui/icons/silk/application_view_icons.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/application_view_icons.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/arrow_inout.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/arrow_inout.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/bullet_go.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/bullet_go.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_line.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_line.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_line_add.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_line_add.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_line_delete.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_line_delete.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_line_edit.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_line_edit.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_line_link.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_line_link.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_organisation.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_organisation.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/chart_organisation_add.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/chart_organisation_add.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/color_swatch.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/color_swatch.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/page_green.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/page_green.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/page_white_picture.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/page_white_picture.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/picture_empty.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/picture_empty.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/shape_handles.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/shape_handles.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/sum.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/sum.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/table.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/table.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/tag_blue_add.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/tag_blue_add.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/textfield_add.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/textfield_add.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/vector_delete.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/vector_delete.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: trunk/grassaddons/gui/icons/silk/wand.png =================================================================== (Binary files differ) Property changes on: trunk/grassaddons/gui/icons/silk/wand.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream From landa at grass.itc.it Sun Sep 30 22:24:10 2007 From: landa at grass.itc.it (landa@grass.itc.it) Date: Sun Sep 30 22:24:12 2007 Subject: [grass-addons] r1117 - in trunk/grassaddons/gui: . gui_modules icons Message-ID: <200709302024.l8UKOA6F004158@grass.itc.it> Author: landa Date: 2007-09-30 22:23:45 +0200 (Sun, 30 Sep 2007) New Revision: 1117 Modified: trunk/grassaddons/gui/README trunk/grassaddons/gui/gui_modules/digit.py trunk/grassaddons/gui/gui_modules/toolbars.py trunk/grassaddons/gui/icons/icon.py Log: Cosmetics (various minor fixes). Modified: trunk/grassaddons/gui/README =================================================================== --- trunk/grassaddons/gui/README 2007-09-30 20:18:26 UTC (rev 1116) +++ trunk/grassaddons/gui/README 2007-09-30 20:23:45 UTC (rev 1117) @@ -143,3 +143,7 @@ To enable 'Silk' icon theme set environment variable: $ export GRASS_ICONPATH=$GISBASE/etc/wx/icons/silk + +To re-enable default icons (TCL/TK theme) + +$ unset GRASS_ICONPATH Modified: trunk/grassaddons/gui/gui_modules/digit.py =================================================================== --- trunk/grassaddons/gui/gui_modules/digit.py 2007-09-30 20:18:26 UTC (rev 1116) +++ trunk/grassaddons/gui/gui_modules/digit.py 2007-09-30 20:23:45 UTC (rev 1117) @@ -42,14 +42,14 @@ import gcmd as cmd import dbm from debug import Debug as Debug - +import select try: driverPath = os.path.join( os.getenv("GISBASE"), "etc","wx", "display_driver") sys.path.append(driverPath) from grass6_wxdriver import DisplayDriver except: print >> sys.stderr, "Digitization tool is disabled.\n" \ - "Under development..." + "Under development...\n" class AbstractDigit: """ @@ -748,8 +748,10 @@ # box = wx.StaticBox (parent=panel, id=wx.ID_ANY, label=" %s " % _("Snapping")) sizer = wx.StaticBoxSizer(box, wx.VERTICAL) - flexSizer = wx.FlexGridSizer (cols=3, hgap=5, vgap=5) - flexSizer.AddGrowableCol(0) + flexSizer1 = wx.FlexGridSizer (cols=3, hgap=5, vgap=5) + flexSizer1.AddGrowableCol(0) + flexSizer2 = wx.FlexGridSizer (cols=2, hgap=5, vgap=5) + flexSizer2.AddGrowableCol(0) # snapping 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), @@ -760,23 +762,33 @@ choices=["screen pixels", "map units"]) self.snappingUnit.SetValue(self.parent.digit.settings["snapping"][1]) self.snappingUnit.Bind(wx.EVT_COMBOBOX, self.OnChangeSnappingUnits) - flexSizer.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) - flexSizer.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE) - flexSizer.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE) + flexSizer1.Add(text, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) + flexSizer1.Add(self.snappingValue, proportion=0, flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE) + flexSizer1.Add(self.snappingUnit, proportion=0, flag=wx.ALIGN_RIGHT | wx.FIXED_MINSIZE) + # 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") + 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) + vertexSizer = wx.BoxSizer(wx.VERTICAL) self.snapVertex = wx.CheckBox(parent=panel, id=wx.ID_ANY, label=_("Snap also to vertex")) self.snapVertex.SetValue(self.parent.digit.settings["snapToVertex"]) - vertexSizer.Add(item=self.snapVertex, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) + 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=_("Snapping threshold is %.1f %s") % \ + label=_("Note: snapping threshold is %.1f %s") % \ (self.parent.digit.threshold, self.mapUnits)) - vertexSizer.Add(item=self.snappingInfo, proportion=0, flag=wx.ALL | wx.EXPAND, border=1) + vertexSizer.Add(item=self.snappingInfo, proportion=0, + flag=wx.ALL | wx.EXPAND, border=1) - sizer.Add(item=flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) - sizer.Add(item=vertexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) + sizer.Add(item=flexSizer1, proportion=1, flag=wx.TOP | wx.LEFT | wx.EXPAND, border=1) + sizer.Add(item=flexSizer2, proportion=1, flag=wx.TOP | wx.LEFT | wx.EXPAND, border=1) + sizer.Add(item=vertexSizer, proportion=1, flag=wx.BOTTOM | wx.LEFT | wx.EXPAND, border=1) border.Add(item=sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) # Modified: trunk/grassaddons/gui/gui_modules/toolbars.py =================================================================== --- trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-30 20:18:26 UTC (rev 1116) +++ trunk/grassaddons/gui/gui_modules/toolbars.py 2007-09-30 20:23:45 UTC (rev 1117) @@ -476,7 +476,11 @@ # create pseudoDC for drawing the map self.parent.MapWindow.pdcVector = wx.PseudoDC() self.parent.digit.driver.SetDevice(self.parent.MapWindow.pdcVector) + # self.parent.MapWindow.UpdateMap() + if not self.parent.MapWindow.resize: + self.parent.MapWindow.UpdateMap(render=True) + return True def StopEditing (self, layerSelected): Modified: trunk/grassaddons/gui/icons/icon.py =================================================================== --- trunk/grassaddons/gui/icons/icon.py 2007-09-30 20:18:26 UTC (rev 1116) +++ trunk/grassaddons/gui/icons/icon.py 2007-09-30 20:23:45 UTC (rev 1117) @@ -40,21 +40,27 @@ "printmap" : 'file-print.gif', "overlay" : 'gui-overlay.gif', # digit + ## add feature "digAddPoint": 'new.point.gif', "digAddLine" : 'new.line.gif', "digAddBoundary": 'new.boundary.gif', "digAddCentroid": 'new.centroid.gif', + ## vertex "digAddVertex" : 'add.vertex.gif', + "digMoveVertex" : 'move.vertex.gif', + "digRemoveVertex" : 'rm.vertex.gif', + "digSplitLine" : 'split.line.gif', + ## edit feature + "digEditLine" : 'edit.line.gif', + "digMoveLine" : 'move.line.gif', + "digDeleteLine" : 'delete.line.gif', + ## cats "digCopyCats" : 'copy.cats.gif', - "digDeleteLine" : 'delete.line.gif', + "digDispCats" : 'display.cats.gif', + ## attributes "digDispAttr" : 'display.attributes.gif', - "digDispCats" : 'display.cats.gif', - "digEditLine" : 'edit.line.gif', - "digMoveLine" : 'move.line.gif', - "digMoveVertex" : 'move.vertex.gif', - "digRemoveVertex" : 'rm.vertex.gif', + ## general "digSettings" : 'settings.gif', - "digSplitLine" : 'split.line.gif', "digExit" : 'exit.gif', # gis manager "newdisplay" : 'gui-startmon.gif',